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 21a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/* 22a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Identify unconditional branches that jump to the immediate successor of the 23a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * branch itself. 24a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 25a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic void applyRedundantBranchElimination(CompilationUnit *cUnit) 26a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 27a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *thisLIR; 28a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 29a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham for (thisLIR = (MipsLIR *) cUnit->firstLIRInsn; 30a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR != (MipsLIR *) cUnit->lastLIRInsn; 31a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR = NEXT_LIR(thisLIR)) { 32a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 33a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* Branch to the next instruction */ 34a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (!thisLIR->flags.isNop && thisLIR->opcode == kMipsB) { 35a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *nextLIR = thisLIR; 36a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 37a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham while (true) { 38a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham nextLIR = NEXT_LIR(nextLIR); 39a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 40a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 41a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Is the branch target the next instruction? 42a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 43a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (nextLIR == (MipsLIR *) thisLIR->generic.target) { 44a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR->flags.isNop = true; 45a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 46a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 47a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 48a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* 49a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Found real useful stuff between the branch and the target. 50a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Need to explicitly check the lastLIRInsn here since with 51a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * method-based JIT the branch might be the last real 52a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * instruction. 53a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 54a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (!isPseudoOpCode(nextLIR->opcode) || 55a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham (nextLIR = (MipsLIR *) cUnit->lastLIRInsn)) 56a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 57a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 58a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 59a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 60a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 61a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 62a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/* 63a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Do simple a form of copy propagation and elimination. 64a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 65a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic void applyCopyPropagation(CompilationUnit *cUnit) 66a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 67a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *thisLIR; 68a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 69a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* look for copies to possibly eliminate */ 70a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham for (thisLIR = (MipsLIR *) cUnit->firstLIRInsn; 71a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR != (MipsLIR *) cUnit->lastLIRInsn; 72a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR = NEXT_LIR(thisLIR)) { 73a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 74a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (thisLIR->flags.isNop || thisLIR->opcode != kMipsMove) 75a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham continue; 76a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 77a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham const int max_insns = 10; 78a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *savedLIR[max_insns]; 79a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int srcRedefined = 0; 80a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int insnCount = 0; 81a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *nextLIR; 82a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 83a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* look for and record all uses of reg defined by the copy */ 84a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham for (nextLIR = (MipsLIR *) NEXT_LIR(thisLIR); 85a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham nextLIR != (MipsLIR *) cUnit->lastLIRInsn; 86a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham nextLIR = NEXT_LIR(nextLIR)) { 87a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 88a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (nextLIR->flags.isNop || nextLIR->opcode == kMips32BitData) 89a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham continue; 90a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 91a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (isPseudoOpCode(nextLIR->opcode)) { 92a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (nextLIR->opcode == kMipsPseudoDalvikByteCodeBoundary || 93a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham nextLIR->opcode == kMipsPseudoBarrier || 94a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham nextLIR->opcode == kMipsPseudoExtended || 95a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham nextLIR->opcode == kMipsPseudoSSARep) 96a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham continue; /* these pseudos don't pose problems */ 97a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham else if (nextLIR->opcode == kMipsPseudoTargetLabel || 98a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham nextLIR->opcode == kMipsPseudoEntryBlock || 99a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham nextLIR->opcode == kMipsPseudoExitBlock) 100a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham insnCount = 0; /* give up for these pseudos */ 101a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; /* reached end for copy propagation */ 102a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 103a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 104a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* Since instructions with IS_BRANCH flag set will have its */ 105a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* useMask and defMask set to ENCODE_ALL, any checking of */ 106a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* these flags must come after the branching checks. */ 107a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 108a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* don't propagate across branch/jump and link case 109a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham or jump via register */ 110a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (EncodingMap[nextLIR->opcode].flags & REG_DEF_LR || 111a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham nextLIR->opcode == kMipsJalr || 112a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham nextLIR->opcode == kMipsJr) { 113a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham insnCount = 0; 114a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 115a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 116a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 117a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* branches with certain targets ok while others aren't */ 118a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (EncodingMap[nextLIR->opcode].flags & IS_BRANCH) { 119a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *targetLIR = (MipsLIR *) nextLIR->generic.target; 120a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (targetLIR->opcode != kMipsPseudoEHBlockLabel && 121a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham targetLIR->opcode != kMipsPseudoChainingCellHot && 122a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham targetLIR->opcode != kMipsPseudoChainingCellNormal && 123a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham targetLIR->opcode != kMipsPseudoChainingCellInvokePredicted && 124a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham targetLIR->opcode != kMipsPseudoChainingCellInvokeSingleton && 125a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham targetLIR->opcode != kMipsPseudoPCReconstructionBlockLabel && 126a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham targetLIR->opcode != kMipsPseudoPCReconstructionCell) { 127a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham insnCount = 0; 128a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 129a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 130a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* FIXME - for now don't propagate across any branch/jump. */ 131a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham insnCount = 0; 132a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 133a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 134a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 135a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* copy def reg used here, so record insn for copy propagation */ 136a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (thisLIR->defMask & nextLIR->useMask) { 137a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (insnCount == max_insns || srcRedefined) { 138a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham insnCount = 0; 139a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; /* just give up if too many or not possible */ 140a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 141a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham savedLIR[insnCount++] = nextLIR; 142a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 143a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 144a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (thisLIR->defMask & nextLIR->defMask) { 145a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (nextLIR->opcode == kMipsMovz) 146a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham insnCount = 0; /* movz relies on thisLIR setting dst reg so abandon propagation*/ 147a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 148a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 149a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 150a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* copy src reg redefined here, so can't propagate further */ 151a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (thisLIR->useMask & nextLIR->defMask) { 152a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (insnCount == 0) 153a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; /* nothing to propagate */ 154a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham srcRedefined = 1; 155a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 156a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 157a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 158a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* conditions allow propagation and copy elimination */ 159a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (insnCount) { 160a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int i; 161a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham for (i = 0; i < insnCount; i++) { 162a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int flags = EncodingMap[savedLIR[i]->opcode].flags; 163a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham savedLIR[i]->useMask &= ~(1 << thisLIR->operands[0]); 164a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham savedLIR[i]->useMask |= 1 << thisLIR->operands[1]; 165a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if ((flags & REG_USE0) && 166a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham savedLIR[i]->operands[0] == thisLIR->operands[0]) 167a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham savedLIR[i]->operands[0] = thisLIR->operands[1]; 168a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if ((flags & REG_USE1) && 169a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham savedLIR[i]->operands[1] == thisLIR->operands[0]) 170a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham savedLIR[i]->operands[1] = thisLIR->operands[1]; 171a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if ((flags & REG_USE2) && 172a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham savedLIR[i]->operands[2] == thisLIR->operands[0]) 173a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham savedLIR[i]->operands[2] = thisLIR->operands[1]; 174a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if ((flags & REG_USE3) && 175a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham savedLIR[i]->operands[3] == thisLIR->operands[0]) 176a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham savedLIR[i]->operands[3] = thisLIR->operands[1]; 177a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 178a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR->flags.isNop = true; 179a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 180a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 181a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 182a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 183a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float 184a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/* 185a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Look for pairs of mov.s instructions that can be combined into mov.d 186a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 187a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic void mergeMovs(CompilationUnit *cUnit) 188a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 189a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *movsLIR = NULL; 190a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *thisLIR; 191a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 192a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham for (thisLIR = (MipsLIR *) cUnit->firstLIRInsn; 193a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR != (MipsLIR *) cUnit->lastLIRInsn; 194a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR = NEXT_LIR(thisLIR)) { 195a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (thisLIR->flags.isNop) 196a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham continue; 197a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 198a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (isPseudoOpCode(thisLIR->opcode)) { 199a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (thisLIR->opcode == kMipsPseudoDalvikByteCodeBoundary || 200a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR->opcode == kMipsPseudoExtended || 201a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR->opcode == kMipsPseudoSSARep) 202a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham continue; /* ok to move across these pseudos */ 203a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham movsLIR = NULL; /* don't merge across other pseudos */ 204a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham continue; 205a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 206a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 207a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* merge pairs of mov.s instructions */ 208a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (thisLIR->opcode == kMipsFmovs) { 209a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (movsLIR == NULL) 210a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham movsLIR = thisLIR; 211a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham else if (((movsLIR->operands[0] & 1) == 0) && 212a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham ((movsLIR->operands[1] & 1) == 0) && 213a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham ((movsLIR->operands[0] + 1) == thisLIR->operands[0]) && 214a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham ((movsLIR->operands[1] + 1) == thisLIR->operands[1])) { 215a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* movsLIR is handling even register - upgrade to mov.d */ 216a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham movsLIR->opcode = kMipsFmovd; 217a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham movsLIR->operands[0] = S2D(movsLIR->operands[0], movsLIR->operands[0]+1); 218a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham movsLIR->operands[1] = S2D(movsLIR->operands[1], movsLIR->operands[1]+1); 219a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR->flags.isNop = true; 220a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham movsLIR = NULL; 221a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 222a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham else if (((movsLIR->operands[0] & 1) == 1) && 223a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham ((movsLIR->operands[1] & 1) == 1) && 224a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham ((movsLIR->operands[0] - 1) == thisLIR->operands[0]) && 225a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham ((movsLIR->operands[1] - 1) == thisLIR->operands[1])) { 226a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* thissLIR is handling even register - upgrade to mov.d */ 227a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR->opcode = kMipsFmovd; 228a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR->operands[0] = S2D(thisLIR->operands[0], thisLIR->operands[0]+1); 229a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR->operands[1] = S2D(thisLIR->operands[1], thisLIR->operands[1]+1); 230a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham movsLIR->flags.isNop = true; 231a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham movsLIR = NULL; 232a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 233a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham else 234a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* carry on searching from here */ 235a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham movsLIR = thisLIR; 236a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham continue; 237a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 238a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 239a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* intervening instruction - start search from scratch */ 240a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham movsLIR = NULL; 241a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 242a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 243a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 244a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 245a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 246a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/* 247a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * Look back first and then ahead to try to find an instruction to move into 248a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * the branch delay slot. If the analysis can be done cheaply enough, it may be 249a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * be possible to tune this routine to be more beneficial (e.g., being more 250a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * particular about what instruction is speculated). 251a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 252a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic MipsLIR *delaySlotLIR(MipsLIR *firstLIR, MipsLIR *branchLIR) 253a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 254a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int isLoad; 255a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int loadVisited = 0; 256a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int isStore; 257a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int storeVisited = 0; 258a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham u8 useMask = branchLIR->useMask; 259a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham u8 defMask = branchLIR->defMask; 260a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *thisLIR; 261a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *newLIR = (MipsLIR *) dvmCompilerNew(sizeof(MipsLIR), true); 262a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 263a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham for (thisLIR = PREV_LIR(branchLIR); 264a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR != firstLIR; 265a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR = PREV_LIR(thisLIR)) { 266a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (thisLIR->flags.isNop) 267a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham continue; 268a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 269a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (isPseudoOpCode(thisLIR->opcode)) { 270a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (thisLIR->opcode == kMipsPseudoDalvikByteCodeBoundary || 271a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR->opcode == kMipsPseudoExtended || 272a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR->opcode == kMipsPseudoSSARep) 273a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham continue; /* ok to move across these pseudos */ 274a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; /* don't move across all other pseudos */ 275a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 276a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 277a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* give up on moving previous instruction down into slot */ 278a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (thisLIR->opcode == kMipsNop || 279a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR->opcode == kMips32BitData || 280a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham EncodingMap[thisLIR->opcode].flags & IS_BRANCH) 281a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; 282a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 283a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* don't reorder loads/stores (the alias info could 284a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham possibly be used to allow as a future enhancement) */ 285a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham isLoad = EncodingMap[thisLIR->opcode].flags & IS_LOAD; 286a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham isStore = EncodingMap[thisLIR->opcode].flags & IS_STORE; 287a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 288a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (!(thisLIR->useMask & defMask) && 289a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham !(thisLIR->defMask & useMask) && 290a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham !(thisLIR->defMask & defMask) && 291a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham !(isLoad && storeVisited) && 292a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham !(isStore && loadVisited) && 293a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham !(isStore && storeVisited)) { 294a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham *newLIR = *thisLIR; 295a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham thisLIR->flags.isNop = true; 296a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return newLIR; /* move into delay slot succeeded */ 297a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 298a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 299a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham loadVisited |= isLoad; 300a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham storeVisited |= isStore; 301a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 302a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* accumulate def/use constraints */ 303a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham useMask |= thisLIR->useMask; 304a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham defMask |= thisLIR->defMask; 305a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 306a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 307a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* for unconditional branches try to copy the instruction at the 308a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham branch target up into the delay slot and adjust the branch */ 309a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (branchLIR->opcode == kMipsB) { 310a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *targetLIR; 311a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham for (targetLIR = (MipsLIR *) branchLIR->generic.target; 312a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham targetLIR; 313a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham targetLIR = NEXT_LIR(targetLIR)) { 314a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (!targetLIR->flags.isNop && 315a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham (!isPseudoOpCode(targetLIR->opcode) || /* can't pull predicted up */ 316a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham targetLIR->opcode == kMipsPseudoChainingCellInvokePredicted)) 317a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; /* try to get to next real op at branch target */ 318a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 319a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (targetLIR && !isPseudoOpCode(targetLIR->opcode) && 320a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham !(EncodingMap[targetLIR->opcode].flags & IS_BRANCH)) { 321a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham *newLIR = *targetLIR; 322a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham branchLIR->generic.target = (LIR *) NEXT_LIR(targetLIR); 323a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return newLIR; 324a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 325a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else if (branchLIR->opcode >= kMipsBeq && branchLIR->opcode <= kMipsBne) { 326a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* for conditional branches try to fill branch delay slot 327a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham via speculative execution when safe */ 328a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *targetLIR; 329a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham for (targetLIR = (MipsLIR *) branchLIR->generic.target; 330a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham targetLIR; 331a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham targetLIR = NEXT_LIR(targetLIR)) { 332a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (!targetLIR->flags.isNop && !isPseudoOpCode(targetLIR->opcode)) 333a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; /* try to get to next real op at branch target */ 334a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 335a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 336a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *nextLIR; 337a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham for (nextLIR = NEXT_LIR(branchLIR); 338a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham nextLIR; 339a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham nextLIR = NEXT_LIR(nextLIR)) { 340a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (!nextLIR->flags.isNop && !isPseudoOpCode(nextLIR->opcode)) 341a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham break; /* try to get to next real op for fall thru */ 342a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 343a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 344a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (nextLIR && targetLIR) { 345a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int flags = EncodingMap[nextLIR->opcode].flags; 346a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int isLoad = flags & IS_LOAD; 347a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 348a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* common branch and fall thru to normal chaining cells case */ 349a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (isLoad && nextLIR->opcode == targetLIR->opcode && 350a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham nextLIR->operands[0] == targetLIR->operands[0] && 351a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham nextLIR->operands[1] == targetLIR->operands[1] && 352a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham nextLIR->operands[2] == targetLIR->operands[2]) { 353a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham *newLIR = *targetLIR; 354a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham branchLIR->generic.target = (LIR *) NEXT_LIR(targetLIR); 355a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return newLIR; 356a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 357a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 358a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* try prefetching (maybe try speculating instructions along the 359a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham trace like dalvik frame load which is common and may be safe) */ 360a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham int isStore = flags & IS_STORE; 361a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (isLoad || isStore) { 362a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham newLIR->opcode = kMipsPref; 363a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham newLIR->operands[0] = isLoad ? 0 : 1; 364a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham newLIR->operands[1] = nextLIR->operands[1]; 365a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham newLIR->operands[2] = nextLIR->operands[2]; 366a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham newLIR->defMask = nextLIR->defMask; 367a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham newLIR->useMask = nextLIR->useMask; 368a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return newLIR; 369a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 370a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 371a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 372a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 373a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* couldn't find a useful instruction to move into the delay slot */ 374a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham newLIR->opcode = kMipsNop; 375a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham return newLIR; 376a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 377a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 378a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham/* 379a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * The branch delay slot has been ignored thus far. This is the point where 380a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * a useful instruction is moved into it or a nop is inserted. Leave existing 381a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * NOPs alone -- these came from sparse and packed switch ops and are needed 382a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham * to maintain the proper offset to the jump table. 383a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham */ 384a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamstatic void introduceBranchDelaySlot(CompilationUnit *cUnit) 385a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 386a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *thisLIR; 387a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *firstLIR =(MipsLIR *) cUnit->firstLIRInsn; 388a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *lastLIR =(MipsLIR *) cUnit->lastLIRInsn; 389a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 390a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham for (thisLIR = lastLIR; thisLIR != firstLIR; thisLIR = PREV_LIR(thisLIR)) { 391a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (thisLIR->flags.isNop || 392a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham isPseudoOpCode(thisLIR->opcode) || 393a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham !(EncodingMap[thisLIR->opcode].flags & IS_BRANCH)) { 394a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham continue; 395a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else if (thisLIR == lastLIR) { 396a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerAppendLIR(cUnit, 397a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham (LIR *) delaySlotLIR(firstLIR, thisLIR)); 398a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } else if (NEXT_LIR(thisLIR)->opcode != kMipsNop) { 399a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerInsertLIRAfter((LIR *) thisLIR, 400a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham (LIR *) delaySlotLIR(firstLIR, thisLIR)); 401a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 402a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 403a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 404a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham if (!thisLIR->flags.isNop && 405a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham !isPseudoOpCode(thisLIR->opcode) && 406a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham EncodingMap[thisLIR->opcode].flags & IS_BRANCH) { 407a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham /* nothing available to move, so insert nop */ 408a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham MipsLIR *nopLIR = (MipsLIR *) dvmCompilerNew(sizeof(MipsLIR), true); 409a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham nopLIR->opcode = kMipsNop; 410a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham dvmCompilerInsertLIRAfter((LIR *) thisLIR, (LIR *) nopLIR); 411a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham } 412a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 413a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham 414a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandhamvoid dvmCompilerApplyGlobalOptimizations(CompilationUnit *cUnit) 415a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham{ 416a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham applyRedundantBranchElimination(cUnit); 417a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham applyCopyPropagation(cUnit); 418a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#ifdef __mips_hard_float 419a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham mergeMovs(cUnit); 420a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham#endif 421a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham introduceBranchDelaySlot(cUnit); 422a8b91c52fd8a90b784835dfe1f8898035266c4ddRaghu Gandham} 423