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