PhiInsn.java revision de75089fb7216d19e9c22cce4dc62a49513477d3
1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.ssa;
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.*;
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.Type;
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.type.TypeBearer;
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.Hex;
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.ArrayList;
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.List;
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * A Phi instruction (magical post-control-flow-merge) instruction
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in SSA form. Will be converted to moves in predecessor blocks before
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * conversion back to ROP form.
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class PhiInsn extends SsaInsn {
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
3499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * result register. The original result register of the phi insn
3599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * is needed during the renaming process after the new result
3699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * register has already been chosen.
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
3899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    private final int ropResultReg;
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
4199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code non-null;} operands of the instruction; built up by
4299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@link #addPhiOperand}
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
4499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    private final ArrayList<Operand> operands = new ArrayList<Operand>();
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
4699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code null-ok;} source registers; constructed lazily */
4799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    private RegisterSpecList sources;
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs a new phi insn with no operands.
51de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param resultReg the result reg for this phi insn
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param block block containing this insn.
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
5599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    public PhiInsn(RegisterSpec resultReg, SsaBasicBlock block) {
5699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        super(resultReg, block);
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ropResultReg = resultReg.getReg();
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Makes a phi insn with a void result type.
62de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param resultReg the result register for this phi insn.
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param block block containing this insn.
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
6699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    public PhiInsn(final int resultReg, final SsaBasicBlock block) {
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
6899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * The result type here is bogus: The type depends on the
6999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * operand and will be derived later.
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
7199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        super(RegisterSpec.make(resultReg, Type.VOID), block);
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ropResultReg = resultReg;
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
7599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@inheritDoc} */
7699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    public PhiInsn clone() {
7799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        throw new UnsupportedOperationException("can't clone phi");
7899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    }
7999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Updates the TypeBearers of all the sources (phi operands) to be
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the current TypeBearer of the register-defining instruction's result.
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * This is used during phi-type resolution.<p>
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Note that local association of operands are preserved in this step.
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param ssaMeth method that contains this insn
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
8999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    public void updateSourcesToDefinitions(SsaMethod ssaMeth) {
9099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        for (Operand o : operands) {
91de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro            RegisterSpec def
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                = ssaMeth.getDefinitionForRegister(
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    o.regSpec.getReg()).getResult();
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            o.regSpec = o.regSpec.withType(def.getType());
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sources = null;
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Changes the result type. Used during phi type resolution
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
10499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param type {@code non-null;} new TypeBearer
10599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param local {@code null-ok;} new local info, if available
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
10799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    public void changeResultType(TypeBearer type, LocalItem local) {
10899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        setResult(RegisterSpec.makeLocalOptional(
10999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project                          getResult().getReg(), type, local));
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
11399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Gets the original rop-form result reg. This is useful during renaming.
114de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
11599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return the original rop-form result reg
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
11799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    public int getRopResultReg() {
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return ropResultReg;
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
12299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Adds an operand to this phi instruction.
123de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param registerSpec register spec, including type and reg of operand
12599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param predBlock predecessor block to be associated with this operand
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void addPhiOperand(RegisterSpec registerSpec,
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            SsaBasicBlock predBlock) {
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        operands.add(new Operand(registerSpec, predBlock.getIndex(),
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                predBlock.getRopLabel()));
131de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
13299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        // Un-cache sources, in case someone has already called getSources().
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sources = null;
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the index of the pred block associated with the RegisterSpec
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * at the particular getSources() index.
139de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param sourcesIndex index of source in getSources()
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return block index
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int predBlockIndexForSourcesIndex(int sourcesIndex) {
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return operands.get(sourcesIndex).blockIndex;
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@inheritDoc}
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
15099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Always returns null for {@code PhiInsn}s.
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Rop getOpcode() {
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return null;
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@inheritDoc}
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
16099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Always returns null for {@code PhiInsn}s.
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Insn getOriginalRopInsn() {
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return null;
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@inheritDoc}
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
17099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Always returns false for {@code PhiInsn}s.
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean canThrow() {
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets sources. Constructed lazily from phi operand data structures and
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * then cached.
180de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
18199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} sources list
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public RegisterSpecList getSources() {
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (sources != null) {
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return sources;
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (operands.size() == 0) {
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // How'd this happen? A phi insn with no operand?
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return RegisterSpecList.EMPTY;
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int szSources = operands.size();
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sources = new RegisterSpecList(szSources);
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < szSources; i++) {
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Operand o = operands.get(i);
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sources.set(i, o.regSpec);
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sources.setImmutable();
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return sources;
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean isRegASource(int reg) {
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Avoid creating a sources list in case it has not already been
21199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project         * created.
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
21499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        for (Operand o : operands) {
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (o.regSpec.getReg() == reg) {
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return true;
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return true if all operands use the same register
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean areAllOperandsEqual() {
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (operands.size() == 0 ) {
22899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project            // This should never happen.
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return true;
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int firstReg = operands.get(0).regSpec.getReg();
23399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        for (Operand o : operands) {
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (firstReg != o.regSpec.getReg()) {
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return false;
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return true;
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void mapSourceRegisters(RegisterMapper mapper) {
24599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        for (Operand o : operands) {
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            RegisterSpec old = o.regSpec;
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            o.regSpec = mapper.map(old);
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (old != o.regSpec) {
24999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project                getBlock().getParent().onSourceChanged(this, old, o.regSpec);
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sources = null;
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
25699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Always throws an exeption, since a phi insn may not be
25799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * converted back to rop form.
258de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return always throws exception
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Insn toRopInsn() {
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throw new IllegalArgumentException(
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                "Cannot convert phi insns to rop form");
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the list of predecessor blocks associated with all operands
26999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * that have {@code reg} as an operand register.
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param reg register to look up
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param ssaMeth method we're operating on
27399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return list of predecessor blocks, empty if none
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
27599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    public List<SsaBasicBlock> predBlocksForReg(int reg, SsaMethod ssaMeth) {
27699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        ArrayList<SsaBasicBlock> ret = new ArrayList<SsaBasicBlock>();
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
27899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        for (Operand o : operands) {
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (o.regSpec.getReg() == reg) {
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                ret.add(ssaMeth.getBlocks().get(o.blockIndex));
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return ret;
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
28999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    public boolean isPhiOrMove() {
290de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro        return true;
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
29499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    @Override
29599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    public boolean hasSideEffect() {
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return Optimizer.getPreserveLocals() && getLocalAssignment() != null;
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void accept(SsaInsn.Visitor v) {
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        v.visitPhiInsn(this);
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
30599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@inheritDoc} */
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String toHuman() {
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return toHumanWithInline(null);
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
31199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Returns human-readable string for listing dumps. This method
31299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * allows sub-classes to specify extra text.
313de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
31499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param extra {@code null-ok;} the argument to print after the opcode
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return human-readable string for listing dumps
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected final String toHumanWithInline(String extra) {
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        StringBuffer sb = new StringBuffer(80);
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sb.append(SourcePosition.NO_INFO);
321de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro        sb.append(": phi");
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (extra != null) {
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sb.append("(");
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sb.append(extra);
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sb.append(")");
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
32999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        RegisterSpec result = getResult();
330de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (result == null) {
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sb.append(" .");
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sb.append(" ");
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sb.append(result.toHuman());
336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sb.append(" <-");
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int sz = getSources().size();
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (sz == 0) {
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sb.append(" .");
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (int i = 0; i < sz; i++) {
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                sb.append(" ");
346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                sb.append(sources.get(i).toHuman()
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        + "[b="
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        + Hex.u2(operands.get(i).ropLabel)  + "]");
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return sb.toString();
353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
35499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
35599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /**
35699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * A single phi operand, consiting of source register and block index
35799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * for move.
35899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     */
35999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    private static class Operand {
36099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        public RegisterSpec regSpec;
36199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        public final int blockIndex;
36299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        public final int ropLabel;       // only used for debugging
36399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
3644b4413ab3d8de5805276cfcde3d7f535d9f64e85Dan Bornstein        public Operand(RegisterSpec regSpec, int blockIndex, int ropLabel) {
36599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project            this.regSpec = regSpec;
36699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project            this.blockIndex = blockIndex;
36799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project            this.ropLabel = ropLabel;
36899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        }
36999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    }
37099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project
37199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /**
37299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Visitor interface for instances of this (outer) class.
37399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     */
37499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    public static interface Visitor {
37599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project        public void visitPhiInsn(PhiInsn insn);
37699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    }
377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
378