1a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/* 2a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Copyright (C) 2009 The Android Open Source Project 3a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 4a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Licensed under the Apache License, Version 2.0 (the "License"); 5a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * you may not use this file except in compliance with the License. 6a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * You may obtain a copy of the License at 7a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 8a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * http://www.apache.org/licenses/LICENSE-2.0 9a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 10a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Unless required by applicable law or agreed to in writing, software 11a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * distributed under the License is distributed on an "AS IS" BASIS, 12a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * See the License for the specific language governing permissions and 14a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * limitations under the License. 15a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 16a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 17a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#include "Dalvik.h" 18a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#include "vm/compiler/CompilerInternals.h" 19a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#include "MipsLIR.h" 20a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#include "Codegen.h" 21a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 22a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#define DEBUG_OPT(X) 23a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 24a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/* Check RAW, WAR, and WAR dependency on the register operands */ 25a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#define CHECK_REG_DEP(use, def, check) ((def & check->useMask) || \ 26a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham ((use | def) & check->defMask)) 27a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 28a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/* Scheduler heuristics */ 29a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#define MAX_HOIST_DISTANCE 20 30a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#define LDLD_DISTANCE 4 31a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#define LD_LATENCY 2 32a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 33a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic inline bool isDalvikRegisterClobbered(MipsLIR *lir1, MipsLIR *lir2) 34a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 35a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int reg1Lo = DECODE_ALIAS_INFO_REG(lir1->aliasInfo); 36a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int reg1Hi = reg1Lo + DECODE_ALIAS_INFO_WIDE(lir1->aliasInfo); 37a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int reg2Lo = DECODE_ALIAS_INFO_REG(lir2->aliasInfo); 38a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int reg2Hi = reg2Lo + DECODE_ALIAS_INFO_WIDE(lir2->aliasInfo); 39a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 40a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return (reg1Lo == reg2Lo) || (reg1Lo == reg2Hi) || (reg1Hi == reg2Lo); 41a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 42a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 43a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#if 0 44a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/* Debugging utility routine */ 45a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic void dumpDependentInsnPair(MipsLIR *thisLIR, MipsLIR *checkLIR, 46a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham const char *optimization) 47a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 48a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham LOGD("************ %s ************", optimization); 49a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmDumpLIRInsn((LIR *) thisLIR, 0); 50a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmDumpLIRInsn((LIR *) checkLIR, 0); 51a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 52a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 53a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 54a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/* Convert a more expensive instruction (ie load) into a move */ 55a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic void convertMemOpIntoMove(CompilationUnit *cUnit, MipsLIR *origLIR, 56a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int dest, int src) 57a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 58a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* Insert a move to replace the load */ 59a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *moveLIR; 60a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham moveLIR = dvmCompilerRegCopyNoInsert( cUnit, dest, src); 61a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 62a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Insert the converted instruction after the original since the 63a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * optimization is scannng in the top-down order and the new instruction 64a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * will need to be re-checked (eg the new dest clobbers the src used in 65a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * thisLIR). 66a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 67a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerInsertLIRAfter((LIR *) origLIR, (LIR *) moveLIR); 68a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 69a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 70a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/* 71a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Perform a pass of top-down walk, from the second-last instruction in the 72a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * superblock, to eliminate redundant loads and stores. 73a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 74a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * An earlier load can eliminate a later load iff 75a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 1) They are must-aliases 76a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 2) The native register is not clobbered in between 77a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 3) The memory location is not written to in between 78a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 79a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * An earlier store can eliminate a later load iff 80a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 1) They are must-aliases 81a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 2) The native register is not clobbered in between 82a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 3) The memory location is not written to in between 83a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 84a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * A later store can be eliminated by an earlier store iff 85a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 1) They are must-aliases 86a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 2) The memory location is not written to in between 87a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 88a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic void applyLoadStoreElimination(CompilationUnit *cUnit, 89a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *headLIR, 90a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *tailLIR) 91a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 92a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *thisLIR; 93a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 94a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (headLIR == tailLIR) return; 95a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 96a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham for (thisLIR = PREV_LIR(tailLIR); 97a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR != headLIR; 98a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR = PREV_LIR(thisLIR)) { 99a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int sinkDistance = 0; 100a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 101a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* Skip non-interesting instructions */ 102a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if ((thisLIR->flags.isNop == true) || 103a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham isPseudoOpCode(thisLIR->opcode) || 104a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham !(EncodingMap[thisLIR->opcode].flags & (IS_LOAD | IS_STORE))) { 105a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham continue; 106a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 107a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 108a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int nativeRegId = thisLIR->operands[0]; 109a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham bool isThisLIRLoad = EncodingMap[thisLIR->opcode].flags & IS_LOAD; 110a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *checkLIR; 111a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* Use the mem mask to determine the rough memory location */ 112a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham u8 thisMemMask = (thisLIR->useMask | thisLIR->defMask) & ENCODE_MEM; 113a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 114a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 115a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Currently only eliminate redundant ld/st for constant and Dalvik 116a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * register accesses. 117a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 118a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (!(thisMemMask & (ENCODE_LITERAL | ENCODE_DALVIK_REG))) continue; 119a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 120a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 121a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Add r15 (pc) to the resource mask to prevent this instruction 122a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * from sinking past branch instructions. Also take out the memory 123a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * region bits since stopMask is used to check data/control 124a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * dependencies. 125a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 126a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham u8 stopUseRegMask = (ENCODE_REG_PC | thisLIR->useMask) & 127a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham ~ENCODE_MEM; 128a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham u8 stopDefRegMask = thisLIR->defMask & ~ENCODE_MEM; 129a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 130a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham for (checkLIR = NEXT_LIR(thisLIR); 131a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham checkLIR != tailLIR; 132a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham checkLIR = NEXT_LIR(checkLIR)) { 133a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 134a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 135a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Skip already dead instructions (whose dataflow information is 136a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * outdated and misleading). 137a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 138a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (checkLIR->flags.isNop) continue; 139a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 140a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham u8 checkMemMask = (checkLIR->useMask | checkLIR->defMask) & 141a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham ENCODE_MEM; 142a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham u8 aliasCondition = thisMemMask & checkMemMask; 143a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham bool stopHere = false; 144a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 145a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 146a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Potential aliases seen - check the alias relations 147a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 148a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (checkMemMask != ENCODE_MEM && aliasCondition != 0) { 149a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham bool isCheckLIRLoad = EncodingMap[checkLIR->opcode].flags & 150a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham IS_LOAD; 151a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (aliasCondition == ENCODE_LITERAL) { 152a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 153a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Should only see literal loads in the instruction 154a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * stream. 155a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 156a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert(!(EncodingMap[checkLIR->opcode].flags & 157a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham IS_STORE)); 158a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* Same value && same register type */ 159a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (checkLIR->aliasInfo == thisLIR->aliasInfo && 160a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham REGTYPE(checkLIR->operands[0]) == REGTYPE(nativeRegId)){ 161a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 162a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Different destination register - insert 163a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * a move 164a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 165a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (checkLIR->operands[0] != nativeRegId) { 166a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham convertMemOpIntoMove(cUnit, checkLIR, 167a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham checkLIR->operands[0], 168a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham nativeRegId); 169a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 170a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham checkLIR->flags.isNop = true; 171a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 172a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else if (aliasCondition == ENCODE_DALVIK_REG) { 173a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* Must alias */ 174a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (checkLIR->aliasInfo == thisLIR->aliasInfo) { 175a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* Only optimize compatible registers */ 176a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham bool regCompatible = 177a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham REGTYPE(checkLIR->operands[0]) == 178a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham REGTYPE(nativeRegId); 179a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if ((isThisLIRLoad && isCheckLIRLoad) || 180a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham (!isThisLIRLoad && isCheckLIRLoad)) { 181a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* RAR or RAW */ 182a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (regCompatible) { 183a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 184a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Different destination register - 185a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * insert a move 186a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 187a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (checkLIR->operands[0] != 188a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham nativeRegId) { 189a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham convertMemOpIntoMove(cUnit, 190a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham checkLIR, 191a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham checkLIR->operands[0], 192a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham nativeRegId); 193a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 194a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham checkLIR->flags.isNop = true; 195a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 196a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 197a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Destinaions are of different types - 198a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * something complicated going on so 199a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * stop looking now. 200a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 201a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham stopHere = true; 202a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 203a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else if (isThisLIRLoad && !isCheckLIRLoad) { 204a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* WAR - register value is killed */ 205a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham stopHere = true; 206a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else if (!isThisLIRLoad && !isCheckLIRLoad) { 207a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* WAW - nuke the earlier store */ 208a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR->flags.isNop = true; 209a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham stopHere = true; 210a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 211a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* Partial overlap */ 212a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else if (isDalvikRegisterClobbered(thisLIR, checkLIR)) { 213a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 214a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * It is actually ok to continue if checkLIR 215a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * is a read. But it is hard to make a test 216a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * case for this so we just stop here to be 217a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * conservative. 218a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 219a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham stopHere = true; 220a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 221a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 222a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* Memory content may be updated. Stop looking now. */ 223a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (stopHere) { 224a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 225a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* The checkLIR has been transformed - check the next one */ 226a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else if (checkLIR->flags.isNop) { 227a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham continue; 228a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 229a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 230a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 231a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 232a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 233a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * this and check LIRs have no memory dependency. Now check if 234a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * their register operands have any RAW, WAR, and WAW 235a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * dependencies. If so, stop looking. 236a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 237a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (stopHere == false) { 238a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham stopHere = CHECK_REG_DEP(stopUseRegMask, stopDefRegMask, 239a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham checkLIR); 240a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 241a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 242a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (stopHere == true) { 243a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham DEBUG_OPT(dumpDependentInsnPair(thisLIR, checkLIR, 244a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham "REG CLOBBERED")); 245a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* Only sink store instructions */ 246a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (sinkDistance && !isThisLIRLoad) { 247a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *newStoreLIR = 248a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham (MipsLIR *) dvmCompilerNew(sizeof(MipsLIR), true); 249a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham *newStoreLIR = *thisLIR; 250a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 251a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Stop point found - insert *before* the checkLIR 252a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * since the instruction list is scanned in the 253a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * top-down order. 254a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 255a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerInsertLIRBefore((LIR *) checkLIR, 256a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham (LIR *) newStoreLIR); 257a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR->flags.isNop = true; 258a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 259a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 260a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else if (!checkLIR->flags.isNop) { 261a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham sinkDistance++; 262a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 263a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 264a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 265a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 266a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 267a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/* 268a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Perform a pass of bottom-up walk, from the second instruction in the 269a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * superblock, to try to hoist loads to earlier slots. 270a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 271a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic void applyLoadHoisting(CompilationUnit *cUnit, 272a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *headLIR, 273a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *tailLIR) 274a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 275a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *thisLIR, *checkLIR; 276a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 277a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Store the list of independent instructions that can be hoisted past. 278a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Will decide the best place to insert later. 279a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 280a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *prevInstList[MAX_HOIST_DISTANCE]; 281a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 282a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* Empty block */ 283a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (headLIR == tailLIR) return; 284a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 285a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* Start from the second instruction */ 286a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham for (thisLIR = NEXT_LIR(headLIR); 287a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR != tailLIR; 288a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR = NEXT_LIR(thisLIR)) { 289a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 290a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* Skip non-interesting instructions */ 291a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if ((thisLIR->flags.isNop == true) || 292a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham isPseudoOpCode(thisLIR->opcode) || 293a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham !(EncodingMap[thisLIR->opcode].flags & IS_LOAD)) { 294a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham continue; 295a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 296a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 297a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham u8 stopUseAllMask = thisLIR->useMask; 298a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 299a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 300a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Branches for null/range checks are marked with the true resource 301a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * bits, and loads to Dalvik registers, constant pools, and non-alias 302a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * locations are safe to be hoisted. So only mark the heap references 303a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * conservatively here. 304a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 305a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (stopUseAllMask & ENCODE_HEAP_REF) { 306a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham stopUseAllMask |= ENCODE_REG_PC; 307a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 308a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 309a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* Similar as above, but just check for pure register dependency */ 310a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham u8 stopUseRegMask = stopUseAllMask & ~ENCODE_MEM; 311a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham u8 stopDefRegMask = thisLIR->defMask & ~ENCODE_MEM; 312a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 313a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int nextSlot = 0; 314a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham bool stopHere = false; 315a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 316a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* Try to hoist the load to a good spot */ 317a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham for (checkLIR = PREV_LIR(thisLIR); 318a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham checkLIR != headLIR; 319a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham checkLIR = PREV_LIR(checkLIR)) { 320a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 321a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 322a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Skip already dead instructions (whose dataflow information is 323a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * outdated and misleading). 324a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 325a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (checkLIR->flags.isNop) continue; 326a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 327a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham u8 checkMemMask = checkLIR->defMask & ENCODE_MEM; 328a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham u8 aliasCondition = stopUseAllMask & checkMemMask; 329a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham stopHere = false; 330a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 331a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* Potential WAR alias seen - check the exact relation */ 332a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (checkMemMask != ENCODE_MEM && aliasCondition != 0) { 333a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* We can fully disambiguate Dalvik references */ 334a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (aliasCondition == ENCODE_DALVIK_REG) { 335a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* Must alias or partually overlap */ 336a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if ((checkLIR->aliasInfo == thisLIR->aliasInfo) || 337a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham isDalvikRegisterClobbered(thisLIR, checkLIR)) { 338a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham stopHere = true; 339a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 340a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* Conservatively treat all heap refs as may-alias */ 341a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else { 342a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham assert(aliasCondition == ENCODE_HEAP_REF); 343a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham stopHere = true; 344a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 345a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* Memory content may be updated. Stop looking now. */ 346a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (stopHere) { 347a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham prevInstList[nextSlot++] = checkLIR; 348a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 349a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 350a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 351a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 352a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (stopHere == false) { 353a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham stopHere = CHECK_REG_DEP(stopUseRegMask, stopDefRegMask, 354a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham checkLIR); 355a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 356a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 357a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 358a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Store the dependent or non-pseudo/indepedent instruction to the 359a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * list. 360a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 361a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (stopHere || !isPseudoOpCode(checkLIR->opcode)) { 362a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham prevInstList[nextSlot++] = checkLIR; 363a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (nextSlot == MAX_HOIST_DISTANCE) break; 364a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 365a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 366a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* Found a new place to put the load - move it here */ 367a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (stopHere == true) { 368a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham DEBUG_OPT(dumpDependentInsnPair(checkLIR, thisLIR 369a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham "HOIST STOP")); 370a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 371a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 372a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 373a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 374a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 375a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Reached the top - use headLIR as the dependent marker as all labels 376a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * are barriers. 377a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 378a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (stopHere == false && nextSlot < MAX_HOIST_DISTANCE) { 379a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham prevInstList[nextSlot++] = headLIR; 380a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 381a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 382a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 383a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * At least one independent instruction is found. Scan in the reversed 384a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * direction to find a beneficial slot. 385a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 386a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (nextSlot >= 2) { 387a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int firstSlot = nextSlot - 2; 388a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int slot; 389a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *depLIR = prevInstList[nextSlot-1]; 390a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* If there is ld-ld dependency, wait LDLD_DISTANCE cycles */ 391a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (!isPseudoOpCode(depLIR->opcode) && 392a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham (EncodingMap[depLIR->opcode].flags & IS_LOAD)) { 393a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham firstSlot -= LDLD_DISTANCE; 394a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 395a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 396a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Make sure we check slot >= 0 since firstSlot may be negative 397a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * when the loop is first entered. 398a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 399a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham for (slot = firstSlot; slot >= 0; slot--) { 400a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *curLIR = prevInstList[slot]; 401a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *prevLIR = prevInstList[slot+1]; 402a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 403bd1b0d74bbf40c69e47863fab7ea99eac418c515Douglas Leung /* 404bd1b0d74bbf40c69e47863fab7ea99eac418c515Douglas Leung * Check the highest instruction. 405bd1b0d74bbf40c69e47863fab7ea99eac418c515Douglas Leung * ENCODE_ALL represents a scheduling barrier. 406bd1b0d74bbf40c69e47863fab7ea99eac418c515Douglas Leung */ 407a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (prevLIR->defMask == ENCODE_ALL) { 408a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 409a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * If the first instruction is a load, don't hoist anything 410a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * above it since it is unlikely to be beneficial. 411a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 412a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (EncodingMap[curLIR->opcode].flags & IS_LOAD) continue; 413a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 414bd1b0d74bbf40c69e47863fab7ea99eac418c515Douglas Leung * Need to unconditionally break here even if the hoisted 415bd1b0d74bbf40c69e47863fab7ea99eac418c515Douglas Leung * distance is greater than LD_LATENCY (ie more than enough 416bd1b0d74bbf40c69e47863fab7ea99eac418c515Douglas Leung * cycles are inserted to hide the load latency) since theu 417bd1b0d74bbf40c69e47863fab7ea99eac418c515Douglas Leung * subsequent code doesn't expect to compare against a 418bd1b0d74bbf40c69e47863fab7ea99eac418c515Douglas Leung * pseudo opcode (whose opcode value is negative). 419a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 420bd1b0d74bbf40c69e47863fab7ea99eac418c515Douglas Leung break; 421a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 422a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 423a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 424a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * NOTE: now prevLIR is guaranteed to be a non-pseudo 425a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * instruction (ie accessing EncodingMap[prevLIR->opcode] is 426a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * safe). 427a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * 428a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Try to find two instructions with load/use dependency until 429a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * the remaining instructions are less than LD_LATENCY. 430a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 431a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (((curLIR->useMask & prevLIR->defMask) && 432a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham (EncodingMap[prevLIR->opcode].flags & IS_LOAD)) || 433a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham (slot < LD_LATENCY)) { 434a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 435a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 436a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 437a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 438a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* Found a slot to hoist to */ 439a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (slot >= 0) { 440a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *curLIR = prevInstList[slot]; 441a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *newLoadLIR = (MipsLIR *) dvmCompilerNew(sizeof(MipsLIR), 442a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham true); 443a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham *newLoadLIR = *thisLIR; 444a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 445a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Insertion is guaranteed to succeed since checkLIR 446a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * is never the first LIR on the list 447a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 448a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerInsertLIRBefore((LIR *) curLIR, 449a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham (LIR *) newLoadLIR); 450a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR->flags.isNop = true; 451a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 452a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 453a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 454a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 455a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 456a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamvoid dvmCompilerApplyLocalOptimizations(CompilationUnit *cUnit, LIR *headLIR, 457a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham LIR *tailLIR) 458a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 459a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (!(gDvmJit.disableOpt & (1 << kLoadStoreElimination))) { 460a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham applyLoadStoreElimination(cUnit, (MipsLIR *) headLIR, 461a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham (MipsLIR *) tailLIR); 462a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 463a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (!(gDvmJit.disableOpt & (1 << kLoadHoisting))) { 464a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham applyLoadHoisting(cUnit, (MipsLIR *) headLIR, (MipsLIR *) tailLIR); 465a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 466a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 467