1311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/*
2311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Copyright (C) 2013 The Android Open Source Project
3311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee *
4311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Licensed under the Apache License, Version 2.0 (the "License");
5311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * you may not use this file except in compliance with the License.
6311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * You may obtain a copy of the License at
7311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee *
8311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee *      http://www.apache.org/licenses/LICENSE-2.0
9311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee *
10311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Unless required by applicable law or agreed to in writing, software
11311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * distributed under the License is distributed on an "AS IS" BASIS,
12311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * See the License for the specific language governing permissions and
14311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * limitations under the License.
15311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */
16311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee
17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_COMPILER_DEX_MIR_GRAPH_H_
18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_COMPILER_DEX_MIR_GRAPH_H_
19311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee
20311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#include "dex_file.h"
21311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#include "dex_instruction.h"
22311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#include "compiler_ir.h"
23862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee#include "arena_bit_vector.h"
24862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee#include "growable_array.h"
25311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee
26311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeenamespace art {
27311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee
28ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbeeenum InstructionAnalysisAttributePos {
29ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee  kUninterestingOp = 0,
30ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee  kArithmeticOp,
31ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee  kFPOp,
32ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee  kSingleOp,
33ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee  kDoubleOp,
34ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee  kIntOp,
35ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee  kLongOp,
36ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee  kBranchOp,
37ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee  kInvokeOp,
38ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee  kArrayOp,
39ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee  kHeavyweightOp,
40ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee  kSimpleConstOp,
41fe9ca4028f379688ecba6132ac3738171176b3e4buzbee  kMoveOp,
42fe9ca4028f379688ecba6132ac3738171176b3e4buzbee  kSwitch
43ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee};
44ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee
45ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee#define AN_NONE (1 << kUninterestingOp)
46ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee#define AN_MATH (1 << kArithmeticOp)
47ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee#define AN_FP (1 << kFPOp)
48ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee#define AN_LONG (1 << kLongOp)
49ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee#define AN_INT (1 << kIntOp)
50ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee#define AN_SINGLE (1 << kSingleOp)
51ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee#define AN_DOUBLE (1 << kDoubleOp)
52ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee#define AN_FLOATMATH (1 << kFPOp)
53ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee#define AN_BRANCH (1 << kBranchOp)
54ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee#define AN_INVOKE (1 << kInvokeOp)
55ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee#define AN_ARRAYOP (1 << kArrayOp)
56ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee#define AN_HEAVYWEIGHT (1 << kHeavyweightOp)
57ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee#define AN_SIMPLECONST (1 << kSimpleConstOp)
58ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee#define AN_MOVE (1 << kMoveOp)
59fe9ca4028f379688ecba6132ac3738171176b3e4buzbee#define AN_SWITCH (1 << kSwitch)
60ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee#define AN_COMPUTATIONAL (AN_MATH | AN_ARRAYOP | AN_MOVE | AN_SIMPLECONST)
61ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee
62311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeeenum DataFlowAttributePos {
63311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kUA = 0,
64311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kUB,
65311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kUC,
66311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kAWide,
67311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kBWide,
68311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kCWide,
69311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kDA,
70311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kIsMove,
71311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kSetsConst,
72311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kFormat35c,
73311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kFormat3rc,
74311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kNullCheckSrc0,        // Null check of uses[0].
75311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kNullCheckSrc1,        // Null check of uses[1].
76311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kNullCheckSrc2,        // Null check of uses[2].
77311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kNullCheckOut0,        // Null check out outgoing arg0.
78311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kDstNonNull,           // May assume dst is non-null.
79311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kRetNonNull,           // May assume retval is non-null.
80311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kNullTransferSrc0,     // Object copy src[0] -> dst.
81311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kNullTransferSrcN,     // Phi null check state transfer.
82311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kRangeCheckSrc1,       // Range check of uses[1].
83311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kRangeCheckSrc2,       // Range check of uses[2].
84311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kRangeCheckSrc3,       // Range check of uses[3].
85311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kFPA,
86311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kFPB,
87311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kFPC,
88311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kCoreA,
89311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kCoreB,
90311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kCoreC,
91311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kRefA,
92311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kRefB,
93311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kRefC,
94311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  kUsesMethodStar,       // Implicit use of Method*.
95311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee};
96311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee
97311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_NOP                  0
98311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_UA                   (1 << kUA)
99311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_UB                   (1 << kUB)
100311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_UC                   (1 << kUC)
101311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_A_WIDE               (1 << kAWide)
102311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_B_WIDE               (1 << kBWide)
103311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_C_WIDE               (1 << kCWide)
104311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_DA                   (1 << kDA)
105311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_IS_MOVE              (1 << kIsMove)
106311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_SETS_CONST           (1 << kSetsConst)
107311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_FORMAT_35C           (1 << kFormat35c)
108311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_FORMAT_3RC           (1 << kFormat3rc)
109311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_NULL_CHK_0           (1 << kNullCheckSrc0)
110311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_NULL_CHK_1           (1 << kNullCheckSrc1)
111311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_NULL_CHK_2           (1 << kNullCheckSrc2)
112311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_NULL_CHK_OUT0        (1 << kNullCheckOut0)
113311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_NON_NULL_DST         (1 << kDstNonNull)
114311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_NON_NULL_RET         (1 << kRetNonNull)
115311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_NULL_TRANSFER_0      (1 << kNullTransferSrc0)
116311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_NULL_TRANSFER_N      (1 << kNullTransferSrcN)
117311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_RANGE_CHK_1          (1 << kRangeCheckSrc1)
118311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_RANGE_CHK_2          (1 << kRangeCheckSrc2)
119311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_RANGE_CHK_3          (1 << kRangeCheckSrc3)
120311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_FP_A                 (1 << kFPA)
121311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_FP_B                 (1 << kFPB)
122311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_FP_C                 (1 << kFPC)
123311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_CORE_A               (1 << kCoreA)
124311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_CORE_B               (1 << kCoreB)
125311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_CORE_C               (1 << kCoreC)
126311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_REF_A                (1 << kRefA)
127311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_REF_B                (1 << kRefB)
128311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_REF_C                (1 << kRefC)
129311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_UMS                  (1 << kUsesMethodStar)
130311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee
131311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_HAS_USES             (DF_UA | DF_UB | DF_UC)
132311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee
133311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_HAS_DEFS             (DF_DA)
134311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee
135311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_HAS_NULL_CHKS        (DF_NULL_CHK_0 | \
136311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee                                 DF_NULL_CHK_1 | \
137311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee                                 DF_NULL_CHK_2 | \
138311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee                                 DF_NULL_CHK_OUT0)
139311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee
140311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_HAS_RANGE_CHKS       (DF_RANGE_CHK_1 | \
141311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee                                 DF_RANGE_CHK_2 | \
142311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee                                 DF_RANGE_CHK_3)
143311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee
144311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_HAS_NR_CHKS          (DF_HAS_NULL_CHKS | \
145311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee                                 DF_HAS_RANGE_CHKS)
146311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee
147311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_A_IS_REG             (DF_UA | DF_DA)
148311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_B_IS_REG             (DF_UB)
149311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_C_IS_REG             (DF_UC)
150311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_IS_GETTER_OR_SETTER  (DF_IS_GETTER | DF_IS_SETTER)
151311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#define DF_USES_FP              (DF_FP_A | DF_FP_B | DF_FP_C)
152311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee
1531fd3346740dfb7f47be9922312b68a4227fada96buzbeeenum OatMethodAttributes {
1541fd3346740dfb7f47be9922312b68a4227fada96buzbee  kIsLeaf,            // Method is leaf.
1551fd3346740dfb7f47be9922312b68a4227fada96buzbee  kHasLoop,           // Method contains simple loop.
1561fd3346740dfb7f47be9922312b68a4227fada96buzbee};
1571fd3346740dfb7f47be9922312b68a4227fada96buzbee
1581fd3346740dfb7f47be9922312b68a4227fada96buzbee#define METHOD_IS_LEAF          (1 << kIsLeaf)
1591fd3346740dfb7f47be9922312b68a4227fada96buzbee#define METHOD_HAS_LOOP         (1 << kHasLoop)
1601fd3346740dfb7f47be9922312b68a4227fada96buzbee
1611fd3346740dfb7f47be9922312b68a4227fada96buzbee// Minimum field size to contain Dalvik v_reg number.
1621fd3346740dfb7f47be9922312b68a4227fada96buzbee#define VREG_NUM_WIDTH 16
1631fd3346740dfb7f47be9922312b68a4227fada96buzbee
1641fd3346740dfb7f47be9922312b68a4227fada96buzbee#define INVALID_SREG (-1)
1651fd3346740dfb7f47be9922312b68a4227fada96buzbee#define INVALID_VREG (0xFFFFU)
1661fd3346740dfb7f47be9922312b68a4227fada96buzbee#define INVALID_REG (0xFF)
1671fd3346740dfb7f47be9922312b68a4227fada96buzbee#define INVALID_OFFSET (0xDEADF00FU)
1681fd3346740dfb7f47be9922312b68a4227fada96buzbee
1691fd3346740dfb7f47be9922312b68a4227fada96buzbee/* SSA encodings for special registers */
1701fd3346740dfb7f47be9922312b68a4227fada96buzbee#define SSA_METHOD_BASEREG (-2)
1711fd3346740dfb7f47be9922312b68a4227fada96buzbee/* First compiler temp basereg, grows smaller */
1721fd3346740dfb7f47be9922312b68a4227fada96buzbee#define SSA_CTEMP_BASEREG (SSA_METHOD_BASEREG - 1)
1731fd3346740dfb7f47be9922312b68a4227fada96buzbee
1741fd3346740dfb7f47be9922312b68a4227fada96buzbee#define MIR_IGNORE_NULL_CHECK           (1 << kMIRIgnoreNullCheck)
1751fd3346740dfb7f47be9922312b68a4227fada96buzbee#define MIR_NULL_CHECK_ONLY             (1 << kMIRNullCheckOnly)
1761fd3346740dfb7f47be9922312b68a4227fada96buzbee#define MIR_IGNORE_RANGE_CHECK          (1 << kMIRIgnoreRangeCheck)
1771fd3346740dfb7f47be9922312b68a4227fada96buzbee#define MIR_RANGE_CHECK_ONLY            (1 << kMIRRangeCheckOnly)
1781fd3346740dfb7f47be9922312b68a4227fada96buzbee#define MIR_INLINED                     (1 << kMIRInlined)
1791fd3346740dfb7f47be9922312b68a4227fada96buzbee#define MIR_INLINED_PRED                (1 << kMIRInlinedPred)
1801fd3346740dfb7f47be9922312b68a4227fada96buzbee#define MIR_CALLEE                      (1 << kMIRCallee)
1811fd3346740dfb7f47be9922312b68a4227fada96buzbee#define MIR_IGNORE_SUSPEND_CHECK        (1 << kMIRIgnoreSuspendCheck)
1821fd3346740dfb7f47be9922312b68a4227fada96buzbee#define MIR_DUP                         (1 << kMIRDup)
1831fd3346740dfb7f47be9922312b68a4227fada96buzbee
184862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee#define BLOCK_NAME_LEN 80
185862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee
1861fd3346740dfb7f47be9922312b68a4227fada96buzbee/*
1871fd3346740dfb7f47be9922312b68a4227fada96buzbee * In general, vreg/sreg describe Dalvik registers that originated with dx.  However,
1881fd3346740dfb7f47be9922312b68a4227fada96buzbee * it is useful to have compiler-generated temporary registers and have them treated
1891fd3346740dfb7f47be9922312b68a4227fada96buzbee * in the same manner as dx-generated virtual registers.  This struct records the SSA
1901fd3346740dfb7f47be9922312b68a4227fada96buzbee * name of compiler-introduced temporaries.
1911fd3346740dfb7f47be9922312b68a4227fada96buzbee */
1921fd3346740dfb7f47be9922312b68a4227fada96buzbeestruct CompilerTemp {
1931fd3346740dfb7f47be9922312b68a4227fada96buzbee  int s_reg;
1941fd3346740dfb7f47be9922312b68a4227fada96buzbee};
1951fd3346740dfb7f47be9922312b68a4227fada96buzbee
1961fd3346740dfb7f47be9922312b68a4227fada96buzbee// When debug option enabled, records effectiveness of null and range check elimination.
1971fd3346740dfb7f47be9922312b68a4227fada96buzbeestruct Checkstats {
1981fd3346740dfb7f47be9922312b68a4227fada96buzbee  int null_checks;
1991fd3346740dfb7f47be9922312b68a4227fada96buzbee  int null_checks_eliminated;
2001fd3346740dfb7f47be9922312b68a4227fada96buzbee  int range_checks;
2011fd3346740dfb7f47be9922312b68a4227fada96buzbee  int range_checks_eliminated;
2021fd3346740dfb7f47be9922312b68a4227fada96buzbee};
2031fd3346740dfb7f47be9922312b68a4227fada96buzbee
2041fd3346740dfb7f47be9922312b68a4227fada96buzbee// Dataflow attributes of a basic block.
2051fd3346740dfb7f47be9922312b68a4227fada96buzbeestruct BasicBlockDataFlow {
2061fd3346740dfb7f47be9922312b68a4227fada96buzbee  ArenaBitVector* use_v;
2071fd3346740dfb7f47be9922312b68a4227fada96buzbee  ArenaBitVector* def_v;
2081fd3346740dfb7f47be9922312b68a4227fada96buzbee  ArenaBitVector* live_in_v;
2091fd3346740dfb7f47be9922312b68a4227fada96buzbee  ArenaBitVector* phi_v;
2101fd3346740dfb7f47be9922312b68a4227fada96buzbee  int* vreg_to_ssa_map;
2111fd3346740dfb7f47be9922312b68a4227fada96buzbee  ArenaBitVector* ending_null_check_v;
2121fd3346740dfb7f47be9922312b68a4227fada96buzbee};
2131fd3346740dfb7f47be9922312b68a4227fada96buzbee
2141fd3346740dfb7f47be9922312b68a4227fada96buzbee/*
2151fd3346740dfb7f47be9922312b68a4227fada96buzbee * Normalized use/def for a MIR operation using SSA names rather than vregs.  Note that
2161fd3346740dfb7f47be9922312b68a4227fada96buzbee * uses/defs retain the Dalvik convention that long operations operate on a pair of 32-bit
2171fd3346740dfb7f47be9922312b68a4227fada96buzbee * vregs.  For example, "ADD_LONG v0, v2, v3" would have 2 defs (v0/v1) and 4 uses (v2/v3, v4/v5).
2181fd3346740dfb7f47be9922312b68a4227fada96buzbee * Following SSA renaming, this is the primary struct used by code generators to locate
2191fd3346740dfb7f47be9922312b68a4227fada96buzbee * operand and result registers.  This is a somewhat confusing and unhelpful convention that
2201fd3346740dfb7f47be9922312b68a4227fada96buzbee * we may want to revisit in the future.
2211fd3346740dfb7f47be9922312b68a4227fada96buzbee */
2221fd3346740dfb7f47be9922312b68a4227fada96buzbeestruct SSARepresentation {
2231fd3346740dfb7f47be9922312b68a4227fada96buzbee  int num_uses;
2241fd3346740dfb7f47be9922312b68a4227fada96buzbee  int* uses;
2251fd3346740dfb7f47be9922312b68a4227fada96buzbee  bool* fp_use;
2261fd3346740dfb7f47be9922312b68a4227fada96buzbee  int num_defs;
2271fd3346740dfb7f47be9922312b68a4227fada96buzbee  int* defs;
2281fd3346740dfb7f47be9922312b68a4227fada96buzbee  bool* fp_def;
2291fd3346740dfb7f47be9922312b68a4227fada96buzbee};
2301fd3346740dfb7f47be9922312b68a4227fada96buzbee
2311fd3346740dfb7f47be9922312b68a4227fada96buzbee/*
2321fd3346740dfb7f47be9922312b68a4227fada96buzbee * The Midlevel Intermediate Representation node, which may be largely considered a
2331fd3346740dfb7f47be9922312b68a4227fada96buzbee * wrapper around a Dalvik byte code.
2341fd3346740dfb7f47be9922312b68a4227fada96buzbee */
2351fd3346740dfb7f47be9922312b68a4227fada96buzbeestruct MIR {
2361fd3346740dfb7f47be9922312b68a4227fada96buzbee  DecodedInstruction dalvikInsn;
2379329e6d1a8ff8d3775c4a9db9a7bb97694bc267dbuzbee  uint32_t width;                 // NOTE: only need 16 bits for width.
2381fd3346740dfb7f47be9922312b68a4227fada96buzbee  unsigned int offset;
2391fd3346740dfb7f47be9922312b68a4227fada96buzbee  int m_unit_index;               // From which method was this MIR included
2401fd3346740dfb7f47be9922312b68a4227fada96buzbee  MIR* prev;
2411fd3346740dfb7f47be9922312b68a4227fada96buzbee  MIR* next;
2421fd3346740dfb7f47be9922312b68a4227fada96buzbee  SSARepresentation* ssa_rep;
2431fd3346740dfb7f47be9922312b68a4227fada96buzbee  int optimization_flags;
2441fd3346740dfb7f47be9922312b68a4227fada96buzbee  union {
2451fd3346740dfb7f47be9922312b68a4227fada96buzbee    // Establish link between two halves of throwing instructions.
2461fd3346740dfb7f47be9922312b68a4227fada96buzbee    MIR* throw_insn;
2471fd3346740dfb7f47be9922312b68a4227fada96buzbee    // Saved opcode for NOP'd MIRs
2481fd3346740dfb7f47be9922312b68a4227fada96buzbee    Instruction::Code original_opcode;
2491fd3346740dfb7f47be9922312b68a4227fada96buzbee  } meta;
2501fd3346740dfb7f47be9922312b68a4227fada96buzbee};
2511fd3346740dfb7f47be9922312b68a4227fada96buzbee
252862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbeestruct SuccessorBlockInfo;
253862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee
2541fd3346740dfb7f47be9922312b68a4227fada96buzbeestruct BasicBlock {
2551fd3346740dfb7f47be9922312b68a4227fada96buzbee  int id;
2561fd3346740dfb7f47be9922312b68a4227fada96buzbee  int dfs_id;
2571fd3346740dfb7f47be9922312b68a4227fada96buzbee  bool visited;
2581fd3346740dfb7f47be9922312b68a4227fada96buzbee  bool hidden;
2591fd3346740dfb7f47be9922312b68a4227fada96buzbee  bool catch_entry;
2601fd3346740dfb7f47be9922312b68a4227fada96buzbee  bool explicit_throw;
2611fd3346740dfb7f47be9922312b68a4227fada96buzbee  bool conditional_branch;
2621fd3346740dfb7f47be9922312b68a4227fada96buzbee  bool terminated_by_return;        // Block ends with a Dalvik return opcode.
2631fd3346740dfb7f47be9922312b68a4227fada96buzbee  bool dominates_return;            // Is a member of return extended basic block.
2641fd3346740dfb7f47be9922312b68a4227fada96buzbee  uint16_t start_offset;
2651fd3346740dfb7f47be9922312b68a4227fada96buzbee  uint16_t nesting_depth;
2661fd3346740dfb7f47be9922312b68a4227fada96buzbee  BBType block_type;
2671fd3346740dfb7f47be9922312b68a4227fada96buzbee  MIR* first_mir_insn;
2681fd3346740dfb7f47be9922312b68a4227fada96buzbee  MIR* last_mir_insn;
2691fd3346740dfb7f47be9922312b68a4227fada96buzbee  BasicBlock* fall_through;
2701fd3346740dfb7f47be9922312b68a4227fada96buzbee  BasicBlock* taken;
2711fd3346740dfb7f47be9922312b68a4227fada96buzbee  BasicBlock* i_dom;                // Immediate dominator.
2721fd3346740dfb7f47be9922312b68a4227fada96buzbee  BasicBlockDataFlow* data_flow_info;
273862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee  GrowableArray<BasicBlock*>* predecessors;
2741fd3346740dfb7f47be9922312b68a4227fada96buzbee  ArenaBitVector* dominators;
2751fd3346740dfb7f47be9922312b68a4227fada96buzbee  ArenaBitVector* i_dominated;      // Set nodes being immediately dominated.
2761fd3346740dfb7f47be9922312b68a4227fada96buzbee  ArenaBitVector* dom_frontier;     // Dominance frontier.
2771fd3346740dfb7f47be9922312b68a4227fada96buzbee  struct {                          // For one-to-many successors like.
2781fd3346740dfb7f47be9922312b68a4227fada96buzbee    BlockListType block_list_type;  // switch and exception handling.
279862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee    GrowableArray<SuccessorBlockInfo*>* blocks;
2801fd3346740dfb7f47be9922312b68a4227fada96buzbee  } successor_block_list;
2811fd3346740dfb7f47be9922312b68a4227fada96buzbee};
2821fd3346740dfb7f47be9922312b68a4227fada96buzbee
2831fd3346740dfb7f47be9922312b68a4227fada96buzbee/*
2841fd3346740dfb7f47be9922312b68a4227fada96buzbee * The "blocks" field in "successor_block_list" points to an array of elements with the type
2851fd3346740dfb7f47be9922312b68a4227fada96buzbee * "SuccessorBlockInfo".  For catch blocks, key is type index for the exception.  For swtich
2861fd3346740dfb7f47be9922312b68a4227fada96buzbee * blocks, key is the case value.
2871fd3346740dfb7f47be9922312b68a4227fada96buzbee */
288862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee// TODO: make class with placement new.
2891fd3346740dfb7f47be9922312b68a4227fada96buzbeestruct SuccessorBlockInfo {
2901fd3346740dfb7f47be9922312b68a4227fada96buzbee  BasicBlock* block;
2911fd3346740dfb7f47be9922312b68a4227fada96buzbee  int key;
2921fd3346740dfb7f47be9922312b68a4227fada96buzbee};
2931fd3346740dfb7f47be9922312b68a4227fada96buzbee
2941fd3346740dfb7f47be9922312b68a4227fada96buzbee/*
2951fd3346740dfb7f47be9922312b68a4227fada96buzbee * Whereas a SSA name describes a definition of a Dalvik vreg, the RegLocation describes
2961fd3346740dfb7f47be9922312b68a4227fada96buzbee * the type of an SSA name (and, can also be used by code generators to record where the
2971fd3346740dfb7f47be9922312b68a4227fada96buzbee * value is located (i.e. - physical register, frame, spill, etc.).  For each SSA name (SReg)
2981fd3346740dfb7f47be9922312b68a4227fada96buzbee * there is a RegLocation.
2991fd3346740dfb7f47be9922312b68a4227fada96buzbee * FIXME: The orig_sreg field was added as a workaround for llvm bitcode generation.  With
3001fd3346740dfb7f47be9922312b68a4227fada96buzbee * the latest restructuring, we should be able to remove it and rely on s_reg_low throughout.
3011fd3346740dfb7f47be9922312b68a4227fada96buzbee */
3021fd3346740dfb7f47be9922312b68a4227fada96buzbeestruct RegLocation {
3031fd3346740dfb7f47be9922312b68a4227fada96buzbee  RegLocationType location:3;
3041fd3346740dfb7f47be9922312b68a4227fada96buzbee  unsigned wide:1;
3051fd3346740dfb7f47be9922312b68a4227fada96buzbee  unsigned defined:1;   // Do we know the type?
3061fd3346740dfb7f47be9922312b68a4227fada96buzbee  unsigned is_const:1;  // Constant, value in mir_graph->constant_values[].
3071fd3346740dfb7f47be9922312b68a4227fada96buzbee  unsigned fp:1;        // Floating point?
3081fd3346740dfb7f47be9922312b68a4227fada96buzbee  unsigned core:1;      // Non-floating point?
3091fd3346740dfb7f47be9922312b68a4227fada96buzbee  unsigned ref:1;       // Something GC cares about.
3107934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom  unsigned high_word:1;  // High word of pair?
3111fd3346740dfb7f47be9922312b68a4227fada96buzbee  unsigned home:1;      // Does this represent the home location?
3121fd3346740dfb7f47be9922312b68a4227fada96buzbee  uint8_t low_reg;      // First physical register.
3131fd3346740dfb7f47be9922312b68a4227fada96buzbee  uint8_t high_reg;     // 2nd physical register (if wide).
3141fd3346740dfb7f47be9922312b68a4227fada96buzbee  int32_t s_reg_low;    // SSA name for low Dalvik word.
3151fd3346740dfb7f47be9922312b68a4227fada96buzbee  int32_t orig_sreg;    // TODO: remove after Bitcode gen complete
3161fd3346740dfb7f47be9922312b68a4227fada96buzbee                        // and consolodate usage w/ s_reg_low.
3171fd3346740dfb7f47be9922312b68a4227fada96buzbee};
3181fd3346740dfb7f47be9922312b68a4227fada96buzbee
3191fd3346740dfb7f47be9922312b68a4227fada96buzbee/*
3201fd3346740dfb7f47be9922312b68a4227fada96buzbee * Collection of information describing an invoke, and the destination of
3211fd3346740dfb7f47be9922312b68a4227fada96buzbee * the subsequent MOVE_RESULT (if applicable).  Collected as a unit to enable
3221fd3346740dfb7f47be9922312b68a4227fada96buzbee * more efficient invoke code generation.
3231fd3346740dfb7f47be9922312b68a4227fada96buzbee */
3241fd3346740dfb7f47be9922312b68a4227fada96buzbeestruct CallInfo {
3251fd3346740dfb7f47be9922312b68a4227fada96buzbee  int num_arg_words;    // Note: word count, not arg count.
3261fd3346740dfb7f47be9922312b68a4227fada96buzbee  RegLocation* args;    // One for each word of arguments.
3271fd3346740dfb7f47be9922312b68a4227fada96buzbee  RegLocation result;   // Eventual target of MOVE_RESULT.
3281fd3346740dfb7f47be9922312b68a4227fada96buzbee  int opt_flags;
3291fd3346740dfb7f47be9922312b68a4227fada96buzbee  InvokeType type;
3301fd3346740dfb7f47be9922312b68a4227fada96buzbee  uint32_t dex_idx;
3311fd3346740dfb7f47be9922312b68a4227fada96buzbee  uint32_t index;       // Method idx for invokes, type idx for FilledNewArray.
3321fd3346740dfb7f47be9922312b68a4227fada96buzbee  uintptr_t direct_code;
3331fd3346740dfb7f47be9922312b68a4227fada96buzbee  uintptr_t direct_method;
3341fd3346740dfb7f47be9922312b68a4227fada96buzbee  RegLocation target;    // Target of following move_result.
3351fd3346740dfb7f47be9922312b68a4227fada96buzbee  bool skip_this;
3361fd3346740dfb7f47be9922312b68a4227fada96buzbee  bool is_range;
3371fd3346740dfb7f47be9922312b68a4227fada96buzbee  int offset;            // Dalvik offset.
3381fd3346740dfb7f47be9922312b68a4227fada96buzbee};
3391fd3346740dfb7f47be9922312b68a4227fada96buzbee
3401fd3346740dfb7f47be9922312b68a4227fada96buzbee
3411fd3346740dfb7f47be9922312b68a4227fada96buzbeeconst RegLocation bad_loc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0,
3421fd3346740dfb7f47be9922312b68a4227fada96buzbee                             INVALID_REG, INVALID_REG, INVALID_SREG, INVALID_SREG};
343311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee
344311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeeclass MIRGraph {
34571fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers public:
346862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee  MIRGraph(CompilationUnit* cu, ArenaAllocator* arena);
3476282dc12440a2072dc06a616160027ff21bd895eIan Rogers  ~MIRGraph();
34871fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
34971fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  /*
350ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee   * Examine the graph to determine whether it's worthwile to spend the time compiling
351ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee   * this method.
352ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee   */
353ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee  bool SkipCompilation(Runtime::CompilerFilter compiler_filter);
354ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee
355ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee  /*
35671fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers   * Parse dex method and add MIR at current insert point.  Returns id (which is
35771fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers   * actually the index of the method in the m_units_ array).
35871fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers   */
35971fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  void InlineMethod(const DexFile::CodeItem* code_item, uint32_t access_flags,
360ee39a10e45a6a0880e8b829525c40d6055818560Ian Rogers                    InvokeType invoke_type, uint16_t class_def_idx,
36171fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers                    uint32_t method_idx, jobject class_loader, const DexFile& dex_file);
36271fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
36371fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  /* Find existing block */
36471fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  BasicBlock* FindBlock(unsigned int code_offset) {
36571fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers    return FindBlock(code_offset, false, false, NULL);
36671fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
36771fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
36871fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  const uint16_t* GetCurrentInsns() const {
36971fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers    return current_code_item_->insns_;
37071fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
37171fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
37271fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  const uint16_t* GetInsns(int m_unit_index) const {
37371fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers    return m_units_[m_unit_index]->GetCodeItem()->insns_;
37471fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
37571fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
37671fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  int GetNumBlocks() const {
37771fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers    return num_blocks_;
37871fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
37971fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
380ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee  size_t GetNumDalvikInsns() const {
381ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee    return cu_->code_item->insns_size_in_code_units_;
382ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee  }
383ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee
38471fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  ArenaBitVector* GetTryBlockAddr() const {
38571fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers    return try_block_addr_;
38671fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
38771fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
38871fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  BasicBlock* GetEntryBlock() const {
38971fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers    return entry_block_;
39071fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
39171fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
39271fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  BasicBlock* GetExitBlock() const {
39371fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers    return exit_block_;
39471fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
39571fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
39671fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  BasicBlock* GetBasicBlock(int block_id) const {
397862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee    return block_list_.Get(block_id);
39871fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
39971fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
40071fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  size_t GetBasicBlockListCount() const {
401862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee    return block_list_.Size();
40271fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
40371fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
404862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee  GrowableArray<BasicBlock*>* GetBlockList() {
40571fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers    return &block_list_;
40671fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
40771fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
408862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee  GrowableArray<int>* GetDfsOrder() {
409862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee    return dfs_order_;
41071fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
41171fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
412862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee  GrowableArray<int>* GetDfsPostOrder() {
413862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee    return dfs_post_order_;
41471fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
41571fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
416862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee  GrowableArray<int>* GetDomPostOrder() {
417862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee    return dom_post_order_traversal_;
41871fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
41971fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
42071fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  int GetDefCount() const {
42171fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers    return def_count_;
42271fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
42371fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
424862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee  ArenaAllocator* GetArena() {
425862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee    return arena_;
426862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee  }
427862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee
42871fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  void EnableOpcodeCounting() {
429f6c4b3ba3825de1dbb3e747a68b809c6cc8eb4dbMathieu Chartier    opcode_count_ = static_cast<int*>(arena_->Alloc(kNumPackedOpcodes * sizeof(int),
430f6c4b3ba3825de1dbb3e747a68b809c6cc8eb4dbMathieu Chartier                                                    ArenaAllocator::kAllocMisc));
43171fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
43271fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
43371fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  void ShowOpcodeStats();
43471fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
43571fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  DexCompilationUnit* GetCurrentDexCompilationUnit() const {
43671fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers    return m_units_[current_method_];
43771fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
43871fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
43971fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  void DumpCFG(const char* dir_prefix, bool all_blocks);
44071fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
44171fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  void BuildRegLocations();
44271fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
44371fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  void DumpRegLocTable(RegLocation* table, int count);
44471fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
44571fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  void BasicBlockOptimization();
44671fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
44771fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  bool IsConst(int32_t s_reg) const {
448862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee    return is_constant_v_->IsBitSet(s_reg);
44971fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
45071fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
45171fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  bool IsConst(RegLocation loc) const {
45271fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers    return (IsConst(loc.orig_sreg));
45371fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
45471fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
45571fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  int32_t ConstantValue(RegLocation loc) const {
45671fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers    DCHECK(IsConst(loc));
45771fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers    return constant_values_[loc.orig_sreg];
45871fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
45971fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
46071fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  int32_t ConstantValue(int32_t s_reg) const {
46171fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers    DCHECK(IsConst(s_reg));
46271fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers    return constant_values_[s_reg];
46371fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
46471fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
46571fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  int64_t ConstantValueWide(RegLocation loc) const {
46671fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers    DCHECK(IsConst(loc));
46771fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers    return (static_cast<int64_t>(constant_values_[loc.orig_sreg + 1]) << 32) |
46871fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers        Low32Bits(static_cast<int64_t>(constant_values_[loc.orig_sreg]));
46971fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
47071fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
47171fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  bool IsConstantNullRef(RegLocation loc) const {
47271fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers    return loc.ref && loc.is_const && (ConstantValue(loc) == 0);
47371fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
47471fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
47571fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  int GetNumSSARegs() const {
47671fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers    return num_ssa_regs_;
47771fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
47871fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
47971fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  void SetNumSSARegs(int new_num) {
48071fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers    num_ssa_regs_ = new_num;
48171fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
48271fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
483862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee  unsigned int GetNumReachableBlocks() const {
48471fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers    return num_reachable_blocks_;
48571fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
48671fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
48771fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  int GetUseCount(int vreg) const {
488862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee    return use_counts_.Get(vreg);
48971fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
49071fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
49171fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  int GetRawUseCount(int vreg) const {
492862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee    return raw_use_counts_.Get(vreg);
49371fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
49471fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
49571fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  int GetSSASubscript(int ssa_reg) const {
496862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee    return ssa_subscripts_->Get(ssa_reg);
49771fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  }
49871fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
4992ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom  RegLocation GetRawSrc(MIR* mir, int num) {
5001fd3346740dfb7f47be9922312b68a4227fada96buzbee    DCHECK(num < mir->ssa_rep->num_uses);
5011fd3346740dfb7f47be9922312b68a4227fada96buzbee    RegLocation res = reg_location_[mir->ssa_rep->uses[num]];
5021fd3346740dfb7f47be9922312b68a4227fada96buzbee    return res;
5031fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
5041fd3346740dfb7f47be9922312b68a4227fada96buzbee
5052ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom  RegLocation GetRawDest(MIR* mir) {
5061fd3346740dfb7f47be9922312b68a4227fada96buzbee    DCHECK_GT(mir->ssa_rep->num_defs, 0);
5071fd3346740dfb7f47be9922312b68a4227fada96buzbee    RegLocation res = reg_location_[mir->ssa_rep->defs[0]];
5081fd3346740dfb7f47be9922312b68a4227fada96buzbee    return res;
5091fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
5101fd3346740dfb7f47be9922312b68a4227fada96buzbee
5112ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom  RegLocation GetDest(MIR* mir) {
5121fd3346740dfb7f47be9922312b68a4227fada96buzbee    RegLocation res = GetRawDest(mir);
5131fd3346740dfb7f47be9922312b68a4227fada96buzbee    DCHECK(!res.wide);
5141fd3346740dfb7f47be9922312b68a4227fada96buzbee    return res;
5151fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
5161fd3346740dfb7f47be9922312b68a4227fada96buzbee
5172ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom  RegLocation GetSrc(MIR* mir, int num) {
5181fd3346740dfb7f47be9922312b68a4227fada96buzbee    RegLocation res = GetRawSrc(mir, num);
5191fd3346740dfb7f47be9922312b68a4227fada96buzbee    DCHECK(!res.wide);
5201fd3346740dfb7f47be9922312b68a4227fada96buzbee    return res;
5211fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
5221fd3346740dfb7f47be9922312b68a4227fada96buzbee
5232ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom  RegLocation GetDestWide(MIR* mir) {
5241fd3346740dfb7f47be9922312b68a4227fada96buzbee    RegLocation res = GetRawDest(mir);
5251fd3346740dfb7f47be9922312b68a4227fada96buzbee    DCHECK(res.wide);
5261fd3346740dfb7f47be9922312b68a4227fada96buzbee    return res;
5271fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
5281fd3346740dfb7f47be9922312b68a4227fada96buzbee
5292ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom  RegLocation GetSrcWide(MIR* mir, int low) {
5301fd3346740dfb7f47be9922312b68a4227fada96buzbee    RegLocation res = GetRawSrc(mir, low);
5311fd3346740dfb7f47be9922312b68a4227fada96buzbee    DCHECK(res.wide);
5321fd3346740dfb7f47be9922312b68a4227fada96buzbee    return res;
5331fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
5341fd3346740dfb7f47be9922312b68a4227fada96buzbee
5351fd3346740dfb7f47be9922312b68a4227fada96buzbee  RegLocation GetBadLoc() {
5361fd3346740dfb7f47be9922312b68a4227fada96buzbee    return bad_loc;
5371fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
5381fd3346740dfb7f47be9922312b68a4227fada96buzbee
5391fd3346740dfb7f47be9922312b68a4227fada96buzbee  int GetMethodSReg() {
5401fd3346740dfb7f47be9922312b68a4227fada96buzbee    return method_sreg_;
5411fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
5421fd3346740dfb7f47be9922312b68a4227fada96buzbee
5431fd3346740dfb7f47be9922312b68a4227fada96buzbee  bool MethodIsLeaf() {
5441fd3346740dfb7f47be9922312b68a4227fada96buzbee    return attributes_ & METHOD_IS_LEAF;
5451fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
5461fd3346740dfb7f47be9922312b68a4227fada96buzbee
5471fd3346740dfb7f47be9922312b68a4227fada96buzbee  RegLocation GetRegLocation(int index) {
5481fd3346740dfb7f47be9922312b68a4227fada96buzbee    DCHECK((index >= 0) && (index > num_ssa_regs_));
5491fd3346740dfb7f47be9922312b68a4227fada96buzbee    return reg_location_[index];
5501fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
5511fd3346740dfb7f47be9922312b68a4227fada96buzbee
5521fd3346740dfb7f47be9922312b68a4227fada96buzbee  RegLocation GetMethodLoc() {
5531fd3346740dfb7f47be9922312b68a4227fada96buzbee    return reg_location_[method_sreg_];
5541fd3346740dfb7f47be9922312b68a4227fada96buzbee  }
5551fd3346740dfb7f47be9922312b68a4227fada96buzbee
556479f83c196d5a95e36196eac548dc6019e70a5bebuzbee  bool IsSpecialCase() {
557479f83c196d5a95e36196eac548dc6019e70a5bebuzbee    return special_case_ != kNoHandler;
558479f83c196d5a95e36196eac548dc6019e70a5bebuzbee  }
559479f83c196d5a95e36196eac548dc6019e70a5bebuzbee
560479f83c196d5a95e36196eac548dc6019e70a5bebuzbee  SpecialCaseHandler GetSpecialCase() {
561479f83c196d5a95e36196eac548dc6019e70a5bebuzbee    return special_case_;
562479f83c196d5a95e36196eac548dc6019e70a5bebuzbee  }
563479f83c196d5a95e36196eac548dc6019e70a5bebuzbee
5649329e6d1a8ff8d3775c4a9db9a7bb97694bc267dbuzbee  bool IsBackedge(BasicBlock* branch_bb, BasicBlock* target_bb) {
5659329e6d1a8ff8d3775c4a9db9a7bb97694bc267dbuzbee    return ((target_bb != NULL) && (target_bb->start_offset <= branch_bb->start_offset));
5669329e6d1a8ff8d3775c4a9db9a7bb97694bc267dbuzbee  }
5679329e6d1a8ff8d3775c4a9db9a7bb97694bc267dbuzbee
5689329e6d1a8ff8d3775c4a9db9a7bb97694bc267dbuzbee  bool IsBackwardsBranch(BasicBlock* branch_bb) {
5699329e6d1a8ff8d3775c4a9db9a7bb97694bc267dbuzbee    return IsBackedge(branch_bb, branch_bb->taken) || IsBackedge(branch_bb, branch_bb->fall_through);
5709329e6d1a8ff8d3775c4a9db9a7bb97694bc267dbuzbee  }
5719329e6d1a8ff8d3775c4a9db9a7bb97694bc267dbuzbee
57271fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  void BasicBlockCombine();
57371fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  void CodeLayout();
57471fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  void DumpCheckStats();
57571fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  void PropagateConstants();
57671fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  MIR* FindMoveResult(BasicBlock* bb, MIR* mir);
57771fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  int SRegToVReg(int ssa_reg) const;
57871fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  void VerifyDataflow();
57971fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  void MethodUseCount();
58071fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  void SSATransformation();
58171fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  void CheckForDominanceFrontier(BasicBlock* dom_bb, const BasicBlock* succ_bb);
58271fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  void NullCheckElimination();
5831fd3346740dfb7f47be9922312b68a4227fada96buzbee  bool SetFp(int index, bool is_fp);
5841fd3346740dfb7f47be9922312b68a4227fada96buzbee  bool SetCore(int index, bool is_core);
5851fd3346740dfb7f47be9922312b68a4227fada96buzbee  bool SetRef(int index, bool is_ref);
5861fd3346740dfb7f47be9922312b68a4227fada96buzbee  bool SetWide(int index, bool is_wide);
5871fd3346740dfb7f47be9922312b68a4227fada96buzbee  bool SetHigh(int index, bool is_high);
5881fd3346740dfb7f47be9922312b68a4227fada96buzbee  void AppendMIR(BasicBlock* bb, MIR* mir);
5891fd3346740dfb7f47be9922312b68a4227fada96buzbee  void PrependMIR(BasicBlock* bb, MIR* mir);
5901fd3346740dfb7f47be9922312b68a4227fada96buzbee  void InsertMIRAfter(BasicBlock* bb, MIR* current_mir, MIR* new_mir);
5911fd3346740dfb7f47be9922312b68a4227fada96buzbee  char* GetDalvikDisassembly(const MIR* mir);
5921fd3346740dfb7f47be9922312b68a4227fada96buzbee  void ReplaceSpecialChars(std::string& str);
5931fd3346740dfb7f47be9922312b68a4227fada96buzbee  std::string GetSSAName(int ssa_reg);
5941fd3346740dfb7f47be9922312b68a4227fada96buzbee  std::string GetSSANameWithConst(int ssa_reg, bool singles_only);
5951fd3346740dfb7f47be9922312b68a4227fada96buzbee  void GetBlockName(BasicBlock* bb, char* name);
5961fd3346740dfb7f47be9922312b68a4227fada96buzbee  const char* GetShortyFromTargetIdx(int);
5971fd3346740dfb7f47be9922312b68a4227fada96buzbee  void DumpMIRGraph();
5981fd3346740dfb7f47be9922312b68a4227fada96buzbee  CallInfo* NewMemCallInfo(BasicBlock* bb, MIR* mir, InvokeType type, bool is_range);
599862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee  BasicBlock* NewMemBB(BBType block_type, int block_id);
60071fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
60171fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers  /*
60271fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers   * IsDebugBuild sanity check: keep track of the Dex PCs for catch entries so that later on
60371fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers   * we can verify that all catch entries have native PC entries.
60471fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers   */
6056f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  std::set<uint32_t> catches_;
60671fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers
6076f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  // TODO: make these private.
6086f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  RegLocation* reg_location_;                         // Map SSA names to location.
6096f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  GrowableArray<CompilerTemp*> compiler_temps_;
6106f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  SafeMap<unsigned int, unsigned int> block_id_map_;  // Block collapse lookup cache.
6111fd3346740dfb7f47be9922312b68a4227fada96buzbee
6126f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  static const int oat_data_flow_attributes_[kMirOpLast];
6136f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  static const char* extended_mir_op_names_[kMirOpLast - kMirOpFirst];
614ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee  static const uint32_t analysis_attributes_[kMirOpLast];
6151fd3346740dfb7f47be9922312b68a4227fada96buzbee
61671fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers private:
6176f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  int FindCommonParent(int block1, int block2);
6186f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  void ComputeSuccLineIn(ArenaBitVector* dest, const ArenaBitVector* src1,
6196f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom                         const ArenaBitVector* src2);
6206f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  void HandleLiveInUse(ArenaBitVector* use_v, ArenaBitVector* def_v,
6216f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom                       ArenaBitVector* live_in_v, int dalvik_reg_id);
6226f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  void HandleDef(ArenaBitVector* def_v, int dalvik_reg_id);
6236f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  void CompilerInitializeSSAConversion();
6246f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  bool DoSSAConversion(BasicBlock* bb);
6256f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  bool InvokeUsesMethodStar(MIR* mir);
6266f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  int ParseInsn(const uint16_t* code_ptr, DecodedInstruction* decoded_instruction);
6276f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  bool ContentIsInsn(const uint16_t* code_ptr);
6286f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  BasicBlock* SplitBlock(unsigned int code_offset, BasicBlock* orig_block,
62971fe267165765bee6ff1b2e6c35de17910a14f80Ian Rogers                         BasicBlock** immed_pred_block_p);
6306f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  BasicBlock* FindBlock(unsigned int code_offset, bool split, bool create,
6316f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom                        BasicBlock** immed_pred_block_p);
6326f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  void ProcessTryCatchBlocks();
6336f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  BasicBlock* ProcessCanBranch(BasicBlock* cur_block, MIR* insn, int cur_offset, int width,
6346f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom                               int flags, const uint16_t* code_ptr, const uint16_t* code_end);
6356f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  void ProcessCanSwitch(BasicBlock* cur_block, MIR* insn, int cur_offset, int width, int flags);
6366f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  BasicBlock* ProcessCanThrow(BasicBlock* cur_block, MIR* insn, int cur_offset, int width,
6376f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom                              int flags, ArenaBitVector* try_block_addr, const uint16_t* code_ptr,
6386f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom                              const uint16_t* code_end);
6396f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  int AddNewSReg(int v_reg);
6406f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  void HandleSSAUse(int* uses, int dalvik_reg, int reg_index);
6416f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  void HandleSSADef(int* defs, int dalvik_reg, int reg_index);
6426f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  void DataFlowSSAFormat35C(MIR* mir);
6436f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  void DataFlowSSAFormat3RC(MIR* mir);
6446f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  bool FindLocalLiveIn(BasicBlock* bb);
6456f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  void ClearAllVisitedFlags();
6466f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  bool CountUses(struct BasicBlock* bb);
6476f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  bool InferTypeAndSize(BasicBlock* bb);
6486f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  bool VerifyPredInfo(BasicBlock* bb);
6496f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  BasicBlock* NeedsVisit(BasicBlock* bb);
6506f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  BasicBlock* NextUnvisitedSuccessor(BasicBlock* bb);
6516f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  void MarkPreOrder(BasicBlock* bb);
6526f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  void RecordDFSOrders(BasicBlock* bb);
6536f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  void ComputeDFSOrders();
6546f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  void ComputeDefBlockMatrix();
6556f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  void ComputeDomPostOrderTraversal(BasicBlock* bb);
6566f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  void ComputeDominators();
6576f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  void InsertPhiNodes();
6586f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  void DoDFSPreOrderSSARename(BasicBlock* block);
6596f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  void SetConstant(int32_t ssa_reg, int value);
6606f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  void SetConstantWide(int ssa_reg, int64_t value);
6616f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  int GetSSAUseCount(int s_reg);
6626f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  bool BasicBlockOpt(BasicBlock* bb);
6636f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  bool EliminateNullChecks(BasicBlock* bb);
6646f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  void NullCheckEliminationInit(BasicBlock* bb);
6656f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  bool BuildExtendedBBList(struct BasicBlock* bb);
6666f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  bool FillDefBlockMatrix(BasicBlock* bb);
6676f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  void InitializeDominationInfo(BasicBlock* bb);
6686f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  bool ComputeblockIDom(BasicBlock* bb);
6696f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  bool ComputeBlockDominators(BasicBlock* bb);
6706f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  bool SetDominators(BasicBlock* bb);
6716f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  bool ComputeBlockLiveIns(BasicBlock* bb);
6726f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  bool InsertPhiNodeOperands(BasicBlock* bb);
6736f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  bool ComputeDominanceFrontier(BasicBlock* bb);
6746f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  void DoConstantPropogation(BasicBlock* bb);
6756f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  void CountChecks(BasicBlock* bb);
6766f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  bool CombineBlocks(BasicBlock* bb);
677ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee  void AnalyzeBlock(BasicBlock* bb, struct MethodStats* stats);
678ee17e0aa4d24deb11c1766bfcc6a864519df1c1ebuzbee  bool ComputeSkipCompilation(struct MethodStats* stats, bool skip_default);
6796f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom
6806f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  CompilationUnit* const cu_;
6816f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  GrowableArray<int>* ssa_base_vregs_;
6826f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  GrowableArray<int>* ssa_subscripts_;
6836f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  // Map original Dalvik virtual reg i to the current SSA name.
6846f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  int* vreg_to_ssa_map_;            // length == method->registers_size
6856f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  int* ssa_last_defs_;              // length == method->registers_size
6866f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  ArenaBitVector* is_constant_v_;   // length == num_ssa_reg
6876f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  int* constant_values_;            // length == num_ssa_reg
6886f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  // Use counts of ssa names.
6896f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  GrowableArray<uint32_t> use_counts_;      // Weighted by nesting depth
6906f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  GrowableArray<uint32_t> raw_use_counts_;  // Not weighted
6916f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  unsigned int num_reachable_blocks_;
6926f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  GrowableArray<int>* dfs_order_;
6936f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  GrowableArray<int>* dfs_post_order_;
6946f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  GrowableArray<int>* dom_post_order_traversal_;
6956f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  int* i_dom_list_;
6966f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  ArenaBitVector** def_block_matrix_;    // num_dalvik_register x num_blocks.
6976f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  ArenaBitVector* temp_block_v_;
6986f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  ArenaBitVector* temp_dalvik_register_v_;
6996f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  ArenaBitVector* temp_ssa_register_v_;  // num_ssa_regs.
7006f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  static const int kInvalidEntry = -1;
7016f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  GrowableArray<BasicBlock*> block_list_;
7026f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  ArenaBitVector* try_block_addr_;
7036f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  BasicBlock* entry_block_;
7046f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  BasicBlock* exit_block_;
7056f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  BasicBlock* cur_block_;
7066f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  int num_blocks_;
7076f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  const DexFile::CodeItem* current_code_item_;
7087934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom  SafeMap<unsigned int, BasicBlock*> block_map_;  // FindBlock lookup cache.
7096f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  std::vector<DexCompilationUnit*> m_units_;     // List of methods included in this graph
7106f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  typedef std::pair<int, int> MIRLocation;       // Insert point, (m_unit_ index, offset)
7116f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  std::vector<MIRLocation> method_stack_;        // Include stack
7126f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  int current_method_;
7136f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  int current_offset_;
7146f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  int def_count_;                                // Used to estimate size of ssa name storage.
7156f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  int* opcode_count_;                            // Dex opcode coverage stats.
7166f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  int num_ssa_regs_;                             // Number of names following SSA transformation.
7177934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom  std::vector<BasicBlock*> extended_basic_blocks_;  // Heads of block "traces".
7186f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  int method_sreg_;
7196f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  unsigned int attributes_;
7206f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  Checkstats* checkstats_;
721479f83c196d5a95e36196eac548dc6019e70a5bebuzbee  SpecialCaseHandler special_case_;
7226f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom  ArenaAllocator* arena_;
723311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee};
724311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee
725311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee}  // namespace art
726311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee
727fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_COMPILER_DEX_MIR_GRAPH_H_
728