1e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng/* 2e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng * Copyright (C) 2009 The Android Open Source Project 3e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng * 4e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng * Licensed under the Apache License, Version 2.0 (the "License"); 5e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng * you may not use this file except in compliance with the License. 6e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng * You may obtain a copy of the License at 7e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng * 8e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng * http://www.apache.org/licenses/LICENSE-2.0 9e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng * 10e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng * Unless required by applicable law or agreed to in writing, software 11e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng * distributed under the License is distributed on an "AS IS" BASIS, 12e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng * See the License for the specific language governing permissions and 14e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng * limitations under the License. 15e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng */ 16e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng 17e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng#include "Dalvik.h" 18e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng#include "vm/compiler/CompilerInternals.h" 1989efc3d632adfa076bd622369b1ad8e4b49cf20eBill Buzbee#include "ArmLIR.h" 205d90c20bd7903d7bba966b224e576bf137bf8b4bBen Cheng#include "Codegen.h" 21e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng 22d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng#define DEBUG_OPT(X) 23d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 247ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng/* Check RAW, WAR, and WAR dependency on the register operands */ 257ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng#define CHECK_REG_DEP(use, def, check) ((def & check->useMask) || \ 267ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng ((use | def) & check->defMask)) 277ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee 287ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng/* Scheduler heuristics */ 297ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng#define MAX_HOIST_DISTANCE 20 307ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng#define LDLD_DISTANCE 4 317ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng#define LD_LATENCY 2 327ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee 33a4aaf68a8bafa44433ceff2bb957a481381aa9a8Ben Chengstatic inline bool isDalvikRegisterClobbered(ArmLIR *lir1, ArmLIR *lir2) 34270c1d64a192341be842f46734054c692bac061eBill Buzbee{ 357ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng int reg1Lo = DECODE_ALIAS_INFO_REG(lir1->aliasInfo); 367ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng int reg1Hi = reg1Lo + DECODE_ALIAS_INFO_WIDE(lir1->aliasInfo); 377ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng int reg2Lo = DECODE_ALIAS_INFO_REG(lir2->aliasInfo); 387ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng int reg2Hi = reg2Lo + DECODE_ALIAS_INFO_WIDE(lir2->aliasInfo); 39d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 407ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng return (reg1Lo == reg2Lo) || (reg1Lo == reg2Hi) || (reg1Hi == reg2Lo); 41d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng} 42d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 43fc075c2d1ae63c26f96e0c6eeb72efc898dbebbfBen Cheng#if 0 44fc075c2d1ae63c26f96e0c6eeb72efc898dbebbfBen Cheng/* Debugging utility routine */ 45d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Chengstatic void dumpDependentInsnPair(ArmLIR *thisLIR, ArmLIR *checkLIR, 46d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng const char *optimization) 47d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng{ 48062bf509a77fce9dfcb7e7b2e401cf2a124d83d5Steve Block ALOGD("************ %s ************", optimization); 49d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng dvmDumpLIRInsn((LIR *) thisLIR, 0); 50d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng dvmDumpLIRInsn((LIR *) checkLIR, 0); 51270c1d64a192341be842f46734054c692bac061eBill Buzbee} 52fc075c2d1ae63c26f96e0c6eeb72efc898dbebbfBen Cheng#endif 53d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 547ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng/* Convert a more expensive instruction (ie load) into a move */ 557ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Chengstatic void convertMemOpIntoMove(CompilationUnit *cUnit, ArmLIR *origLIR, 567ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng int dest, int src) 577ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng{ 587ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* Insert a move to replace the load */ 597ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng ArmLIR *moveLIR; 607ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng moveLIR = dvmCompilerRegCopyNoInsert( cUnit, dest, src); 617ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* 627ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * Insert the converted instruction after the original since the 637ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * optimization is scannng in the top-down order and the new instruction 647ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * will need to be re-checked (eg the new dest clobbers the src used in 657ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * thisLIR). 667ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng */ 677ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng dvmCompilerInsertLIRAfter((LIR *) origLIR, (LIR *) moveLIR); 687ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng} 697ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng 70e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng/* 717ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * Perform a pass of top-down walk, from the second-last instruction in the 727ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * superblock, to eliminate redundant loads and stores. 737ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * 747ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * An earlier load can eliminate a later load iff 757ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * 1) They are must-aliases 767ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * 2) The native register is not clobbered in between 777ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * 3) The memory location is not written to in between 787ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * 797ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * An earlier store can eliminate a later load iff 807ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * 1) They are must-aliases 817ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * 2) The native register is not clobbered in between 827ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * 3) The memory location is not written to in between 837ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * 847ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * A later store can be eliminated by an earlier store iff 857ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * 1) They are must-aliases 867ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * 2) The memory location is not written to in between 87e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng */ 88e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Chengstatic void applyLoadStoreElimination(CompilationUnit *cUnit, 8989efc3d632adfa076bd622369b1ad8e4b49cf20eBill Buzbee ArmLIR *headLIR, 9089efc3d632adfa076bd622369b1ad8e4b49cf20eBill Buzbee ArmLIR *tailLIR) 91e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng{ 9289efc3d632adfa076bd622369b1ad8e4b49cf20eBill Buzbee ArmLIR *thisLIR; 93e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng 947ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (headLIR == tailLIR) return; 957ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng 967ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng for (thisLIR = PREV_LIR(tailLIR); 977ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng thisLIR != headLIR; 987ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng thisLIR = PREV_LIR(thisLIR)) { 997ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng int sinkDistance = 0; 1007ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng 1017ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* Skip non-interesting instructions */ 1027ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if ((thisLIR->flags.isNop == true) || 1037ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng isPseudoOpcode(thisLIR->opcode) || 1047ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng !(EncodingMap[thisLIR->opcode].flags & (IS_LOAD | IS_STORE))) { 105e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng continue; 106e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng } 1077ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng 1087ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng int nativeRegId = thisLIR->operands[0]; 1097ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng bool isThisLIRLoad = EncodingMap[thisLIR->opcode].flags & IS_LOAD; 1107ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng ArmLIR *checkLIR; 1117ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* Use the mem mask to determine the rough memory location */ 1127ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng u8 thisMemMask = (thisLIR->useMask | thisLIR->defMask) & ENCODE_MEM; 1137ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng 1147ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* 1157ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * Currently only eliminate redundant ld/st for constant and Dalvik 1167ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * register accesses. 1177ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng */ 1187ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (!(thisMemMask & (ENCODE_LITERAL | ENCODE_DALVIK_REG))) continue; 1197ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng 1207ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* 1217ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * Add r15 (pc) to the resource mask to prevent this instruction 1227ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * from sinking past branch instructions. Also take out the memory 1237ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * region bits since stopMask is used to check data/control 1247ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * dependencies. 1257ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng */ 1267ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng u8 stopUseRegMask = (ENCODE_REG_PC | thisLIR->useMask) & 1277ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng ~ENCODE_MEM; 1287ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng u8 stopDefRegMask = thisLIR->defMask & ~ENCODE_MEM; 1297ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng 1307ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng for (checkLIR = NEXT_LIR(thisLIR); 1317ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng checkLIR != tailLIR; 1327ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng checkLIR = NEXT_LIR(checkLIR)) { 1337ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng 134243db252574a78ff7326e7446d9042e321314c4fBen Cheng /* 135243db252574a78ff7326e7446d9042e321314c4fBen Cheng * Skip already dead instructions (whose dataflow information is 136243db252574a78ff7326e7446d9042e321314c4fBen Cheng * outdated and misleading). 137243db252574a78ff7326e7446d9042e321314c4fBen Cheng */ 138243db252574a78ff7326e7446d9042e321314c4fBen Cheng if (checkLIR->flags.isNop) continue; 139243db252574a78ff7326e7446d9042e321314c4fBen Cheng 1407ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng u8 checkMemMask = (checkLIR->useMask | checkLIR->defMask) & 1417ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng ENCODE_MEM; 1427ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng u8 aliasCondition = thisMemMask & checkMemMask; 1437ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng bool stopHere = false; 1447ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng 145dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng /* 1467ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * Potential aliases seen - check the alias relations 147dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng */ 1487ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (checkMemMask != ENCODE_MEM && aliasCondition != 0) { 1497ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng bool isCheckLIRLoad = EncodingMap[checkLIR->opcode].flags & 1507ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng IS_LOAD; 1517ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (aliasCondition == ENCODE_LITERAL) { 1527ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* 1537ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * Should only see literal loads in the instruction 1547ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * stream. 1557ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng */ 1567ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng assert(!(EncodingMap[checkLIR->opcode].flags & 1577ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng IS_STORE)); 1587ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* Same value && same register type */ 1597ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (checkLIR->aliasInfo == thisLIR->aliasInfo && 1607ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng REGTYPE(checkLIR->operands[0]) == REGTYPE(nativeRegId)){ 161e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng /* 1627ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * Different destination register - insert 1637ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * a move 164e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng */ 1657ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (checkLIR->operands[0] != nativeRegId) { 1667ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng convertMemOpIntoMove(cUnit, checkLIR, 1677ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng checkLIR->operands[0], 1687ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng nativeRegId); 1697ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng } 1707ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng checkLIR->flags.isNop = true; 171d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 1727ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng } else if (aliasCondition == ENCODE_DALVIK_REG) { 1737ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* Must alias */ 1747ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (checkLIR->aliasInfo == thisLIR->aliasInfo) { 1757ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* Only optimize compatible registers */ 1767ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng bool regCompatible = 1777ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng REGTYPE(checkLIR->operands[0]) == 1787ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng REGTYPE(nativeRegId); 1797ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if ((isThisLIRLoad && isCheckLIRLoad) || 1807ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng (!isThisLIRLoad && isCheckLIRLoad)) { 1817ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* RAR or RAW */ 1827ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (regCompatible) { 1837ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* 1847ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * Different destination register - 1857ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * insert a move 1867ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng */ 1877ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (checkLIR->operands[0] != 1887ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng nativeRegId) { 1897ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng convertMemOpIntoMove(cUnit, 1907ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng checkLIR, 1917ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng checkLIR->operands[0], 1927ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng nativeRegId); 1937ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng } 1947ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng checkLIR->flags.isNop = true; 1957ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng } else { 1967ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* 1977ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * Destinaions are of different types - 1987ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * something complicated going on so 1997ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * stop looking now. 2007ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng */ 2017ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng stopHere = true; 2027ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng } 2037ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng } else if (isThisLIRLoad && !isCheckLIRLoad) { 2047ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* WAR - register value is killed */ 2057ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng stopHere = true; 2067ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng } else if (!isThisLIRLoad && !isCheckLIRLoad) { 2077ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* WAW - nuke the earlier store */ 208d72564ca7aa66c6d95b6ca34299258b65ecfd1cbBen Cheng thisLIR->flags.isNop = true; 2097ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng stopHere = true; 210e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng } 2117ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* Partial overlap */ 2127ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng } else if (isDalvikRegisterClobbered(thisLIR, checkLIR)) { 2137ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* 2147ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * It is actually ok to continue if checkLIR 2157ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * is a read. But it is hard to make a test 2167ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * case for this so we just stop here to be 2177ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * conservative. 2187ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng */ 2197ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng stopHere = true; 220e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng } 2217ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng } 2227ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* Memory content may be updated. Stop looking now. */ 2237ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (stopHere) { 2247ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng break; 2257ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* The checkLIR has been transformed - check the next one */ 2267ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng } else if (checkLIR->flags.isNop) { 2277ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng continue; 2287ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng } 2297ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng } 2307ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng 231e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng 2327ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* 2337ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * this and check LIRs have no memory dependency. Now check if 2347ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * their register operands have any RAW, WAR, and WAW 2357ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * dependencies. If so, stop looking. 2367ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng */ 2377ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (stopHere == false) { 2387ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng stopHere = CHECK_REG_DEP(stopUseRegMask, stopDefRegMask, 2397ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng checkLIR); 2407ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng } 2417ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng 2427ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (stopHere == true) { 2437ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng DEBUG_OPT(dumpDependentInsnPair(thisLIR, checkLIR, 2447ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng "REG CLOBBERED")); 2457ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* Only sink store instructions */ 2467ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (sinkDistance && !isThisLIRLoad) { 2477ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng ArmLIR *newStoreLIR = 2487ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), true); 2497ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng *newStoreLIR = *thisLIR; 250e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng /* 2517ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * Stop point found - insert *before* the checkLIR 2527ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * since the instruction list is scanned in the 2537ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * top-down order. 254e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng */ 2557ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng dvmCompilerInsertLIRBefore((LIR *) checkLIR, 2567ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng (LIR *) newStoreLIR); 2577ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng thisLIR->flags.isNop = true; 258e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng } 2597ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng break; 2607ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng } else if (!checkLIR->flags.isNop) { 2617ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng sinkDistance++; 262e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng } 263e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng } 264e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng } 265e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng} 266e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng 2677ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng/* 2687ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * Perform a pass of bottom-up walk, from the second instruction in the 2697ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * superblock, to try to hoist loads to earlier slots. 2707ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng */ 271dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Chengstatic void applyLoadHoisting(CompilationUnit *cUnit, 272dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng ArmLIR *headLIR, 273dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng ArmLIR *tailLIR) 274dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng{ 2757ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng ArmLIR *thisLIR, *checkLIR; 2761f74863d3e0f19930818398f375ebf1cf2d78969Bill Buzbee /* 2777ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * Store the list of independent instructions that can be hoisted past. 2787ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * Will decide the best place to insert later. 2791f74863d3e0f19930818398f375ebf1cf2d78969Bill Buzbee */ 2807ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng ArmLIR *prevInstList[MAX_HOIST_DISTANCE]; 2817ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng 2827ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* Empty block */ 2837ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (headLIR == tailLIR) return; 284dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng 2857ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* Start from the second instruction */ 2867ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng for (thisLIR = NEXT_LIR(headLIR); 287dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng thisLIR != tailLIR; 288dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng thisLIR = NEXT_LIR(thisLIR)) { 2897ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng 2907ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* Skip non-interesting instructions */ 2917ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if ((thisLIR->flags.isNop == true) || 2927ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng isPseudoOpcode(thisLIR->opcode) || 2937ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng !(EncodingMap[thisLIR->opcode].flags & IS_LOAD)) { 294dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng continue; 295dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng } 2961f74863d3e0f19930818398f375ebf1cf2d78969Bill Buzbee 2977ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng u8 stopUseAllMask = thisLIR->useMask; 2987ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng 2997ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* 3007ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * Branches for null/range checks are marked with the true resource 3017ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * bits, and loads to Dalvik registers, constant pools, and non-alias 3027ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * locations are safe to be hoisted. So only mark the heap references 3037ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * conservatively here. 3047ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng */ 3057ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (stopUseAllMask & ENCODE_HEAP_REF) { 3067ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng stopUseAllMask |= ENCODE_REG_PC; 3071f74863d3e0f19930818398f375ebf1cf2d78969Bill Buzbee } 3081f74863d3e0f19930818398f375ebf1cf2d78969Bill Buzbee 3097ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* Similar as above, but just check for pure register dependency */ 3107ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng u8 stopUseRegMask = stopUseAllMask & ~ENCODE_MEM; 3117ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng u8 stopDefRegMask = thisLIR->defMask & ~ENCODE_MEM; 3121f74863d3e0f19930818398f375ebf1cf2d78969Bill Buzbee 3137ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng int nextSlot = 0; 3148402bdf3308aac0743e2c3af248c48202b8b2dc1Doug Kwan bool stopHere = false; 315dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng 3167ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* Try to hoist the load to a good spot */ 3177ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng for (checkLIR = PREV_LIR(thisLIR); 3187ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng checkLIR != headLIR; 3197ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng checkLIR = PREV_LIR(checkLIR)) { 320dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng 321243db252574a78ff7326e7446d9042e321314c4fBen Cheng /* 322243db252574a78ff7326e7446d9042e321314c4fBen Cheng * Skip already dead instructions (whose dataflow information is 323243db252574a78ff7326e7446d9042e321314c4fBen Cheng * outdated and misleading). 324243db252574a78ff7326e7446d9042e321314c4fBen Cheng */ 3257ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (checkLIR->flags.isNop) continue; 326dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng 3277ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng u8 checkMemMask = checkLIR->defMask & ENCODE_MEM; 3287ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng u8 aliasCondition = stopUseAllMask & checkMemMask; 3297ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng stopHere = false; 330d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 3317ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* Potential WAR alias seen - check the exact relation */ 3327ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (checkMemMask != ENCODE_MEM && aliasCondition != 0) { 3337ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* We can fully disambiguate Dalvik references */ 3347ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (aliasCondition == ENCODE_DALVIK_REG) { 3357ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* Must alias or partually overlap */ 3367ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if ((checkLIR->aliasInfo == thisLIR->aliasInfo) || 3377ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng isDalvikRegisterClobbered(thisLIR, checkLIR)) { 3387ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng stopHere = true; 3397ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng } 3407ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* Conservatively treat all heap refs as may-alias */ 3417ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng } else { 3427ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng assert(aliasCondition == ENCODE_HEAP_REF); 3437ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng stopHere = true; 344d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 3457ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* Memory content may be updated. Stop looking now. */ 3467ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (stopHere) { 3477ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng prevInstList[nextSlot++] = checkLIR; 348d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng break; 349d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 350d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 351d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 3527ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (stopHere == false) { 3537ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng stopHere = CHECK_REG_DEP(stopUseRegMask, stopDefRegMask, 3547ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng checkLIR); 3557ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng } 356d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 357d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng /* 3587ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * Store the dependent or non-pseudo/indepedent instruction to the 3597ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * list. 360d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng */ 3617ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (stopHere || !isPseudoOpcode(checkLIR->opcode)) { 3627ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng prevInstList[nextSlot++] = checkLIR; 3637ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (nextSlot == MAX_HOIST_DISTANCE) break; 3647ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng } 365dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng 3667ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* Found a new place to put the load - move it here */ 3677ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (stopHere == true) { 3687ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng DEBUG_OPT(dumpDependentInsnPair(checkLIR, thisLIR 3697ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng "HOIST STOP")); 3707ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng break; 3717ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng } 3727ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng } 373dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng 3747ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* 3757ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * Reached the top - use headLIR as the dependent marker as all labels 3767ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * are barriers. 3777ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng */ 3787ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (stopHere == false && nextSlot < MAX_HOIST_DISTANCE) { 3797ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng prevInstList[nextSlot++] = headLIR; 3807ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng } 381d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 3827ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* 3837ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * At least one independent instruction is found. Scan in the reversed 3847ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * direction to find a beneficial slot. 3857ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng */ 3867ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (nextSlot >= 2) { 3877ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng int firstSlot = nextSlot - 2; 3887ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng int slot; 3897ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng ArmLIR *depLIR = prevInstList[nextSlot-1]; 3907ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* If there is ld-ld dependency, wait LDLD_DISTANCE cycles */ 3917ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (!isPseudoOpcode(depLIR->opcode) && 3927ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng (EncodingMap[depLIR->opcode].flags & IS_LOAD)) { 3937ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng firstSlot -= LDLD_DISTANCE; 3947ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng } 3957ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* 3967ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * Make sure we check slot >= 0 since firstSlot may be negative 3977ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * when the loop is first entered. 3987ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng */ 3997ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng for (slot = firstSlot; slot >= 0; slot--) { 4007ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng ArmLIR *curLIR = prevInstList[slot]; 4017ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng ArmLIR *prevLIR = prevInstList[slot+1]; 402d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 403513691130f0c1ab94f52127c40d0018bb7dfc529Ben Cheng /* 404513691130f0c1ab94f52127c40d0018bb7dfc529Ben Cheng * Check the highest instruction. 405513691130f0c1ab94f52127c40d0018bb7dfc529Ben Cheng * ENCODE_ALL represents a scheduling barrier. 406513691130f0c1ab94f52127c40d0018bb7dfc529Ben Cheng */ 4077ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (prevLIR->defMask == ENCODE_ALL) { 408d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng /* 4097ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * If the first instruction is a load, don't hoist anything 4107ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * above it since it is unlikely to be beneficial. 411d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng */ 4127ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (EncodingMap[curLIR->opcode].flags & IS_LOAD) continue; 413dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng /* 414513691130f0c1ab94f52127c40d0018bb7dfc529Ben Cheng * Need to unconditionally break here even if the hoisted 415513691130f0c1ab94f52127c40d0018bb7dfc529Ben Cheng * distance is greater than LD_LATENCY (ie more than enough 416513691130f0c1ab94f52127c40d0018bb7dfc529Ben Cheng * cycles are inserted to hide the load latency) since theu 417513691130f0c1ab94f52127c40d0018bb7dfc529Ben Cheng * subsequent code doesn't expect to compare against a 418513691130f0c1ab94f52127c40d0018bb7dfc529Ben Cheng * pseudo opcode (whose opcode value is negative). 419dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng */ 420513691130f0c1ab94f52127c40d0018bb7dfc529Ben Cheng break; 4211f74863d3e0f19930818398f375ebf1cf2d78969Bill Buzbee } 4221f74863d3e0f19930818398f375ebf1cf2d78969Bill Buzbee 4231f74863d3e0f19930818398f375ebf1cf2d78969Bill Buzbee /* 4247ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * NOTE: now prevLIR is guaranteed to be a non-pseudo 4257ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * instruction (ie accessing EncodingMap[prevLIR->opcode] is 4267ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * safe). 4277ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * 4287ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * Try to find two instructions with load/use dependency until 4297ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * the remaining instructions are less than LD_LATENCY. 4301f74863d3e0f19930818398f375ebf1cf2d78969Bill Buzbee */ 4317ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (((curLIR->useMask & prevLIR->defMask) && 4327ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng (EncodingMap[prevLIR->opcode].flags & IS_LOAD)) || 4337ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng (slot < LD_LATENCY)) { 4341f74863d3e0f19930818398f375ebf1cf2d78969Bill Buzbee break; 4351f74863d3e0f19930818398f375ebf1cf2d78969Bill Buzbee } 4361f74863d3e0f19930818398f375ebf1cf2d78969Bill Buzbee } 4371f74863d3e0f19930818398f375ebf1cf2d78969Bill Buzbee 4387ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng /* Found a slot to hoist to */ 4397ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng if (slot >= 0) { 4407ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng ArmLIR *curLIR = prevInstList[slot]; 4417ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng ArmLIR *newLoadLIR = (ArmLIR *) dvmCompilerNew(sizeof(ArmLIR), 4427ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng true); 4437ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng *newLoadLIR = *thisLIR; 4441f74863d3e0f19930818398f375ebf1cf2d78969Bill Buzbee /* 4457ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * Insertion is guaranteed to succeed since checkLIR 4467ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng * is never the first LIR on the list 4471f74863d3e0f19930818398f375ebf1cf2d78969Bill Buzbee */ 4487ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng dvmCompilerInsertLIRBefore((LIR *) curLIR, 4497ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng (LIR *) newLoadLIR); 4507ab74e14ed8dac0e51ce72fc6283ee2f1ffdf087Ben Cheng thisLIR->flags.isNop = true; 4511f74863d3e0f19930818398f375ebf1cf2d78969Bill Buzbee } 452dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng } 453dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng } 454dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng} 455dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng 456e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Chengvoid dvmCompilerApplyLocalOptimizations(CompilationUnit *cUnit, LIR *headLIR, 457e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng LIR *tailLIR) 458e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng{ 459dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng if (!(gDvmJit.disableOpt & (1 << kLoadStoreElimination))) { 460dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng applyLoadStoreElimination(cUnit, (ArmLIR *) headLIR, 461dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng (ArmLIR *) tailLIR); 462dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng } 463dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng if (!(gDvmJit.disableOpt & (1 << kLoadHoisting))) { 464dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng applyLoadHoisting(cUnit, (ArmLIR *) headLIR, (ArmLIR *) tailLIR); 465dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng } 466e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng} 467