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