10c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/* 20c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * Copyright (C) 2012 The Android Open Source Project 30c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * 40c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * Licensed under the Apache License, Version 2.0 (the "License"); 50c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * you may not use this file except in compliance with the License. 60c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * You may obtain a copy of the License at 70c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * 80c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * http://www.apache.org/licenses/LICENSE-2.0 90c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * 100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * Unless required by applicable law or agreed to in writing, software 110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * distributed under the License is distributed on an "AS IS" BASIS, 120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * See the License for the specific language governing permissions and 140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen * limitations under the License. 150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/*! \file AnalysisO1.cpp 190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen \brief This file implements register allocator, constant folding 200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#include "libdex/DexOpcodes.h" 220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#include "libdex/DexFile.h" 230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#include "Lower.h" 240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#include "interp/InterpState.h" 250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#include "interp/InterpDefs.h" 260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#include "libdex/Leb128.h" 270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/* compilation flags to turn on debug printout */ 290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//#define DEBUG_COMPILE_TABLE 300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//#define DEBUG_ALLOC_CONSTRAINT 310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//#define DEBUG_REGALLOC 320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//#define DEBUG_REG_USED 330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//#define DEBUG_REFCOUNT 340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//#define DEBUG_REACHING_DEF2 350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//#define DEBUG_REACHING_DEF 360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//#define DEBUG_LIVE_RANGE 370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//#define DEBUG_MOVE_OPT 380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//#define DEBUG_SPILL 390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//#define DEBUG_ENDOFBB 400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//#define DEBUG_CONST 410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/* 420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen #define DEBUG_XFER_POINTS 430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen #define DEBUG_DSE 440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen #define DEBUG_CFG 450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen #define DEBUG_GLOBALTYPE 460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen #define DEBUG_STATE 470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen #define DEBUG_COMPILE_TABLE 480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen #define DEBUG_VIRTUAL_INFO 490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen #define DEBUG_MOVE_OPT 500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen #define DEBUG_MERGE_ENTRY 510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen #define DEBUG_INVALIDATE 520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#include "AnalysisO1.h" 540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid dumpCompileTable(); 560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/* There are 3 kinds of variables that are handled in this file: 580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1> virtual register (isVirtualReg()) 590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2> temporary (!isVirtualReg() && regNum < PhysicalReg_GLUE_DVMDEX) 600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 3> glue variables: regNum >= PhysicalReg_GLUE_DVMDEX 610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** check whether a variable is a virtual register 630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool isVirtualReg(int type) { 650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((type & LowOpndRegType_virtual) != 0) return true; 660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool isTemporary(int type, int regNum) { 690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!isVirtualReg(type) && regNum < PhysicalReg_GLUE_DVMDEX) return true; 700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** convert type defined in lowering module to type defined in register allocator 740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen in lowering module <type, isPhysical> 750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen in register allocator: LowOpndRegType_hard LowOpndRegType_virtual LowOpndRegType_scratch 760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint convertType(int type, int reg, bool isPhysical) { 780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int newType = type; 790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isPhysical) newType |= LowOpndRegType_hard; 800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isVirtualReg(type)) newType |= LowOpndRegType_virtual; 810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* reg number for a VR can exceed PhysicalReg_SCRATCH_1 */ 830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(reg >= PhysicalReg_SCRATCH_1 && reg < PhysicalReg_GLUE_DVMDEX) 840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen newType |= LowOpndRegType_scratch; 850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return newType; 870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** return the size of a variable 900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenOpndSize getRegSize(int type) { 920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((type & MASK_FOR_TYPE) == LowOpndRegType_xmm) return OpndSize_64; 930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((type & MASK_FOR_TYPE) == LowOpndRegType_fs) return OpndSize_64; 940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* for type _gp, _fs_s, _ss */ 950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return OpndSize_32; 960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/* 990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Overlapping cases between two variables A and B 1000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen layout for A,B isAPartiallyOverlapB isBPartiallyOverlapA 1010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1> |__| |____| OVERLAP_ALIGN OVERLAP_B_COVER_A 1020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen |__| |____| 1030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2> |____| OVERLAP_B_IS_LOW_OF_A OVERLAP_B_COVER_LOW_OF_A 1040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen |__| 1050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 3> |____| OVERLAP_B_IS_HIGH_OF_A OVERLAP_B_COVER_HIGH_OF_A 1060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen |__| 1070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 4> |____| OVERLAP_LOW_OF_A_IS_HIGH_OF_B OVERLAP_B_COVER_LOW_OF_A 1080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen |____| 1090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 5> |____| OVERLAP_HIGH_OF_A_IS_LOW_OF_B OVERLAP_B_COVER_HIGH_OF_A 1100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen |____| 1110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 6> |__| OVERLAP_A_IS_LOW_OF_B OVERLAP_B_COVER_A 1120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen |____| 1130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 7> |__| OVERLAP_A_IS_HIGH_OF_B OVERLAP_B_COVER_A 1140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen |____| 1150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 1160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** determine the overlapping between variable B and A 1170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 1180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenOverlapCase getBPartiallyOverlapA(int regB, LowOpndRegType tB, int regA, LowOpndRegType tA) { 1190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(getRegSize(tA) == getRegSize(tB) && regA == regB) return OVERLAP_B_COVER_A; 1200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(getRegSize(tA) == OpndSize_64 && getRegSize(tB) == OpndSize_32 && regA == regB) return OVERLAP_B_COVER_LOW_OF_A; 1210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(getRegSize(tA) == OpndSize_64 && getRegSize(tB) == OpndSize_32 && regB == regA + 1) return OVERLAP_B_COVER_HIGH_OF_A; 1220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(getRegSize(tA) == OpndSize_32 && getRegSize(tB) == OpndSize_64 && (regA == regB || regA == regB+1)) return OVERLAP_B_COVER_A; 1230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(getRegSize(tB) == OpndSize_64 && getRegSize(tA) == OpndSize_64 && regA == regB+1) return OVERLAP_B_COVER_LOW_OF_A; 1240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(getRegSize(tB) == OpndSize_64 && getRegSize(tA) == OpndSize_64 && regB == regA+1) return OVERLAP_B_COVER_HIGH_OF_A; 1250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return OVERLAP_NO; 1260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 1270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** determine overlapping between variable A and B 1290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 1300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenOverlapCase getAPartiallyOverlapB(int regA, LowOpndRegType tA, int regB, LowOpndRegType tB) { 1310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(getRegSize(tA) == getRegSize(tB) && regA == regB) return OVERLAP_ALIGN; 1320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(getRegSize(tA) == OpndSize_64 && getRegSize(tB) == OpndSize_32 && regA == regB) 1330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return OVERLAP_B_IS_LOW_OF_A; 1340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(getRegSize(tA) == OpndSize_64 && getRegSize(tB) == OpndSize_32 && regB == regA+1) 1350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return OVERLAP_B_IS_HIGH_OF_A; 1360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(getRegSize(tB) == OpndSize_64 && getRegSize(tA) == OpndSize_64 && regA == regB+1) 1370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return OVERLAP_LOW_OF_A_IS_HIGH_OF_B; 1380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(getRegSize(tB) == OpndSize_64 && getRegSize(tA) == OpndSize_64 && regB == regA+1) 1390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return OVERLAP_HIGH_OF_A_IS_LOW_OF_B; 1400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(getRegSize(tA) == OpndSize_32 && getRegSize(tB) == OpndSize_64 && regA == regB) 1410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return OVERLAP_A_IS_LOW_OF_B; 1420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(getRegSize(tA) == OpndSize_32 && getRegSize(tB) == OpndSize_64 && regA == regB+1) 1430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return OVERLAP_A_IS_HIGH_OF_B; 1440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return OVERLAP_NO; 1450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 1460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** determine whether variable A fully covers B 1480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 1490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool isAFullyCoverB(int regA, LowOpndRegType tA, int regB, LowOpndRegType tB) { 1500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(getRegSize(tB) == OpndSize_32) return true; 1510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(getRegSize(tA) == getRegSize(tB) && regA == regB) return true; 1520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 1530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 1540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/* 1560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen RegAccessType accessType 1570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1> DefOrUse.accessType 1580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen can only be D(VR), L(low part of VR), H(high part of VR), N(none) 1590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for def, it means which part of the VR is live 1600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for use, it means which part of the VR comes from the def 1610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2> VirtualRegInfo.accessType 1620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for currentInfo, it can only be a combination of U & D 1630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for entries in infoBasicBlock, it can be a combination of U & D|L|H 1640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 1650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/* 1670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Key data structures used: 1680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1> BasicBlock_O1 1690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen VirtualRegInfo infoBasicBlock[] 1700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen DefUsePair* defUseTable 1710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen XferPoint xferPoints[] 1720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2> MemoryVRInfo memVRTable[] 1730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LiveRange* ranges 1740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 3> compileTableEntry compileTable[] 1750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 4> VirtualRegInfo 1760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen DefOrUse reachingDefs[3] 1770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 5> DefUsePair, LiveRange 1780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 1790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! one entry for each variable used 1810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! a variable can be virtual register, or a temporary (can be hard-coded) 1830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChencompileTableEntry compileTable[COMPILE_TABLE_SIZE]; 1840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint num_compile_entries; 1850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! tables to save the states of register allocation 1860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenregAllocStateEntry1 stateTable1_1[COMPILE_TABLE_SIZE]; 1870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenregAllocStateEntry1 stateTable1_2[COMPILE_TABLE_SIZE]; 1880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenregAllocStateEntry1 stateTable1_3[COMPILE_TABLE_SIZE]; 1890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenregAllocStateEntry1 stateTable1_4[COMPILE_TABLE_SIZE]; 1900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenregAllocStateEntry2 stateTable2_1[COMPILE_TABLE_SIZE]; 1910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenregAllocStateEntry2 stateTable2_2[COMPILE_TABLE_SIZE]; 1920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenregAllocStateEntry2 stateTable2_3[COMPILE_TABLE_SIZE]; 1930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenregAllocStateEntry2 stateTable2_4[COMPILE_TABLE_SIZE]; 1940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! array of VirtualRegInfo to store VRs accessed by a single bytecode 1960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenVirtualRegInfo infoByteCode[MAX_REG_PER_BYTECODE]; 1970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint num_regs_per_bytecode; 1980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! array of TempRegInfo to store temporaries accessed by a single bytecode 1990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenTempRegInfo infoByteCodeTemp[MAX_TEMP_REG_PER_BYTECODE]; 2000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint num_temp_regs_per_bytecode; 2010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! array of MemoryVRInfo to store whether a VR is in memory 2020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#define NUM_MEM_VR_ENTRY 140 2030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenMemoryVRInfo memVRTable[NUM_MEM_VR_ENTRY]; 2040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint num_memory_vr; 2050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenCompilationUnit* currentUnit = NULL; 2070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! the current basic block 2090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenBasicBlock_O1* currentBB = NULL; 2100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! array of RegisterInfo for all the physical registers 2110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenRegisterInfo allRegs[PhysicalReg_GLUE+1]; //initialized in codeGen 2120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenVirtualRegInfo currentInfo; 2140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenVirtualRegInfo tmpInfo; 2150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! this array says whether a spill location is used (0 means not used, 1 means used) 2170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint spillIndexUsed[MAX_SPILL_JIT_IA]; 2180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint indexForGlue = -1; 2190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint num_bbs_for_method; 2210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! array of basic blocks in a method in program order 2220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenBasicBlock_O1* method_bbs_sorted[MAX_NUM_BBS_PER_METHOD]; 2230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! the entry basic block 2240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenBasicBlock_O1* bb_entry; 2250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint pc_start = -1; 2260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint pc_end = -1; 2270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!array of PCs for exception handlers 2290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint exceptionHandlers[10]; 2300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint num_exception_handlers; 2310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool canSpillReg[PhysicalReg_Null]; //physical registers that should not be spilled 2330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint inGetVR_num = -1; 2340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint inGetVR_type; 2350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/////////////////////////////////////////////////////////////////////////////// 2370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen// FORWARD FUNCTION DECLARATION 2380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid addExceptionHandler(s4 tmp); 2390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint createCFG(Method* method); 2410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint collectInfoOfBasicBlock(Method* method, BasicBlock_O1* bb); 2420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid dumpVirtualInfoOfBasicBlock(BasicBlock_O1* bb); 2430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid setTypeOfVR(); 2440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid insertGlueReg(); 2450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid dumpVirtualInfoOfMethod(); 2460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint codeGenBasicBlock(const Method* method, BasicBlock_O1* bb); 2470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//used in collectInfoOfBasicBlock: getVirtualRegInfo 2490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint mergeEntry2(BasicBlock_O1* bb); 2500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint sortAllocConstraint(RegAllocConstraint* allocConstraints, 2510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen RegAllocConstraint* allocConstraintsSorted, bool fromHighToLow); 2520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//used in codeGenBasicBlock 2540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid insertFromVirtualInfo(BasicBlock_O1* bb, int k); //update compileTable 2550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid insertFromTempInfo(int k); //update compileTable 2560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint updateXferPoints(); 2570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid updateLiveTable(); 2580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid printDefUseTable(); 2590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool isFirstOfHandler(BasicBlock_O1* bb); 2600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//used in mergeEntry2 2620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//following functions will not update global data structure 2630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenRegAccessType mergeAccess2(RegAccessType A, RegAccessType B, OverlapCase isBPartiallyOverlapA); 2640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenRegAccessType updateAccess1(RegAccessType A, OverlapCase isAPartiallyOverlapB); //will not update global data structure 2650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenRegAccessType updateAccess2(RegAccessType C1, RegAccessType C2); 2660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenRegAccessType updateAccess3(RegAccessType C, RegAccessType B); 2670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid updateDefUseTable(); 2690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid updateReachingDefA(int indexToA, OverlapCase isBPartiallyOverlapA); 2700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid updateReachingDefB1(int indexToA); 2710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid updateReachingDefB2(); 2720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid updateReachingDefB3(); 2730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenRegAccessType insertAUse(DefUsePair* ptr, int offsetPC, int regNum, LowOpndRegType physicalType); 2750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenDefUsePair* insertADef(int offsetPC, int regNum, LowOpndRegType pType, RegAccessType rType); 2760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenRegAccessType insertDefUsePair(int reachingDefIndex); 2770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//used in updateXferPoints 2790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint fakeUsageAtEndOfBB(BasicBlock_O1* bb); 2800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid insertLoadXfer(int offset, int regNum, LowOpndRegType pType); 2810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint searchMemTable(int regNum); 2820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid mergeLiveRange(int tableIndex, int rangeStart, int rangeEnd); 2830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//used in updateLiveTable 2840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenRegAccessType setAccessTypeOfUse(OverlapCase isDefPartiallyOverlapUse, RegAccessType reachingDefLive); 2850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenDefUsePair* searchDefUseTable(int offsetPC, int regNum, LowOpndRegType pType); 2860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid insertAccess(int tableIndex, LiveRange* startP, int rangeStart); 2870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//register allocation 2890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint spillLogicalReg(int spill_index, bool updateTable); 2900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** check whether the current bytecode is IF or GOTO or SWITCH 2920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 2930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool isCurrentByteCodeJump() { 2940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u2 inst_op = INST_INST(inst); 2950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(inst_op == OP_IF_EQ || inst_op == OP_IF_NE || inst_op == OP_IF_LT || 2960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen inst_op == OP_IF_GE || inst_op == OP_IF_GT || inst_op == OP_IF_LE) return true; 2970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(inst_op == OP_IF_EQZ || inst_op == OP_IF_NEZ || inst_op == OP_IF_LTZ || 2980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen inst_op == OP_IF_GEZ || inst_op == OP_IF_GTZ || inst_op == OP_IF_LEZ) return true; 2990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(inst_op == OP_GOTO || inst_op == OP_GOTO_16 || inst_op == OP_GOTO_32) return true; 3000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(inst_op == OP_PACKED_SWITCH || inst_op == OP_SPARSE_SWITCH) return true; 3010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 3020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 3030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 3040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/* this function is called before code generation of basic blocks 3050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen initialize data structure allRegs, which stores information for each physical register, 3060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen whether it is used, when it was last freed, whether it is callee-saved */ 3070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid initializeAllRegs() { 3080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 3090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = PhysicalReg_EAX; k <= PhysicalReg_EBP; k++) { 3100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen allRegs[k].physicalReg = (PhysicalReg) k; 3110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(k == PhysicalReg_EDI || k == PhysicalReg_ESP || k == PhysicalReg_EBP) 3120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen allRegs[k].isUsed = true; 3130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 3140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen allRegs[k].isUsed = false; 3150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen allRegs[k].freeTimeStamp = -1; 3160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 3170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(k == PhysicalReg_EBX || k == PhysicalReg_EBP || k == PhysicalReg_ESI || k == PhysicalReg_EDI) 3180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen allRegs[k].isCalleeSaved = true; 3190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 3200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen allRegs[k].isCalleeSaved = false; 3210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 3220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = PhysicalReg_XMM0; k <= PhysicalReg_XMM7; k++) { 3230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen allRegs[k].physicalReg = (PhysicalReg) k; 3240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen allRegs[k].isUsed = false; 3250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen allRegs[k].freeTimeStamp = -1; 3260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen allRegs[k].isCalleeSaved = false; 3270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 3280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 3290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 3300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** sync up allRegs (isUsed & freeTimeStamp) with compileTable 3310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen global data: RegisterInfo allRegs[PhysicalReg_Null] 3320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen update allRegs[EAX to XMM7] except EDI,ESP,EBP 3330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen update RegisterInfo.isUsed & RegisterInfo.freeTimeStamp 3340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if the physical register was used and is not used now 3350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 3360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid syncAllRegs() { 3370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k, k2; 3380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = PhysicalReg_EAX; k <= PhysicalReg_XMM7; k++) { 3390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(k == PhysicalReg_EDI || k == PhysicalReg_ESP || k == PhysicalReg_EBP) 3400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen continue; 3410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //check whether the physical register is used by any logical register 3420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool stillUsed = false; 3430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k2 = 0; k2 < num_compile_entries; k2++) { 3440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k2].physicalReg == k) { 3450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stillUsed = true; 3460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 3470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 3480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 3490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(stillUsed && !allRegs[k].isUsed) { 3500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen allRegs[k].isUsed = true; 3510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 3520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!stillUsed && allRegs[k].isUsed) { 3530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen allRegs[k].isUsed = false; 3540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen allRegs[k].freeTimeStamp = lowOpTimeStamp; 3550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 3560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 3570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 3580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 3590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 3600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!sync up spillIndexUsed with compileTable 3610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 3620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 3630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid updateSpillIndexUsed() { 3640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 3650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k <= MAX_SPILL_JIT_IA-1; k++) spillIndexUsed[k] = 0; 3660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_compile_entries; k++) { 3670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isVirtualReg(compileTable[k].physicalType)) continue; 3680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].spill_loc_index >= 0) { 3690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].spill_loc_index > 4*(MAX_SPILL_JIT_IA-1)) 3700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("spill_loc_index is wrong for entry %d: %d", 3710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen k, compileTable[k].spill_loc_index); 3720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen spillIndexUsed[compileTable[k].spill_loc_index >> 2] = 1; 3730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 3740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 3750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 3760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 3770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/* free memory used in all basic blocks */ 3780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid freeCFG() { 3790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 3800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_bbs_for_method; k++) { 3810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* free defUseTable for method_bbs_sorted[k] */ 3820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen DefUsePair* ptr = method_bbs_sorted[k]->defUseTable; 3830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptr != NULL) { 3840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen DefUsePair* tmp = ptr->next; 3850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* free ptr->uses */ 3860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen DefOrUseLink* ptrUse = ptr->uses; 3870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptrUse != NULL) { 3880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen DefOrUseLink* tmp2 = ptrUse->next; 3890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen free(ptrUse); 3900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrUse = tmp2; 3910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 3920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen free(ptr); 3930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = tmp; 3940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 3950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen free(method_bbs_sorted[k]); 3960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 3970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 3980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 3990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/* update compileTable.physicalReg, compileTable.spill_loc_index & allRegs.isUsed 4000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for glue-related variables, they do not exist 4010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen not in a physical register (physicalReg is Null) 4020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen not in a spilled memory location (spill_loc_index is -1) 4030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 4040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid initializeRegStateOfBB(BasicBlock_O1* bb) { 4050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //for GLUE variables, do not exist 4060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 4070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_compile_entries; k++) { 4080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* trace-based JIT: there is no VR with GG type */ 4090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isVirtualReg(compileTable[k].physicalType) && compileTable[k].gType == GLOBALTYPE_GG) { 4100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(bb->bb_index > 0) { //non-entry block 4110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isFirstOfHandler(bb)) { 4120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* at the beginning of an exception handler, GG VR is in the interpreted stack */ 4130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].physicalReg = PhysicalReg_Null; 4140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_COMPILE_TABLE 4150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("at the first basic block of an exception handler, GG VR %d type %d is in memory", 4160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].regNum, compileTable[k].physicalType); 4170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 4180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 4190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].physicalReg == PhysicalReg_Null) { 4200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* GG VR is in a specific physical register */ 4210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].physicalReg = compileTable[k].physicalReg_prev; 4220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 4230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int tReg = compileTable[k].physicalReg; 4240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen allRegs[tReg].isUsed = true; 4250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REG_USED 4260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("REGALLOC: physical reg %d is used by a GG VR %d %d at beginning of BB", tReg, compileTable[k].regNum, compileTable[k].physicalType); 4270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 4280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 4290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } //non-entry block 4300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } //if GG VR 4310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].regNum != PhysicalReg_GLUE && 4320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].regNum >= PhysicalReg_GLUE_DVMDEX) { 4330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* glue related registers */ 4340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].physicalReg = PhysicalReg_Null; 4350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].spill_loc_index = -1; 4360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 4370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 4380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 4390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 4400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/* update memVRTable[].nullCheckDone */ 4410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid initializeNullCheck(int indexToMemVR) { 4420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool found = false; 4430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef GLOBAL_NULLCHECK_OPT 4440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* search nullCheck_inB of the current Basic Block */ 4450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < nullCheck_inSize[currentBB->bb_index2]; k++) { 4460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(nullCheck_inB[currentBB->bb_index2][k] == memVRTable[indexToMemVR].regNum) { 4470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen found = true; 4480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 4490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 4500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 4510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 4520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[indexToMemVR].nullCheckDone = found; 4530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 4540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 4550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/* initialize memVRTable */ 4560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid initializeMemVRTable() { 4570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_memory_vr = 0; 4580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 4590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_compile_entries; k++) { 4600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!isVirtualReg(compileTable[k].physicalType)) continue; 4610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* VRs in compileTable */ 4620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool setToInMemory = (compileTable[k].physicalReg == PhysicalReg_Null); 4630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regNum = compileTable[k].regNum; 4640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen OpndSize sizeVR = getRegSize(compileTable[k].physicalType); 4650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* search memVRTable for the VR in compileTable */ 4660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int kk; 4670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexL = -1; 4680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexH = -1; 4690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(kk = 0; kk < num_memory_vr; kk++) { 4700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(memVRTable[kk].regNum == regNum) { 4710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen indexL = kk; 4720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen continue; 4730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 4740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(memVRTable[kk].regNum == regNum+1 && sizeVR == OpndSize_64) { 4750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen indexH = kk; 4760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen continue; 4770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 4780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 4790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexL < 0) { 4800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* the low half of VR is not in memVRTable 4810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen add an entry for the low half in memVRTable */ 4820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(num_memory_vr >= NUM_MEM_VR_ENTRY) { 4830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("exceeds size of memVRTable"); 4840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dvmAbort(); 4850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 4860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[num_memory_vr].regNum = regNum; 4870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[num_memory_vr].inMemory = setToInMemory; 4880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen initializeNullCheck(num_memory_vr); //set nullCheckDone 4890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[num_memory_vr].boundCheck.checkDone = false; 4900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[num_memory_vr].num_ranges = 0; 4910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[num_memory_vr].ranges = NULL; 4920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[num_memory_vr].delayFreeFlags = VRDELAY_NONE; 4930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_memory_vr++; 4940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 4950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(sizeVR == OpndSize_64 && indexH < 0) { 4960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* the high half of VR is not in memVRTable 4970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen add an entry for the high half in memVRTable */ 4980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(num_memory_vr >= NUM_MEM_VR_ENTRY) { 4990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("exceeds size of memVRTable"); 5000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dvmAbort(); 5010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 5020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[num_memory_vr].regNum = regNum+1; 5030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[num_memory_vr].inMemory = setToInMemory; 5040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen initializeNullCheck(num_memory_vr); 5050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[num_memory_vr].boundCheck.checkDone = false; 5060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[num_memory_vr].num_ranges = 0; 5070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[num_memory_vr].ranges = NULL; 5080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[num_memory_vr].delayFreeFlags = VRDELAY_NONE; 5090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_memory_vr++; 5100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 5110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 5120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 5130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 5140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/* create a O1 basic block from basic block constructed in JIT MIR */ 5150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenBasicBlock_O1* createBasicBlockO1(BasicBlock* bb) { 5160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen BasicBlock_O1* bb1 = createBasicBlock(0, -1); 5170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb1->jitBasicBlock = bb; 5180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return bb1; 5190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 5200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 5210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/* a basic block in JIT MIR can contain bytecodes that are not in program order 5220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for example, a "goto" bytecode will be followed by the goto target */ 5230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid preprocessingBB(BasicBlock* bb) { 5240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB = createBasicBlockO1(bb); 5250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* initialize currentBB->allocConstraints */ 5260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int ii; 5270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(ii = 0; ii < 8; ii++) { 5280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->allocConstraints[ii].physicalReg = (PhysicalReg)ii; 5290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->allocConstraints[ii].count = 0; 5300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 5310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen collectInfoOfBasicBlock(currentMethod, currentBB); 5320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_COMPILE_TABLE 5330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpVirtualInfoOfBasicBlock(currentBB); 5340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 5350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB = NULL; 5360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 5370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 5380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid preprocessingTrace() { 5390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k, k2, k3, jj; 5400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* this is a simplified verson of setTypeOfVR() 5410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen all VRs are assumed to be GL, no VR will be GG 5420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 5430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_bbs_for_method; k++) 5440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(jj = 0; jj < method_bbs_sorted[k]->num_regs; jj++) 5450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen method_bbs_sorted[k]->infoBasicBlock[jj].gType = GLOBALTYPE_GL; 5460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 5470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* insert a glue-related register GLUE_DVMDEX to compileTable */ 5480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertGlueReg(); 5490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 5500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int compile_entries_old = num_compile_entries; 5510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k2 = 0; k2 < num_bbs_for_method; k2++) { 5520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB = method_bbs_sorted[k2]; 5530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* update compileTable with virtual register from currentBB */ 5540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k3 = 0; k3 < currentBB->num_regs; k3++) { 5550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertFromVirtualInfo(currentBB, k3); 5560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 5570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 5580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* for each GL|GG type VR, insert fake usage at end of basic block to keep it live */ 5590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int offsetPC_back = offsetPC; 5600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen offsetPC = PC_FOR_END_OF_BB; 5610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_compile_entries; k++) { 5620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentInfo.regNum = compileTable[k].regNum; 5630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentInfo.physicalType = (LowOpndRegType)compileTable[k].physicalType; 5640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isVirtualReg(compileTable[k].physicalType) && 5650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].gType == GLOBALTYPE_GL) { 5660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* update defUseTable by assuming a fake usage at END of a basic block for variable @ currentInfo */ 5670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen fakeUsageAtEndOfBB(currentBB); 5680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 5690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isVirtualReg(compileTable[k].physicalType) && 5700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].gType == GLOBALTYPE_GG) { 5710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen fakeUsageAtEndOfBB(currentBB); 5720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 5730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 5740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen offsetPC = offsetPC_back; 5750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_compile_entries = compile_entries_old; 5760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 5770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* initialize data structure allRegs */ 5780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen initializeAllRegs(); 5790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_COMPILE_TABLE 5800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpCompileTable(); 5810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 5820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB = NULL; 5830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 5840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 5850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid printJitTraceInfoAtRunTime(const Method* method, int offset) { 5860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("execute trace for %s%s at offset %x", method->clazz->descriptor, method->name, offset); 5870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 5880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 5890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid startOfTraceO1(const Method* method, LowOpBlockLabel* labelList, int exceptionBlockId, CompilationUnit *cUnit) { 5900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_exception_handlers = 0; 5910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_compile_entries = 0; 5920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB = NULL; 5930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen pc_start = -1; 5940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb_entry = NULL; 5950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_bbs_for_method = 0; 5960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentUnit = cUnit; 5970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen lowOpTimeStamp = 0; 5980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 5990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen// dumpDebuggingInfo is gone in CompilationUnit struct 6000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#if 0 6010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* add code to dump debugging information */ 6020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(cUnit->dumpDebuggingInfo) { 6030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_imm_to_mem(OpndSize_32, cUnit->startOffset, -4, PhysicalReg_ESP, true); //2nd argument: offset 6040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_imm_to_mem(OpndSize_32, (int)currentMethod, -8, PhysicalReg_ESP, true); //1st argument: method 6050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen load_effective_addr(-8, PhysicalReg_ESP, true, PhysicalReg_ESP, true); 6060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 6070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typedef void (*vmHelper)(const Method*, int); 6080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen vmHelper funcPtr = printJitTraceInfoAtRunTime; 6090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_imm_to_reg(OpndSize_32, (int)funcPtr, PhysicalReg_ECX, true); 6100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen call_reg(PhysicalReg_ECX, true); 6110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 6120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen load_effective_addr(8, PhysicalReg_ESP, true, PhysicalReg_ESP, true); 6130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 6140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 6150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 6160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 6170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 6180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/* Code generation for a basic block defined for JIT 6190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen We have two data structures for a basic block: 6200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen BasicBlock defined in vm/compiler by JIT 6210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen BasicBlock_O1 defined in o1 */ 6220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint codeGenBasicBlockJit(const Method* method, BasicBlock* bb) { 6230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* search method_bbs_sorted to find the O1 basic block corresponding to bb */ 6240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 6250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_bbs_for_method; k++) { 6260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(method_bbs_sorted[k]->jitBasicBlock == bb) { 6270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen lowOpTimeStamp = 0; //reset time stamp at start of a basic block 6280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB = method_bbs_sorted[k]; 6290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int cg_ret = codeGenBasicBlock(method, currentBB); 6300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB = NULL; 6310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return cg_ret; 6320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 6330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 6340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("can't find the corresponding O1 basic block for id %d type %d", 6350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->id, bb->blockType); 6360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return -1; 6370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 6380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid endOfBasicBlock(BasicBlock* bb) { 6390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen isScratchPhysical = true; 6400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB = NULL; 6410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 6420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid endOfTraceO1() { 6430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeCFG(); 6440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 6450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 6460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** entry point to collect information about virtual registers used in a basic block 6470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Initialize data structure BasicBlock_O1 6480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen The usage information of virtual registers is stoerd in bb->infoBasicBlock 6490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 6500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Global variables accessed: offsetPC, rPC 6510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 6520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint collectInfoOfBasicBlock(Method* method, BasicBlock_O1* bb) { 6530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->num_regs = 0; 6540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->num_defs = 0; 6550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->defUseTable = NULL; 6560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->defUseTail = NULL; 6570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u2* rPC_start = (u2*)method->insns; 6580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int kk; 6590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->endsWithReturn = false; 6600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->hasAccessToGlue = false; 6610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 6620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MIR* mir; 6630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int seqNum = 0; 6640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* traverse the MIR in basic block 6650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen sequence number is used to make sure next bytecode will have a larger sequence number */ 6660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(mir = bb->jitBasicBlock->firstMIRInsn; mir; mir = mir->next) { 6670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen offsetPC = seqNum; 6680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen mir->seqNum = seqNum++; 6690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen rPC = rPC_start + mir->offset; 6700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef WITH_JIT_INLINING 6710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(mir->dalvikInsn.opcode >= kMirOpFirst && 6720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen mir->dalvikInsn.opcode != kMirOpCheckInlinePrediction) continue; 6730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ir->dalvikInsn.opcode == kMirOpCheckInlinePrediction) { //TODO 6740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 6750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#else 6760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(mir->dalvikInsn.opcode >= kNumPackedOpcodes) continue; 6770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 6780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen inst = FETCH(0); 6790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u2 inst_op = INST_INST(inst); 6800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* update bb->hasAccessToGlue */ 6810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((inst_op >= OP_MOVE_RESULT && inst_op <= OP_RETURN_OBJECT) || 6820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (inst_op >= OP_MONITOR_ENTER && inst_op <= OP_INSTANCE_OF) || 6830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (inst_op == OP_FILLED_NEW_ARRAY) || 6840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (inst_op == OP_FILLED_NEW_ARRAY_RANGE) || 6850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (inst_op == OP_THROW) || 6860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (inst_op >= OP_INVOKE_VIRTUAL && inst_op <= OP_INVOKE_INTERFACE_RANGE) || 6870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (inst_op >= OP_THROW_VERIFICATION_ERROR && 6880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen inst_op <= OP_EXECUTE_INLINE_RANGE) || 6890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (inst_op >= OP_INVOKE_VIRTUAL_QUICK && inst_op <= OP_INVOKE_SUPER_QUICK_RANGE)) 6900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->hasAccessToGlue = true; 6910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* update bb->endsWithReturn */ 6920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(inst_op == OP_RETURN_VOID || inst_op == OP_RETURN || inst_op == OP_RETURN_VOID_BARRIER || 6930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen inst_op == OP_RETURN_OBJECT || inst_op == OP_RETURN_WIDE) 6940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->endsWithReturn = true; 6950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 6960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* get virtual register usage in current bytecode */ 6970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen getVirtualRegInfo(infoByteCode); 6980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int num_regs = num_regs_per_bytecode; 6990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(kk = 0; kk < num_regs; kk++) { 7000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentInfo = infoByteCode[kk]; 7010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_MERGE_ENTRY 7020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("call mergeEntry2 at offsetPC %x kk %d VR %d %d", offsetPC, kk, 7030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentInfo.regNum, currentInfo.physicalType); 7040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 7050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen mergeEntry2(bb); //update defUseTable of the basic block 7060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 7070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 7080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //dumpVirtualInfoOfBasicBlock(bb); 7090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen }//for each bytecode 7100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 7110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->pc_end = seqNum; 7120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 7130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //sort allocConstraints of each basic block 7140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(kk = 0; kk < bb->num_regs; kk++) { 7150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_ALLOC_CONSTRAINT 7160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("sort virtual reg %d type %d -------", bb->infoBasicBlock[kk].regNum, 7170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->infoBasicBlock[kk].physicalType); 7180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 7190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen sortAllocConstraint(bb->infoBasicBlock[kk].allocConstraints, 7200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->infoBasicBlock[kk].allocConstraintsSorted, true); 7210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 7220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_ALLOC_CONSTRAINT 7230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("sort constraints for BB %d --------", bb->bb_index); 7240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 7250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen sortAllocConstraint(bb->allocConstraints, bb->allocConstraintsSorted, false); 7260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 7270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 7280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 7290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** entry point to generate native code for a O1 basic block 7300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen There are 3 kinds of virtual registers in a O1 basic block: 7310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 1> L VR: local within the basic block 7320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 2> GG VR: is live in other basic blocks, 7330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen its content is in a pre-defined GPR at the beginning of a basic block 7340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 3> GL VR: is live in other basic blocks, 7350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen its content is in the interpreted stack at the beginning of a basic block 7360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable is updated with infoBasicBlock at the start of the basic block; 7370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Before lowering each bytecode, compileTable is updated with infoByteCodeTemp; 7380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen At end of the basic block, right before the jump instruction, handles constant VRs and GG VRs 7390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 7400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint codeGenBasicBlock(const Method* method, BasicBlock_O1* bb) { 7410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* we assume at the beginning of each basic block, 7420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen all GL VRs reside in memory and all GG VRs reside in predefined physical registers, 7430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen so at the end of a basic block, recover a spilled GG VR, store a GL VR to memory */ 7440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* update compileTable with entries in bb->infoBasicBlock */ 7450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 7460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < bb->num_regs; k++) { 7470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertFromVirtualInfo(bb, k); 7480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 7490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateXferPoints(); //call fakeUsageAtEndOfBB 7500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REACHING_DEF 7510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen printDefUseTable(); 7520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 7530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DSE_OPT 7540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen removeDeadDefs(); 7550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen printDefUseTable(); 7560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 7570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //clear const section of compileTable 7580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_compile_entries; k++) compileTable[k].isConst = false; 7590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_const_vr = 0; 7600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_COMPILE_TABLE 7610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("At start of basic block %d (num of VRs %d) -------", bb->bb_index, bb->num_regs); 7620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpCompileTable(); 7630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 7640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen initializeRegStateOfBB(bb); 7650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen initializeMemVRTable(); 7660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateLiveTable(); 7670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); //before code gen of a basic block, also called at end of a basic block? 7680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_COMPILE_TABLE 7690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("At start of basic block %d (num of VRs %d) -------", bb->bb_index, bb->num_regs); 7700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 7710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 7720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u2* rPC_start = (u2*)method->insns; 7730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool lastByteCodeIsJump = false; 7740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MIR* mir; 7750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(mir = bb->jitBasicBlock->firstMIRInsn; mir; mir = mir->next) { 7760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen offsetPC = mir->seqNum; 7770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen rPC = rPC_start + mir->offset; 7780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef WITH_JIT_INLINING 7790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(mir->dalvikInsn.opcode >= kMirOpFirst && 7800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen mir->dalvikInsn.opcode != kMirOpCheckInlinePrediction) { 7810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#else 7820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(mir->dalvikInsn.opcode >= kNumPackedOpcodes) { 7830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 7840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen handleExtendedMIR(currentUnit, mir); 7850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen continue; 7860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 7870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 7880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen inst = FETCH(0); 7890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //before handling a bytecode, import info of temporary registers to compileTable including refCount 7900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_temp_regs_per_bytecode = getTempRegInfo(infoByteCodeTemp); 7910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_temp_regs_per_bytecode; k++) { 7920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(infoByteCodeTemp[k].versionNum > 0) continue; 7930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertFromTempInfo(k); 7940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 7950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startNativeCode(-1, -1); 7960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k <= MAX_SPILL_JIT_IA-1; k++) spillIndexUsed[k] = 0; 7970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //update spillIndexUsed if a glue variable was spilled 7980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_compile_entries; k++) { 7990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].regNum >= PhysicalReg_GLUE_DVMDEX) { 8000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].spill_loc_index >= 0) 8010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen spillIndexUsed[compileTable[k].spill_loc_index >> 2] = 1; 8020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 8030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 8040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_COMPILE_TABLE 8050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("compile table size after importing temporary info %d", num_compile_entries); 8060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("before one bytecode %d (num of VRs %d) -------", bb->bb_index, bb->num_regs); 8070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 8080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //set isConst to true for CONST & MOVE MOVE_OBJ? 8090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //clear isConst to true for MOVE, MOVE_OBJ, MOVE_RESULT, MOVE_EXCEPTION ... 8100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool isConst = getConstInfo(bb); //will reset isConst if a VR is updated by the bytecode 8110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool isDeadStmt = false; 8120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DSE_OPT 8130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_dead_pc; k++) { 8140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(deadPCs[k] == offsetPC) { 8150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen isDeadStmt = true; 8160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 8170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 8180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 8190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 8200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen getVirtualRegInfo(infoByteCode); 8210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //call something similar to mergeEntry2, but only update refCount 8220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //clear refCount 8230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_regs_per_bytecode; k++) { 8240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexT = searchCompileTable(LowOpndRegType_virtual | infoByteCode[k].physicalType, 8250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen infoByteCode[k].regNum); 8260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexT >= 0) 8270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[indexT].refCount = 0; 8280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 8290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_regs_per_bytecode; k++) { 8300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexT = searchCompileTable(LowOpndRegType_virtual | infoByteCode[k].physicalType, 8310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen infoByteCode[k].regNum); 8320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexT >= 0) 8330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[indexT].refCount += infoByteCode[k].refCount; 8340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } //for k 8350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DSE_OPT 8360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isDeadStmt) { //search compileTable 8370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen getVirtualRegInfo(infoByteCode); 8380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_DSE 8390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("DSE: stmt at offsetPC %d is dead", offsetPC); 8400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 8410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_regs_per_bytecode; k++) { 8420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexT = searchCompileTable(LowOpndRegType_virtual | infoByteCode[k].physicalType, 8430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen infoByteCode[k].regNum); 8440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexT >= 0) 8450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[indexT].refCount -= infoByteCode[k].refCount; 8460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 8470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 8480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 8490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen lastByteCodeIsJump = false; 8500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!isConst && !isDeadStmt) //isDeadStmt is false when DSE_OPT is not enabled 8510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen { 8520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_COMPILE_TABLE 8530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpCompileTable(); 8540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 8550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen globalShortMap = NULL; 8560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isCurrentByteCodeJump()) lastByteCodeIsJump = true; 8570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //lowerByteCode will call globalVREndOfBB if it is jump 8580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int retCode = lowerByteCodeJit(method, rPC, mir); 8590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(gDvmJit.codeCacheByteUsed + (stream - streamStart) + 8600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen CODE_CACHE_PADDING > gDvmJit.codeCacheSize) { 8610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("JIT code cache full"); 8620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen gDvmJit.codeCacheFull = true; 8630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return -1; 8640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 8650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 8660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if (retCode == 1) { 8670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("JIT couldn't compile %s%s dex_pc=%d", method->clazz->descriptor, method->name, offsetPC); 8680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return -1; 8690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 8700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateConstInfo(bb); 8710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeShortMap(); 8720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(retCode < 0) { 8730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("error in lowering the bytecode"); 8740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return retCode; 8750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 8760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); //may dump GL VR to memory (this is necessary) 8770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //after each bytecode, make sure non-VRs have refCount of zero 8780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_compile_entries; k++) { 8790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isTemporary(compileTable[k].physicalType, compileTable[k].regNum)) { 8800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef PRINT_WARNING 8810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].refCount > 0) { 8820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGW("refCount for a temporary reg %d %d is %d after a bytecode", compileTable[k].regNum, compileTable[k].physicalType, compileTable[k].refCount); 8830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 8840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 8850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].refCount = 0; 8860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 8870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 8880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { //isConst || isDeadStmt 8890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //if this bytecode is the target of a jump, the mapFromBCtoNCG should be updated 8900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen offsetNCG = stream - streamMethodStart; 8910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen mapFromBCtoNCG[offsetPC] = offsetNCG; 8920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_COMPILE_TABLE 8930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("this bytecode generates a constant and has no side effect"); 8940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 8950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); //may dump GL VR to memory (this is necessary) 8960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 8970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_COMPILE_TABLE 8980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("after one bytecode BB %d (num of VRs %d)", bb->bb_index, bb->num_regs); 8990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 9000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen }//for each bytecode 9010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_COMPILE_TABLE 9020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpCompileTable(); 9030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 9040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!lastByteCodeIsJump) constVREndOfBB(); 9050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //at end of a basic block, get spilled GG VR & dump GL VR 9060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!lastByteCodeIsJump) globalVREndOfBB(method); 9070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //remove entries for temporary registers, L VR and GL VR 9080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int jj; 9090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_compile_entries; ) { 9100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool removeEntry = false; 9110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isVirtualReg(compileTable[k].physicalType) && compileTable[k].gType != GLOBALTYPE_GG) { 9120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen removeEntry = true; 9130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 9140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isTemporary(compileTable[k].physicalType, compileTable[k].regNum)) 9150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen removeEntry = true; 9160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(removeEntry) { 9170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef PRINT_WARNING 9180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].refCount > 0) 9190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGW("refCount for REG %d %d is %d at end of a basic block", compileTable[k].regNum, compileTable[k].physicalType, compileTable[k].refCount); 9200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 9210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].refCount = 0; 9220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(jj = k+1; jj < num_compile_entries; jj++) { 9230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[jj-1] = compileTable[jj]; 9240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 9250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_compile_entries--; 9260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 9270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen k++; 9280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 9290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 9300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 9310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //free LIVE TABLE 9320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_memory_vr; k++) { 9330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LiveRange* ptr2 = memVRTable[k].ranges; 9340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptr2 != NULL) { 9350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LiveRange* tmpP = ptr2->next; 9360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen free(ptr2->accessPC); 9370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen free(ptr2); 9380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr2 = tmpP; 9390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 9400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 9410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_COMPILE_TABLE 9420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("At end of basic block -------"); 9430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpCompileTable(); 9440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 9450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 9460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 9470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 9480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** update infoBasicBlock & defUseTable 9490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen input: currentInfo 9500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen side effect: update currentInfo.reachingDefs 9510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 9520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen update entries in infoBasicBlock by calling updateReachingDefA 9530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if there is no entry in infoBasicBlock for B, an entry will be created and inserted to infoBasicBlock 9540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 9550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen defUseTable is updated to account for the access at currentInfo 9560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if accessType of B is U or UD, we call updateReachingDefB to update currentInfo.reachingDefs 9570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen in order to correctly insert the usage to defUseTable 9580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 9590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint mergeEntry2(BasicBlock_O1* bb) { 9600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LowOpndRegType typeB = currentInfo.physicalType; 9610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regB = currentInfo.regNum; 9620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int jj, k; 9630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int jjend = bb->num_regs; 9640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool isMerged = false; 9650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool hasAlias = false; 9660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen OverlapCase isBPartiallyOverlapA, isAPartiallyOverlapB; 9670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen RegAccessType tmpType = REGACCESS_N; 9680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentInfo.num_reaching_defs = 0; 9690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 9700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* traverse variable A in infoBasicBlock */ 9710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(jj = 0; jj < jjend; jj++) { 9720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regA = bb->infoBasicBlock[jj].regNum; 9730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LowOpndRegType typeA = bb->infoBasicBlock[jj].physicalType; 9740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen isBPartiallyOverlapA = getBPartiallyOverlapA(regB, typeB, regA, typeA); 9750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen isAPartiallyOverlapB = getAPartiallyOverlapB(regA, typeA, regB, typeB); 9760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(regA == regB && typeA == typeB) { 9770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* variable A and B are aligned */ 9780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->infoBasicBlock[jj].accessType = mergeAccess2(bb->infoBasicBlock[jj].accessType, currentInfo.accessType, 9790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen OVERLAP_B_COVER_A); 9800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->infoBasicBlock[jj].refCount += currentInfo.refCount; 9810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* copy reaching defs of variable B from variable A */ 9820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentInfo.num_reaching_defs = bb->infoBasicBlock[jj].num_reaching_defs; 9830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < currentInfo.num_reaching_defs; k++) 9840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentInfo.reachingDefs[k] = bb->infoBasicBlock[jj].reachingDefs[k]; 9850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateDefUseTable(); //use currentInfo to update defUseTable 9860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateReachingDefA(jj, OVERLAP_B_COVER_A); //update reachingDefs of A 9870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen isMerged = true; 9880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen hasAlias = true; 9890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(typeB == LowOpndRegType_gp) { 9900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //merge allocConstraints 9910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < 8; k++) { 9920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->infoBasicBlock[jj].allocConstraints[k].count += currentInfo.allocConstraints[k].count; 9930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 9940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 9950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 9960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(isBPartiallyOverlapA != OVERLAP_NO) { 9970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen tmpType = updateAccess2(tmpType, updateAccess1(bb->infoBasicBlock[jj].accessType, isAPartiallyOverlapB)); 9980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->infoBasicBlock[jj].accessType = mergeAccess2(bb->infoBasicBlock[jj].accessType, currentInfo.accessType, 9990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen isBPartiallyOverlapA); 10000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_MERGE_ENTRY 10010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("update accessType in case 2: VR %d %d accessType %d", regA, typeA, bb->infoBasicBlock[jj].accessType); 10020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 10030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen hasAlias = true; 10040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentInfo.accessType == REGACCESS_U || currentInfo.accessType == REGACCESS_UD) { 10050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* update currentInfo.reachingDefs */ 10060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateReachingDefB1(jj); 10070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateReachingDefB2(); 10080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 10090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateReachingDefA(jj, isBPartiallyOverlapA); 10100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 10110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 10120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //even if B does not overlap with A, B can affect the reaching defs of A 10130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //for example, B is a def of "v0", A is "v1" 10140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen // B can kill some reaching defs of A or affect the accessType of a reaching def 10150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateReachingDefA(jj, OVERLAP_NO); //update reachingDefs of A 10160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 10170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen }//for each variable A in infoBasicBlock 10180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!isMerged) { 10190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* create a new entry in infoBasicBlock */ 10200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->infoBasicBlock[bb->num_regs].refCount = currentInfo.refCount; 10210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->infoBasicBlock[bb->num_regs].physicalType = typeB; 10220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(hasAlias) 10230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->infoBasicBlock[bb->num_regs].accessType = updateAccess3(tmpType, currentInfo.accessType); 10240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 10250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->infoBasicBlock[bb->num_regs].accessType = currentInfo.accessType; 10260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_MERGE_ENTRY 10270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("update accessType in case 3: VR %d %d accessType %d", regB, typeB, bb->infoBasicBlock[bb->num_regs].accessType); 10280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 10290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->infoBasicBlock[bb->num_regs].regNum = regB; 10300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < 8; k++) 10310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->infoBasicBlock[bb->num_regs].allocConstraints[k] = currentInfo.allocConstraints[k]; 10320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_MERGE_ENTRY 10330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("isMerged is false, call updateDefUseTable"); 10340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 10350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateDefUseTable(); //use currentInfo to update defUseTable 10360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateReachingDefB3(); //update currentInfo.reachingDefs if currentInfo defines variable B 10370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 10380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //copy from currentInfo.reachingDefs to bb->infoBasicBlock[bb->num_regs] 10390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->infoBasicBlock[bb->num_regs].num_reaching_defs = currentInfo.num_reaching_defs; 10400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < currentInfo.num_reaching_defs; k++) 10410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->infoBasicBlock[bb->num_regs].reachingDefs[k] = currentInfo.reachingDefs[k]; 10420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_MERGE_ENTRY 10430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("try to update reaching defs for VR %d %d", regB, typeB); 10440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < bb->infoBasicBlock[bb->num_regs].num_reaching_defs; k++) 10450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("reaching def %d @ %d for VR %d %d access %d", k, currentInfo.reachingDefs[k].offsetPC, 10460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentInfo.reachingDefs[k].regNum, currentInfo.reachingDefs[k].physicalType, 10470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentInfo.reachingDefs[k].accessType); 10480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 10490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->num_regs++; 10500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(bb->num_regs >= MAX_REG_PER_BASICBLOCK) { 10510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("too many VRs in a basic block"); 10520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dvmAbort(); 10530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 10540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return -1; 10550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 10560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 10570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 10580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 10590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update reaching defs for infoBasicBlock[indexToA] 10600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 10610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!use currentInfo.reachingDefs to update reaching defs for variable A 10620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid updateReachingDefA(int indexToA, OverlapCase isBPartiallyOverlapA) { 10630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexToA < 0) return; 10640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k, k2; 10650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen OverlapCase isBPartiallyOverlapDef; 10660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentInfo.accessType == REGACCESS_U) { 10670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; //no update to reachingDefs of the VR 10680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 10690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* access in currentInfo is DU, D, or UD */ 10700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isBPartiallyOverlapA == OVERLAP_B_COVER_A) { 10710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* from this point on, the reachingDefs for variable A is a single def to currentInfo at offsetPC */ 10720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].num_reaching_defs = 1; 10730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[0].offsetPC = offsetPC; 10740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[0].regNum = currentInfo.regNum; 10750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[0].physicalType = currentInfo.physicalType; 10760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[0].accessType = REGACCESS_D; 10770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REACHING_DEF 10780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("single reaching def @ %d for VR %d %d", offsetPC, currentInfo.regNum, currentInfo.physicalType); 10790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 10800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 10810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 10820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* update reachingDefs for variable A to get rid of dead defs */ 10830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* Bug fix: it is possible that more than one reaching defs need to be removed 10840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen after one reaching def is removed, num_reaching_defs--, but k should not change 10850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 10860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < currentBB->infoBasicBlock[indexToA].num_reaching_defs; ) { 10870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* remove one reaching def in one interation of the loop */ 10880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //check overlapping between def & B 10890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen isBPartiallyOverlapDef = getBPartiallyOverlapA(currentInfo.regNum, currentInfo.physicalType, 10900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[k].regNum, 10910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[k].physicalType); 10920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REACHING_DEF 10930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("DEBUG B %d %d def %d %d %d", currentInfo.regNum, currentInfo.physicalType, 10940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[k].regNum, 10950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[k].physicalType, 10960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[k].accessType); 10970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 10980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* cases where one def nees to be removed: 10990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if B fully covers def, def is removed 11000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if B overlaps high half of def & def's accessType is H, def is removed 11010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if B overlaps low half of def & def's accessType is L, def is removed 11020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 11030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((isBPartiallyOverlapDef == OVERLAP_B_COVER_HIGH_OF_A && 11040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[k].accessType == REGACCESS_H) || 11050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (isBPartiallyOverlapDef == OVERLAP_B_COVER_LOW_OF_A && 11060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[k].accessType == REGACCESS_L) || 11070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen isBPartiallyOverlapDef == OVERLAP_B_COVER_A 11080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ) { //remove def 11090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //shift from k+1 to end 11100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k2 = k+1; k2 < currentBB->infoBasicBlock[indexToA].num_reaching_defs; k2++) 11110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[k2-1] = currentBB->infoBasicBlock[indexToA].reachingDefs[k2]; 11120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].num_reaching_defs--; 11130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 11140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* 11150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if B overlaps high half of def & def's accessType is not H --> update accessType of def 11160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 11170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(isBPartiallyOverlapDef == OVERLAP_B_COVER_HIGH_OF_A && 11180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[k].accessType != REGACCESS_H) { 11190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //low half is still valid 11200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(getRegSize(currentBB->infoBasicBlock[indexToA].reachingDefs[k].physicalType) == OpndSize_32) 11210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[k].accessType = REGACCESS_D; 11220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 11230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[k].accessType = REGACCESS_L; 11240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REACHING_DEF 11250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("DEBUG: set accessType of def to L"); 11260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 11270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen k++; 11280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 11290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* 11300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if B overlaps low half of def & def's accessType is not L --> update accessType of def 11310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 11320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(isBPartiallyOverlapDef == OVERLAP_B_COVER_LOW_OF_A && 11330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[k].accessType != REGACCESS_L) { 11340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //high half of def is still valid 11350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[k].accessType = REGACCESS_H; 11360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REACHING_DEF 11370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("DEBUG: set accessType of def to H"); 11380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 11390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen k++; 11400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 11410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 11420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen k++; 11430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 11440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen }//for k 11450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isBPartiallyOverlapA != OVERLAP_NO) { 11460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //insert the def to variable @ currentInfo 11470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen k = currentBB->infoBasicBlock[indexToA].num_reaching_defs; 11480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(k >= 3) { 11490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("more than 3 reaching defs"); 11500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 11510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[k].offsetPC = offsetPC; 11520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[k].regNum = currentInfo.regNum; 11530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[k].physicalType = currentInfo.physicalType; 11540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[k].accessType = REGACCESS_D; 11550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].num_reaching_defs++; 11560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 11570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REACHING_DEF2 11580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("IN updateReachingDefA for VR %d %d", currentBB->infoBasicBlock[indexToA].regNum, 11590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].physicalType); 11600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < currentBB->infoBasicBlock[indexToA].num_reaching_defs; k++) 11610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("reaching def %d @ %d for VR %d %d access %d", k, 11620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[k].offsetPC, 11630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[k].regNum, 11640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[k].physicalType, 11650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[k].accessType); 11660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 11670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 11680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 11690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** Given a variable B @currentInfo, 11700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updates its reaching defs by checking reaching defs of variable A @currentBB->infoBasicBlock[indexToA] 11710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen The result is stored in tmpInfo.reachingDefs 11720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 11730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid updateReachingDefB1(int indexToA) { 11740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexToA < 0) return; 11750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 11760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen tmpInfo.num_reaching_defs = 0; 11770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < currentBB->infoBasicBlock[indexToA].num_reaching_defs; k++) { 11780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* go through reachingDefs of variable A @currentBB->infoBasicBlock[indexToA] 11790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for each def, check whether it overlaps with variable B @currentInfo 11800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if the def overlaps with variable B, insert it to tmpInfo.reachingDefs 11810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 11820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen OverlapCase isDefPartiallyOverlapB = getAPartiallyOverlapB( 11830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[k].regNum, 11840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].reachingDefs[k].physicalType, 11850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentInfo.regNum, currentInfo.physicalType 11860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ); 11870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool insert1 = false; //whether to insert the def to tmpInfo.reachingDefs 11880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isDefPartiallyOverlapB == OVERLAP_ALIGN || 11890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen isDefPartiallyOverlapB == OVERLAP_A_IS_LOW_OF_B || 11900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen isDefPartiallyOverlapB == OVERLAP_A_IS_HIGH_OF_B) { 11910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* B aligns with def */ 11920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* def is low half of B, def is high half of B 11930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen in these two cases, def is 32 bits */ 11940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insert1 = true; 11950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 11960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen RegAccessType deftype = currentBB->infoBasicBlock[indexToA].reachingDefs[k].accessType; 11970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isDefPartiallyOverlapB == OVERLAP_B_IS_LOW_OF_A || 11980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen isDefPartiallyOverlapB == OVERLAP_LOW_OF_A_IS_HIGH_OF_B) { 11990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* B is the low half of def */ 12000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* the low half of def is the high half of B */ 12010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(deftype != REGACCESS_H) insert1 = true; 12020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 12030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isDefPartiallyOverlapB == OVERLAP_B_IS_HIGH_OF_A || 12040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen isDefPartiallyOverlapB == OVERLAP_HIGH_OF_A_IS_LOW_OF_B) { 12050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* B is the high half of def */ 12060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* the high half of def is the low half of B */ 12070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(deftype != REGACCESS_L) insert1 = true; 12080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 12090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(insert1) { 12100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(tmpInfo.num_reaching_defs >= 3) { 12110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("more than 3 reaching defs for tmpInfo"); 12120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 12130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen tmpInfo.reachingDefs[tmpInfo.num_reaching_defs] = currentBB->infoBasicBlock[indexToA].reachingDefs[k]; 12140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen tmpInfo.num_reaching_defs++; 12150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REACHING_DEF2 12160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("insert from entry %d %d: index %d", currentBB->infoBasicBlock[indexToA].regNum, 12170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[indexToA].physicalType, k); 12180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 12190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 12200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 12210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 12220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 12230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** update currentInfo.reachingDefs by merging currentInfo.reachingDefs with tmpInfo.reachingDefs 12240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 12250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid updateReachingDefB2() { 12260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k, k2; 12270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k2 = 0; k2 < tmpInfo.num_reaching_defs; k2++ ) { 12280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool merged = false; 12290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < currentInfo.num_reaching_defs; k++) { 12300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* check whether it is the same def, if yes, do nothing */ 12310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentInfo.reachingDefs[k].regNum == tmpInfo.reachingDefs[k2].regNum && 12320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentInfo.reachingDefs[k].physicalType == tmpInfo.reachingDefs[k2].physicalType) { 12330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen merged = true; 12340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentInfo.reachingDefs[k].offsetPC != tmpInfo.reachingDefs[k2].offsetPC) { 12350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("defs on the same VR %d %d with different offsetPC %d vs %d", 12360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentInfo.reachingDefs[k].regNum, currentInfo.reachingDefs[k].physicalType, 12370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentInfo.reachingDefs[k].offsetPC, tmpInfo.reachingDefs[k2].offsetPC); 12380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 12390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentInfo.reachingDefs[k].accessType != tmpInfo.reachingDefs[k2].accessType) 12400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("defs on the same VR %d %d with different accessType", 12410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentInfo.reachingDefs[k].regNum, currentInfo.reachingDefs[k].physicalType); 12420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 12430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 12440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 12450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!merged) { 12460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentInfo.num_reaching_defs >= 3) { 12470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("more than 3 reaching defs for currentInfo"); 12480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 12490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentInfo.reachingDefs[currentInfo.num_reaching_defs] = tmpInfo.reachingDefs[k2]; 12500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentInfo.num_reaching_defs++; 12510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 12520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 12530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 12540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 12550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update currentInfo.reachingDefs with currentInfo if variable is defined in currentInfo 12560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 12570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 12580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid updateReachingDefB3() { 12590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentInfo.accessType == REGACCESS_U) { 12600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; //no need to update currentInfo.reachingDefs 12610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 12620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentInfo.num_reaching_defs = 1; 12630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentInfo.reachingDefs[0].regNum = currentInfo.regNum; 12640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentInfo.reachingDefs[0].physicalType = currentInfo.physicalType; 12650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentInfo.reachingDefs[0].offsetPC = offsetPC; 12660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentInfo.reachingDefs[0].accessType = REGACCESS_D; 12670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 12680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 12690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** update defUseTable by checking currentInfo 12700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 12710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid updateDefUseTable() { 12720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* no access */ 12730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentInfo.accessType == REGACCESS_N) return; 12740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* define then use, or define only */ 12750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentInfo.accessType == REGACCESS_DU || currentInfo.accessType == REGACCESS_D) { 12760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* insert a definition at offsetPC to variable @ currentInfo */ 12770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen DefUsePair* ptr = insertADef(offsetPC, currentInfo.regNum, currentInfo.physicalType, REGACCESS_D); 12780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentInfo.accessType != REGACCESS_D) { 12790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* if access is define then use, insert a use at offsetPC */ 12800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertAUse(ptr, offsetPC, currentInfo.regNum, currentInfo.physicalType); 12810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 12820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 12830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 12840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* use only or use then define 12850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen check the reaching defs for the usage */ 12860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 12870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool isLCovered = false, isHCovered = false, isDCovered = false; 12880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < currentInfo.num_reaching_defs; k++) { 12890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* insert a def currentInfo.reachingDefs[k] and a use of variable at offsetPC */ 12900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen RegAccessType useType = insertDefUsePair(k); 12910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(useType == REGACCESS_D) isDCovered = true; 12920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(useType == REGACCESS_L) isLCovered = true; 12930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(useType == REGACCESS_H) isHCovered = true; 12940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 12950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen OpndSize useSize = getRegSize(currentInfo.physicalType); 12960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!isDCovered) && (!isLCovered)) { 12970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* the low half of variable is not defined in the basic block 12980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen so insert a def to the low half at START of the basic block */ 12990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertDefUsePair(-1); 13000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 13010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(useSize == OpndSize_64 && (!isDCovered) && (!isHCovered)) { 13020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* the high half of variable is not defined in the basic block 13030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen so insert a def to the high half at START of the basic block */ 13040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertDefUsePair(-2); 13050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 13060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentInfo.accessType == REGACCESS_UD) { 13070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* insert a def at offsetPC to variable @ currentInfo */ 13080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertADef(offsetPC, currentInfo.regNum, currentInfo.physicalType, REGACCESS_D); 13090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 13100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 13110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 13120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 13130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! insert a use at offsetPC of given variable at end of DefUsePair 13140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 13150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 13160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenRegAccessType insertAUse(DefUsePair* ptr, int offsetPC, int regNum, LowOpndRegType physicalType) { 13170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen DefOrUseLink* tLink = (DefOrUseLink*)malloc(sizeof(DefOrUseLink)); 13180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(tLink == NULL) { 13190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("Memory allocation failed"); 13200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return REGACCESS_UNKNOWN; 13210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 13220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen tLink->offsetPC = offsetPC; 13230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen tLink->regNum = regNum; 13240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen tLink->physicalType = physicalType; 13250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen tLink->next = NULL; 13260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptr->useTail != NULL) 13270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->useTail->next = tLink; 13280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->useTail = tLink; 13290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptr->uses == NULL) 13300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->uses = tLink; 13310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->num_uses++; 13320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 13330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //check whether the def is partially overlapping with the variable 13340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen OverlapCase isDefPartiallyOverlapB = getBPartiallyOverlapA(ptr->def.regNum, 13350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->def.physicalType, 13360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen regNum, physicalType); 13370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen RegAccessType useType = setAccessTypeOfUse(isDefPartiallyOverlapB, ptr->def.accessType); 13380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen tLink->accessType = useType; 13390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return useType; 13400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 13410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 13420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! insert a def to currentBB->defUseTable 13430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 13440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! update currentBB->defUseTail if necessary 13450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenDefUsePair* insertADef(int offsetPC, int regNum, LowOpndRegType pType, RegAccessType rType) { 13460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen DefUsePair* ptr = (DefUsePair*)malloc(sizeof(DefUsePair)); 13470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptr == NULL) { 13480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("Memory allocation failed"); 13490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 13500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 13510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->next = NULL; 13520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->def.offsetPC = offsetPC; 13530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->def.regNum = regNum; 13540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->def.physicalType = pType; 13550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->def.accessType = rType; 13560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->num_uses = 0; 13570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->useTail = NULL; 13580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->uses = NULL; 13590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB->defUseTail != NULL) { 13600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->defUseTail->next = ptr; 13610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 13620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->defUseTail = ptr; 13630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB->defUseTable == NULL) 13640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->defUseTable = ptr; 13650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->num_defs++; 13660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REACHING_DEF 13670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("insert a def at %d to defUseTable for VR %d %d", offsetPC, 13680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen regNum, pType); 13690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 13700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return ptr; 13710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 13720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 13730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** insert a def to defUseTable, then insert a use of variable @ currentInfo 13740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if reachingDefIndex >= 0, the def is currentInfo.reachingDefs[index] 13750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if reachingDefIndex is -1, the low half is defined at START of the basic block 13760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if reachingDefIndex is -2, the high half is defined at START of the basic block 13770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 13780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenRegAccessType insertDefUsePair(int reachingDefIndex) { 13790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k = reachingDefIndex; 13800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen DefUsePair* tableIndex = NULL; 13810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen DefOrUse theDef; 13820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen theDef.regNum = 0; 13830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(k < 0) { 13840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* def at start of the basic blcok */ 13850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen theDef.offsetPC = PC_FOR_START_OF_BB; 13860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen theDef.accessType = REGACCESS_D; 13870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(k == -1) //low half of variable 13880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen theDef.regNum = currentInfo.regNum; 13890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(k == -2) //high half of variable 13900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen theDef.regNum = currentInfo.regNum+1; 13910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen theDef.physicalType = LowOpndRegType_gp; 13920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 13930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 13940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen theDef = currentInfo.reachingDefs[k]; 13950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 13960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen tableIndex = searchDefUseTable(theDef.offsetPC, theDef.regNum, theDef.physicalType); 13970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(tableIndex == NULL) //insert an entry 13980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen tableIndex = insertADef(theDef.offsetPC, theDef.regNum, theDef.physicalType, theDef.accessType); 13990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 14000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen tableIndex->def.accessType = theDef.accessType; 14010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen RegAccessType useType = insertAUse(tableIndex, offsetPC, currentInfo.regNum, currentInfo.physicalType); 14020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return useType; 14030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 14040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 14050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! insert a XFER_MEM_TO_XMM to currentBB->xferPoints 14060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 14070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 14080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid insertLoadXfer(int offset, int regNum, LowOpndRegType pType) { 14090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //check whether it is already in currentBB->xferPoints 14100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 14110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < currentBB->num_xfer_points; k++) { 14120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB->xferPoints[k].xtype == XFER_MEM_TO_XMM && 14130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[k].offsetPC == offset && 14140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[k].regNum == regNum && 14150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[k].physicalType == pType) 14160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 14170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 14180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[currentBB->num_xfer_points].xtype = XFER_MEM_TO_XMM; 14190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[currentBB->num_xfer_points].regNum = regNum; 14200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[currentBB->num_xfer_points].offsetPC = offset; 14210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[currentBB->num_xfer_points].physicalType = pType; 14220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_XFER_POINTS 14230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("insert to xferPoints %d: XFER_MEM_TO_XMM of VR %d %d at %d", currentBB->num_xfer_points, regNum, pType, offset); 14240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 14250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->num_xfer_points++; 14260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB->num_xfer_points >= MAX_XFER_PER_BB) { 14270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("too many xfer points"); 14280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dvmAbort(); 14290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 14300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 14310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 14320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** update defUseTable by assuming a fake usage at END of a basic block for variable @ currentInfo 14330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen create a fake usage at end of a basic block for variable B (currentInfo.physicalType, currentInfo.regNum) 14340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get reaching def info for variable B and store the info in currentInfo.reachingDefs 14350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for each virtual register (variable A) accessed in the basic block 14360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen update reaching defs of B by checking reaching defs of variable A 14370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen update defUseTable 14380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 14390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint fakeUsageAtEndOfBB(BasicBlock_O1* bb) { 14400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentInfo.accessType = REGACCESS_U; 14410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LowOpndRegType typeB = currentInfo.physicalType; 14420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regB = currentInfo.regNum; 14430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int jj, k; 14440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentInfo.num_reaching_defs = 0; 14450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(jj = 0; jj < bb->num_regs; jj++) { 14460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regA = bb->infoBasicBlock[jj].regNum; 14470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LowOpndRegType typeA = bb->infoBasicBlock[jj].physicalType; 14480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen OverlapCase isBPartiallyOverlapA = getBPartiallyOverlapA(regB, typeB, regA, typeA); 14490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(regA == regB && typeA == typeB) { 14500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* copy reachingDefs from variable A */ 14510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentInfo.num_reaching_defs = bb->infoBasicBlock[jj].num_reaching_defs; 14520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < currentInfo.num_reaching_defs; k++) 14530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentInfo.reachingDefs[k] = bb->infoBasicBlock[jj].reachingDefs[k]; 14540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 14550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 14560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(isBPartiallyOverlapA != OVERLAP_NO) { 14570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* B overlaps with A */ 14580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* update reaching defs of variable B by checking reaching defs of bb->infoBasicBlock[jj] */ 14590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateReachingDefB1(jj); 14600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateReachingDefB2(); //merge currentInfo with tmpInfo 14610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 14620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 14630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* update defUseTable by checking currentInfo */ 14640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateDefUseTable(); 14650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 14660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 14670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 14680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** update xferPoints of currentBB 14690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Traverse currentBB->defUseTable 14700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 14710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint updateXferPoints() { 14720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k = 0; 14730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->num_xfer_points = 0; 14740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen DefUsePair* ptr = currentBB->defUseTable; 14750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen DefOrUseLink* ptrUse = NULL; 14760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* traverse the def use chain of the basic block */ 14770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptr != NULL) { 14780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LowOpndRegType defType = ptr->def.physicalType; 14790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //if definition is for a variable of 32 bits 14800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(getRegSize(defType) == OpndSize_32) { 14810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* check usages of the definition, whether it reaches a GPR, a XMM, a FS, or a SS */ 14820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool hasGpUsage = false; 14830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool hasGpUsage2 = false; //not a fake usage 14840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool hasXmmUsage = false; 14850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool hasFSUsage = false; 14860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool hasSSUsage = false; 14870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrUse = ptr->uses; 14880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptrUse != NULL) { 14890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptrUse->physicalType == LowOpndRegType_gp) { 14900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen hasGpUsage = true; 14910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptrUse->offsetPC != PC_FOR_END_OF_BB) 14920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen hasGpUsage2 = true; 14930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 14940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptrUse->physicalType == LowOpndRegType_ss) hasSSUsage = true; 14950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptrUse->physicalType == LowOpndRegType_fs || 14960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrUse->physicalType == LowOpndRegType_fs_s) 14970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen hasFSUsage = true; 14980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptrUse->physicalType == LowOpndRegType_xmm) { 14990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen hasXmmUsage = true; 15000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 15010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptrUse->physicalType == LowOpndRegType_xmm || 15020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrUse->physicalType == LowOpndRegType_ss) { 15030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* if a 32-bit definition reaches a xmm usage or a SS usage, 15040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insert a XFER_MEM_TO_XMM */ 15050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertLoadXfer(ptrUse->offsetPC, 15060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrUse->regNum, LowOpndRegType_xmm); 15070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 15080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrUse = ptrUse->next; 15090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 15100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(((hasXmmUsage || hasFSUsage || hasSSUsage) && defType == LowOpndRegType_gp) || 15110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (hasGpUsage && defType == LowOpndRegType_fs) || 15120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (defType == LowOpndRegType_ss && (hasGpUsage || hasXmmUsage || hasFSUsage))) { 15130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* insert a transfer if def is on a GPR, usage is on a XMM, FS or SS 15140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if def is on a FS, usage is on a GPR 15150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if def is on a SS, usage is on a GPR, XMM or FS 15160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen transfer type is XFER_DEF_TO_GP_MEM if a real GPR usage exisits 15170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen transfer type is XFER_DEF_TO_GP otherwise*/ 15180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[currentBB->num_xfer_points].offsetPC = ptr->def.offsetPC; 15190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[currentBB->num_xfer_points].regNum = ptr->def.regNum; 15200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[currentBB->num_xfer_points].physicalType = ptr->def.physicalType; 15210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(hasGpUsage2) { //create an entry XFER_DEF_TO_GP_MEM 15220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[currentBB->num_xfer_points].xtype = XFER_DEF_TO_GP_MEM; 15230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 15240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { //create an entry XFER_DEF_TO_MEM 15250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[currentBB->num_xfer_points].xtype = XFER_DEF_TO_MEM; 15260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 15270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[currentBB->num_xfer_points].tableIndex = k; 15280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_XFER_POINTS 15290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("insert XFER %d at def %d: V%d %d", currentBB->num_xfer_points, ptr->def.offsetPC, ptr->def.regNum, defType); 15300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 15310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->num_xfer_points++; 15320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB->num_xfer_points >= MAX_XFER_PER_BB) { 15330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("too many xfer points"); 15340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dvmAbort(); 15350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 15360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 15370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 15380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { /* def is on 64 bits */ 15390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool hasGpUsageOfL = false; //exist a GPR usage of the low half 15400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool hasGpUsageOfH = false; //exist a GPR usage of the high half 15410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool hasGpUsageOfL2 = false; 15420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool hasGpUsageOfH2 = false; 15430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool hasMisaligned = false; 15440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool hasAligned = false; 15450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool hasFSUsage = false; 15460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool hasSSUsage = false; 15470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrUse = ptr->uses; 15480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptrUse != NULL) { 15490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptrUse->physicalType == LowOpndRegType_gp && 15500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrUse->regNum == ptr->def.regNum) { 15510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen hasGpUsageOfL = true; 15520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptrUse->offsetPC != PC_FOR_END_OF_BB) 15530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen hasGpUsageOfL2 = true; 15540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 15550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptrUse->physicalType == LowOpndRegType_gp && 15560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrUse->regNum == ptr->def.regNum + 1) { 15570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen hasGpUsageOfH = true; 15580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptrUse->offsetPC != PC_FOR_END_OF_BB) 15590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen hasGpUsageOfH2 = true; 15600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 15610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptrUse->physicalType == LowOpndRegType_xmm && 15620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrUse->regNum == ptr->def.regNum) { 15630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen hasAligned = true; 15640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* if def is on FS and use is on XMM, insert a XFER_MEM_TO_XMM */ 15650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(defType == LowOpndRegType_fs) 15660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertLoadXfer(ptrUse->offsetPC, 15670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrUse->regNum, LowOpndRegType_xmm); 15680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 15690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptrUse->physicalType == LowOpndRegType_fs || 15700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrUse->physicalType == LowOpndRegType_fs_s) 15710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen hasFSUsage = true; 15720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptrUse->physicalType == LowOpndRegType_xmm && 15730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrUse->regNum != ptr->def.regNum) { 15740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen hasMisaligned = true; 15750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* if use is on XMM and use and def are misaligned, insert a XFER_MEM_TO_XMM */ 15760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertLoadXfer(ptrUse->offsetPC, 15770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrUse->regNum, LowOpndRegType_xmm); 15780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 15790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptrUse->physicalType == LowOpndRegType_ss) { 15800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen hasSSUsage = true; 15810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* if use is on SS, insert a XFER_MEM_TO_XMM */ 15820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertLoadXfer(ptrUse->offsetPC, 15830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrUse->regNum, LowOpndRegType_ss); 15840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 15850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrUse = ptrUse->next; 15860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 15870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(defType == LowOpndRegType_fs && !hasGpUsageOfL && !hasGpUsageOfH) { 15880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptr->next; 15890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen continue; 15900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 15910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(defType == LowOpndRegType_xmm && !hasFSUsage && 15920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen !hasGpUsageOfL && !hasGpUsageOfH && !hasMisaligned && !hasSSUsage) { 15930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptr->next; 15940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen continue; 15950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 15960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* insert a XFER_DEF_IS_XMM */ 15970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[currentBB->num_xfer_points].regNum = ptr->def.regNum; 15980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[currentBB->num_xfer_points].offsetPC = ptr->def.offsetPC; 15990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[currentBB->num_xfer_points].physicalType = ptr->def.physicalType; 16000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[currentBB->num_xfer_points].xtype = XFER_DEF_IS_XMM; 16010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[currentBB->num_xfer_points].vr_gpl = -1; 16020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[currentBB->num_xfer_points].vr_gph = -1; 16030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(hasGpUsageOfL2) currentBB->xferPoints[currentBB->num_xfer_points].vr_gpl = ptr->def.regNum; 16040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(hasGpUsageOfH2) currentBB->xferPoints[currentBB->num_xfer_points].vr_gph = ptr->def.regNum+1; 16050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[currentBB->num_xfer_points].dumpToMem = true; 16060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[currentBB->num_xfer_points].dumpToXmm = false; //not used in updateVirtualReg 16070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(hasAligned) currentBB->xferPoints[currentBB->num_xfer_points].dumpToXmm = true; 16080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[currentBB->num_xfer_points].tableIndex = k; 16090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_XFER_POINTS 16100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("insert XFER %d at def %d: V%d %d", currentBB->num_xfer_points, ptr->def.offsetPC, ptr->def.regNum, defType); 16110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 16120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->num_xfer_points++; 16130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB->num_xfer_points >= MAX_XFER_PER_BB) { 16140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("too many xfer points"); 16150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dvmAbort(); 16160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 16170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 16180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptr->next; 16190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } //while ptr 16200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_XFER_POINTS 16210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("XFER points for current basic block ------"); 16220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < currentBB->num_xfer_points; k++) { 16230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI(" at offset %x, VR %d %d: type %d, vr_gpl %d, vr_gph %d, dumpToMem %d, dumpToXmm %d", 16240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[k].offsetPC, currentBB->xferPoints[k].regNum, 16250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[k].physicalType, currentBB->xferPoints[k].xtype, 16260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[k].vr_gpl, currentBB->xferPoints[k].vr_gph, 16270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[k].dumpToMem, currentBB->xferPoints[k].dumpToXmm); 16280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 16290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 16300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return -1; 16310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 16320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 16330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! update memVRTable[].ranges by browsing the defUseTable 16340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 16350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! each virtual register has a list of live ranges, and each live range has a list of PCs that access the VR 16360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid updateLiveTable() { 16370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen DefUsePair* ptr = currentBB->defUseTable; 16380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptr != NULL) { 16390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool updateUse = false; 16400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptr->num_uses == 0) { 16410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->num_uses = 1; 16420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->uses = (DefOrUseLink*)malloc(sizeof(DefOrUseLink)); 16430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptr->uses == NULL) { 16440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("Memory allocation failed"); 16450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 16460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 16470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->uses->accessType = REGACCESS_D; 16480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->uses->regNum = ptr->def.regNum; 16490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->uses->offsetPC = ptr->def.offsetPC; 16500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->uses->physicalType = ptr->def.physicalType; 16510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->uses->next = NULL; 16520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->useTail = ptr->uses; 16530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateUse = true; 16540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 16550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen DefOrUseLink* ptrUse = ptr->uses; 16560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptrUse != NULL) { 16570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen RegAccessType useType = ptrUse->accessType; 16580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(useType == REGACCESS_L || useType == REGACCESS_D) { 16590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexL = searchMemTable(ptrUse->regNum); 16600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexL >= 0) 16610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen mergeLiveRange(indexL, ptr->def.offsetPC, 16620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrUse->offsetPC); //tableIndex, start PC, end PC 16630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 16640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(getRegSize(ptrUse->physicalType) == OpndSize_64 && 16650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (useType == REGACCESS_H || useType == REGACCESS_D)) { 16660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexH = searchMemTable(ptrUse->regNum+1); 16670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexH >= 0) 16680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen mergeLiveRange(indexH, ptr->def.offsetPC, 16690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrUse->offsetPC); 16700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 16710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrUse = ptrUse->next; 16720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen }//while ptrUse 16730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(updateUse) { 16740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->num_uses = 0; 16750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen free(ptr->uses); 16760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->uses = NULL; 16770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->useTail = NULL; 16780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 16790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptr->next; 16800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen }//while ptr 16810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_LIVE_RANGE 16820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("LIVE TABLE"); 16830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(int k = 0; k < num_memory_vr; k++) { 16840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("VR %d live ", memVRTable[k].regNum); 16850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LiveRange* ptr = memVRTable[k].ranges; 16860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptr != NULL) { 16870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("[%x %x] (", ptr->start, ptr->end); 16880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(int k3 = 0; k3 < ptr->num_access; k3++) 16890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("%x ", ptr->accessPC[k3]); 16900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI(") "); 16910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptr->next; 16920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 16930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI(""); 16940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 16950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 16960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 16970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 16980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!add a live range [rangeStart, rangeEnd] to ranges of memVRTable, merge to existing live ranges if necessary 16990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 17000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!ranges are in increasing order of startPC 17010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid mergeLiveRange(int tableIndex, int rangeStart, int rangeEnd) { 17020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(rangeStart == PC_FOR_START_OF_BB) rangeStart = currentBB->pc_start; 17030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(rangeEnd == PC_FOR_END_OF_BB) rangeEnd = currentBB->pc_end; 17040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_LIVE_RANGE 17050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("LIVERANGE call mergeLiveRange on tableIndex %d with [%x %x]", tableIndex, rangeStart, rangeEnd); 17060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 17070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int startIndex = -1, endIndex = -1; 17080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool startBeforeRange = false, endBeforeRange = false; //before the index or in the range 17090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool startDone = false, endDone = false; 17100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LiveRange* ptr = memVRTable[tableIndex].ranges; 17110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LiveRange* ptrStart = NULL; 17120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LiveRange* ptrStart_prev = NULL; 17130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LiveRange* ptrEnd = NULL; 17140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LiveRange* ptrEnd_prev = NULL; 17150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k = 0; 17160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptr != NULL) { 17170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!startDone) { 17180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptr->start <= rangeStart && 17190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->end >= rangeStart) { 17200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startIndex = k; 17210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrStart = ptr; 17220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startBeforeRange = false; 17230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startDone = true; 17240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 17250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(ptr->start > rangeStart) { 17260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startIndex = k; 17270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrStart = ptr; 17280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startBeforeRange = true; 17290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startDone = true; 17300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 17310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 17320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!startDone) ptrStart_prev = ptr; 17330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!endDone) { 17340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptr->start <= rangeEnd && 17350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->end >= rangeEnd) { 17360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endIndex = k; 17370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrEnd = ptr; 17380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endBeforeRange = false; 17390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endDone = true; 17400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 17410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(ptr->start > rangeEnd) { 17420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endIndex = k; 17430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrEnd = ptr; 17440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endBeforeRange = true; 17450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endDone = true; 17460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 17470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 17480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!endDone) ptrEnd_prev = ptr; 17490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptr->next; 17500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen k++; 17510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } //while 17520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!startDone) { //both can be NULL 17530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startIndex = memVRTable[tableIndex].num_ranges; 17540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrStart = NULL; //ptrStart_prev should be the last live range 17550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startBeforeRange = true; 17560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 17570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //if endDone, ptrEnd is not NULL, ptrEnd_prev can be NULL 17580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!endDone) { //both can be NULL 17590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endIndex = memVRTable[tableIndex].num_ranges; 17600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrEnd = NULL; 17610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endBeforeRange = true; 17620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 17630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(startIndex == endIndex && startBeforeRange && endBeforeRange) { //insert at startIndex 17640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //3 cases depending on BeforeRange when startIndex == endIndex 17650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //insert only if both true 17660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //merge otherwise 17670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /////////// insert before ptrStart 17680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LiveRange* currRange = (LiveRange *)malloc(sizeof(LiveRange)); 17690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptrStart_prev == NULL) { 17700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currRange->next = memVRTable[tableIndex].ranges; 17710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[tableIndex].ranges = currRange; 17720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 17730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currRange->next = ptrStart_prev->next; 17740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrStart_prev->next = currRange; 17750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 17760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currRange->start = rangeStart; 17770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currRange->end = rangeEnd; 17780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currRange->accessPC = (int *)malloc(sizeof(int) * NUM_ACCESS_IN_LIVERANGE); 17790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currRange->num_alloc = NUM_ACCESS_IN_LIVERANGE; 17800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(rangeStart != rangeEnd) { 17810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currRange->num_access = 2; 17820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currRange->accessPC[0] = rangeStart; 17830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currRange->accessPC[1] = rangeEnd; 17840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 17850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currRange->num_access = 1; 17860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currRange->accessPC[0] = rangeStart; 17870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 17880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[tableIndex].num_ranges++; 17890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_LIVE_RANGE 17900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("LIVERANGE insert one live range [%x %x] to tableIndex %d", rangeStart, rangeEnd, tableIndex); 17910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 17920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 17930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 17940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!endBeforeRange) { //here ptrEnd is not NULL 17950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen endIndex++; //next 17960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrEnd_prev = ptrEnd; //ptrEnd_prev is not NULL 17970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrEnd = ptrEnd->next; //ptrEnd can be NULL 17980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 17990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(endIndex < startIndex+1) ALOGE("mergeLiveRange endIndex %d startIndex %d", endIndex, startIndex); 18000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ///////// use ptrStart & ptrEnd_prev 18010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptrStart == NULL || ptrEnd_prev == NULL) { 18020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("mergeLiveRange ptr is NULL"); 18030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 18040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 18050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //endIndex > startIndex (merge the ranges between startIndex and endIndex-1) 18060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //update ptrStart 18070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptrStart->start > rangeStart) 18080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrStart->start = rangeStart; //min of old start & rangeStart 18090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrStart->end = ptrEnd_prev->end; //max of old end & rangeEnd 18100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(rangeEnd > ptrStart->end) 18110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrStart->end = rangeEnd; 18120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_LIVE_RANGE 18130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("LIVERANGE merge entries for tableIndex %d from %d to %d", tableIndex, startIndex+1, endIndex-1); 18140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 18150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptrStart->num_access <= 0) ALOGE("mergeLiveRange number of access"); 18160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_LIVE_RANGE 18170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("LIVERANGE tableIndex %d startIndex %d num_access %d (", tableIndex, startIndex, ptrStart->num_access); 18180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < ptrStart->num_access; k++) 18190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("%x ", ptrStart->accessPC[k]); 18200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI(")"); 18210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 18220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ///// go through pointers from ptrStart->next to ptrEnd 18230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //from startIndex+1 to endIndex-1 18240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptrStart->next; 18250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptr != NULL && ptr != ptrEnd) { 18260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k2; 18270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k2 = 0; k2 < ptr->num_access; k2++) { //merge to startIndex 18280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertAccess(tableIndex, ptrStart, ptr->accessPC[k2]); 18290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen }//k2 18300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptr->next; 18310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 18320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertAccess(tableIndex, ptrStart, rangeStart); 18330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertAccess(tableIndex, ptrStart, rangeEnd); 18340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //remove startIndex+1 to endIndex-1 18350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(startIndex+1 < endIndex) { 18360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptrStart->next; 18370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptr != NULL && ptr != ptrEnd) { 18380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LiveRange* tmpP = ptr->next; 18390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen free(ptr->accessPC); 18400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen free(ptr); 18410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = tmpP; 18420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 18430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrStart->next = ptrEnd; 18440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 18450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[tableIndex].num_ranges -= (endIndex - startIndex - 1); 18460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_LIVE_RANGE 18470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("num_ranges for VR %d: %d", memVRTable[tableIndex].regNum, memVRTable[tableIndex].num_ranges); 18480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 18490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 18500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! insert an access to a given live range, in order 18510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 18520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 18530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid insertAccess(int tableIndex, LiveRange* startP, int rangeStart) { 18540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k3, k4; 18550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_LIVE_RANGE 18560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("LIVERANGE insertAccess %d %x", tableIndex, rangeStart); 18570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 18580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int insertIndex = -1; 18590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k3 = 0; k3 < startP->num_access; k3++) { 18600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(startP->accessPC[k3] == rangeStart) { 18610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 18620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 18630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(startP->accessPC[k3] > rangeStart) { 18640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertIndex = k3; 18650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 18660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 18670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 18680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 18690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //insert here 18700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen k3 = insertIndex; 18710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(insertIndex == -1) { 18720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen k3 = startP->num_access; 18730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 18740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(startP->num_access == startP->num_alloc) { 18750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int currentAlloc = startP->num_alloc; 18760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startP->num_alloc += NUM_ACCESS_IN_LIVERANGE; 18770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int* tmpPtr = (int *)malloc(sizeof(int) * startP->num_alloc); 18780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k4 = 0; k4 < currentAlloc; k4++) 18790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen tmpPtr[k4] = startP->accessPC[k4]; 18800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen free(startP->accessPC); 18810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startP->accessPC = tmpPtr; 18820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 18830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //insert accessPC 18840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k4 = startP->num_access-1; k4 >= k3; k4--) 18850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startP->accessPC[k4+1] = startP->accessPC[k4]; 18860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startP->accessPC[k3] = rangeStart; 18870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_LIVE_RANGE 18880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("LIVERANGE insert %x to tableIndex %d", rangeStart, tableIndex); 18890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 18900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen startP->num_access++; 18910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 18920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 18930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 18940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen///////////////////////////////////////////////////////////////////// 18950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool isInMemory(int regNum, OpndSize size); 18960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid setVRToMemory(int regNum, OpndSize size); 18970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool isVRLive(int vA); 18980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint getSpillIndex(bool isGLUE, OpndSize size); 18990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid clearVRToMemory(int regNum, OpndSize size); 19000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid clearVRNullCheck(int regNum, OpndSize size); 19010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 19020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Cheninline int getSpillLocDisp(int offset) { 19030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef SPILL_IN_THREAD 19040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return offset+offsetof(Thread, spillRegion);; 19050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#else 19060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return offset+offEBP_spill; 19070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 19080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 19090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#if 0 19100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/* used if we keep self pointer in a physical register */ 19110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Cheninline int getSpillLocReg(int offset) { 19120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return PhysicalReg_Glue; 19130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 19140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 19150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef SPILL_IN_THREAD 19160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Cheninline void loadFromSpillRegion_with_self(OpndSize size, int reg_self, bool selfPhysical, int reg, int offset) { 19170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* only 1 instruction is generated by move_mem_to_reg_noalloc */ 19180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg_noalloc(size, 19190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen getSpillLocDisp(offset), reg_self, selfPhysical, 19200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_SPILL, offset, 19210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg, true); 19220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 19230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Cheninline void loadFromSpillRegion(OpndSize size, int reg, int offset) { 19240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_self_pointer(C_SCRATCH_1, isScratchPhysical); 19250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg_self = registerAlloc(LowOpndRegType_scratch, C_SCRATCH_1, isScratchPhysical, false); 19260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* only 1 instruction is generated by move_mem_to_reg_noalloc */ 19270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg_noalloc(size, 19280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen getSpillLocDisp(offset), reg_self, true, 19290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_SPILL, offset, 19300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg, true); 19310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 19320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Cheninline void saveToSpillRegion_with_self(OpndSize size, int selfReg, bool selfPhysical, int reg, int offset) { 19330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem_noalloc(size, 19340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg, true, 19350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen getSpillLocDisp(offset), selfReg, selfPhysical, 19360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_SPILL, offset); 19370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 19380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Cheninline void saveToSpillRegion(OpndSize size, int reg, int offset) { 19390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_self_pointer(C_SCRATCH_1, isScratchPhysical); 19400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int reg_self = registerAlloc(LowOpndRegType_scratch, C_SCRATCH_1, isScratchPhysical, false); 19410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem_noalloc(size, 19420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg, true, 19430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen getSpillLocDisp(offset), reg_self, true, 19440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_SPILL, offset); 19450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 19460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#else 19470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Cheninline void loadFromSpillRegion(OpndSize size, int reg, int offset) { 19480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* only 1 instruction is generated by move_mem_to_reg_noalloc */ 19490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg_noalloc(size, 19500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen getSpillLocDisp(offset), PhysicalReg_EBP, true, 19510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_SPILL, offset, 19520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg, true); 19530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 19540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Cheninline void saveToSpillRegion(OpndSize size, int reg, int offset) { 19550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem_noalloc(size, 19560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg, true, 19570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen getSpillLocDisp(offset), PhysicalReg_EBP, true, 19580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_SPILL, offset); 19590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 19600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 19610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 19620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! dump an immediate to memory, set inMemory to true 19630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 19640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 19650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid dumpImmToMem(int vrNum, OpndSize size, int value) { 19660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isInMemory(vrNum, size)) { 19670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_SPILL 19680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("Skip dumpImmToMem vA %d size %d", vrNum, size); 19690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 19700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 19710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 19720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen set_VR_to_imm_noalloc(vrNum, size, value); 19730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen setVRToMemory(vrNum, size); 19740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 19750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! dump content of a VR to memory, set inMemory to true 19760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 19770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 19780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid dumpToMem(int vrNum, LowOpndRegType type, int regAll) { //ss,gp,xmm 19790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isInMemory(vrNum, getRegSize(type))) { 19800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_SPILL 19810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("Skip dumpToMem vA %d type %d", vrNum, type); 19820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 19830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 19840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 19850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(type == LowOpndRegType_gp || type == LowOpndRegType_xmm) 19860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen set_virtual_reg_noalloc(vrNum, getRegSize(type), regAll, true); 19870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(type == LowOpndRegType_ss) 19880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_ss_reg_to_mem_noalloc(regAll, true, 19890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 4*vrNum, PhysicalReg_FP, true, 19900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, vrNum); 19910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen setVRToMemory(vrNum, getRegSize(type)); 19920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 19930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! dump part of a 64-bit VR to memory and update inMemory 19940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 19950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! isLow tells whether low half or high half is dumped 19960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid dumpPartToMem(int reg /*xmm physical reg*/, int vA, bool isLow) { 19970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isLow) { 19980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isInMemory(vA, OpndSize_32)) { 19990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_SPILL 20000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("Skip dumpPartToMem isLow %d vA %d", isLow, vA); 20010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 20020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 20030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 20040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 20050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 20060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isInMemory(vA+1, OpndSize_32)) { 20070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_SPILL 20080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("Skip dumpPartToMem isLow %d vA %d", isLow, vA); 20090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 20100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 20110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 20120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 20130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isLow) { 20140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!isVRLive(vA)) return; 20150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 20160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 20170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!isVRLive(vA+1)) return; 20180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 20190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //move part to vA or vA+1 20200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isLow) { 20210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_ss_reg_to_mem_noalloc(reg, true, 20220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 4*vA, PhysicalReg_FP, true, MemoryAccess_VR, vA); 20230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 20240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k = getSpillIndex(false, OpndSize_64); 20250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //H, L in 4*k+4 & 4*k 20260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef SPILL_IN_THREAD 20270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_self_pointer(PhysicalReg_SCRATCH_1, isScratchPhysical); 20280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen saveToSpillRegion_with_self(OpndSize_64, PhysicalReg_SCRATCH_1, isScratchPhysical, reg, 4*k); 20290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //update low 32 bits of xmm reg from 4*k+4 20300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_ss_mem_to_reg(NULL, 20310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen getSpillLocDisp(4*k+4), PhysicalReg_SCRATCH_1, isScratchPhysical, 20320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg, true); 20330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#else 20340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen saveToSpillRegion(OpndSize_64, reg, 4*k); 20350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //update low 32 bits of xmm reg from 4*k+4 20360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_ss_mem_to_reg_noalloc( 20370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen getSpillLocDisp(4*k+4), PhysicalReg_EBP, true, 20380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_SPILL, 4*k+4, 20390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg, true); 20400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 20410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //move low 32 bits of xmm reg to vA+1 20420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_ss_reg_to_mem_noalloc(reg, true, 4*(vA+1), PhysicalReg_FP, true, MemoryAccess_VR, vA+1); 20430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 20440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isLow) 20450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen setVRToMemory(vA, OpndSize_32); 20460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 20470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen setVRToMemory(vA+1, OpndSize_32); 20480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 20490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid clearVRBoundCheck(int regNum, OpndSize size); 20500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! the content of a VR is no longer in memory or in physical register if the latest content of a VR is constant 20510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 20520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! clear nullCheckDone; if another VR is overlapped with the given VR, the content of that VR is no longer in physical register 20530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid invalidateVRDueToConst(int reg, OpndSize size) { 20540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen clearVRToMemory(reg, size); //memory content is out-dated 20550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen clearVRNullCheck(reg, size); 20560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen clearVRBoundCheck(reg, size); 20570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //check reg,gp reg,ss reg,xmm reg-1,xmm 20580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //if size is 64: check reg+1,gp|ss reg+1,xmm 20590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index; 20600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //if VR is xmm, check whether we need to dump part of VR to memory 20610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_xmm, reg); 20620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) { 20630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_INVALIDATE 20640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("INVALIDATE virtual reg %d type %d", reg, LowOpndRegType_xmm); 20650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 20660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_32) 20670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpPartToMem(compileTable[index].physicalReg, reg, false); //dump high of xmm to memory 20680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].physicalReg = PhysicalReg_Null; 20690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 20700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_xmm, reg-1); 20710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) { 20720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_INVALIDATE 20730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("INVALIDATE virtual reg %d type %d", reg-1, LowOpndRegType_xmm); 20740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 20750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpPartToMem(compileTable[index].physicalReg, reg-1, true); //dump low of xmm to memory 20760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].physicalReg = PhysicalReg_Null; 20770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 20780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_gp, reg); 20790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) { 20800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_INVALIDATE 20810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("INVALIDATE virtual reg %d type %d", reg, LowOpndRegType_gp); 20820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 20830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].physicalReg = PhysicalReg_Null; 20840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 20850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_ss, reg); 20860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) { 20870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_INVALIDATE 20880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("INVALIDATE virtual reg %d type %d", reg, LowOpndRegType_ss); 20890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 20900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].physicalReg = PhysicalReg_Null; 20910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 20920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64) { 20930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_xmm, reg+1); 20940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) { 20950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_INVALIDATE 20960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("INVALIDATE virtual reg %d type %d", reg+1, LowOpndRegType_xmm); 20970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 20980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpPartToMem(compileTable[index].physicalReg, reg+1, false); //dump high of xmm to memory 20990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].physicalReg = PhysicalReg_Null; 21000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 21010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_gp, reg+1); 21020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) { 21030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_INVALIDATE 21040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("INVALIDATE virtual reg %d type %d", reg+1, LowOpndRegType_gp); 21050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 21060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].physicalReg = PhysicalReg_Null; 21070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 21080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_ss, reg+1); 21090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) { 21100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_INVALIDATE 21110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("INVALIDATE virtual reg %d type %d", reg+1, LowOpndRegType_ss); 21120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 21130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].physicalReg = PhysicalReg_Null; 21140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 21150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 21160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 21170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! check which physical registers hold out-dated content if there is a def 21180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 21190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! if another VR is overlapped with the given VR, the content of that VR is no longer in physical register 21200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! should we update inMemory? 21210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid invalidateVR(int reg, LowOpndRegType pType) { 21220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //def at fs: content of xmm & gp & ss are out-dated (reg-1,xmm reg,xmm reg+1,xmm) (reg,gp|ss reg+1,gp|ss) 21230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //def at xmm: content of misaligned xmm & gp are out-dated (reg-1,xmm reg+1,xmm) (reg,gp|ss reg+1,gp|ss) 21240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //def at fs_s: content of xmm & gp are out-dated (reg-1,xmm reg,xmm) (reg,gp|ss) 21250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //def at gp: content of xmm is out-dated (reg-1,xmm reg,xmm) (reg,ss) 21260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //def at ss: content of xmm & gp are out-dated (reg-1,xmm reg,xmm) (reg,gp) 21270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index; 21280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(pType != LowOpndRegType_xmm) { //check xmm @reg 21290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_xmm, reg); 21300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) { 21310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_INVALIDATE 21320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("INVALIDATE virtual reg %d type %d", reg, LowOpndRegType_xmm); 21330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 21340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(getRegSize(pType) == OpndSize_32) 21350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpPartToMem(compileTable[index].physicalReg, reg, false); //dump high of xmm to memory 21360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].physicalReg = PhysicalReg_Null; 21370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 21380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 21390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //check misaligned xmm @ reg-1 21400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_xmm, reg-1); 21410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) { 21420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_INVALIDATE 21430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("INVALIDATE virtual reg %d type %d", reg-1, LowOpndRegType_xmm); 21440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 21450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpPartToMem(compileTable[index].physicalReg, reg-1, true); //dump low of xmm to memory 21460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].physicalReg = PhysicalReg_Null; 21470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 21480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //check misaligned xmm @ reg+1 21490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(pType == LowOpndRegType_xmm || pType == LowOpndRegType_fs) { 21500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //check reg+1,xmm 21510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_xmm, reg+1); 21520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) { 21530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_INVALIDATE 21540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("INVALIDATE virtual reg %d type %d", reg+1, LowOpndRegType_xmm); 21550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 21560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpPartToMem(compileTable[index].physicalReg, reg+1, false); //dump high of xmm to memory 21570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].physicalReg = PhysicalReg_Null; 21580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 21590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 21600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(pType != LowOpndRegType_gp) { 21610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //check reg,gp 21620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_gp, reg); 21630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) { 21640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_INVALIDATE 21650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("INVALIDATE virtual reg %d type %d", reg, LowOpndRegType_gp); 21660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 21670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].physicalReg = PhysicalReg_Null; 21680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 21690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 21700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(pType == LowOpndRegType_xmm || pType == LowOpndRegType_fs) { 21710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //check reg+1,gp 21720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_gp, reg+1); 21730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) { 21740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_INVALIDATE 21750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("INVALIDATE virtual reg %d type %d", reg+1, LowOpndRegType_gp); 21760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 21770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].physicalReg = PhysicalReg_Null; 21780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 21790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 21800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(pType != LowOpndRegType_ss) { 21810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //check reg,ss 21820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_ss, reg); 21830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) { 21840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_INVALIDATE 21850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("INVALIDATE virtual reg %d type %d", reg, LowOpndRegType_ss); 21860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 21870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].physicalReg = PhysicalReg_Null; 21880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 21890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 21900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(pType == LowOpndRegType_xmm || pType == LowOpndRegType_fs) { 21910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //check reg+1,ss 21920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_ss, reg+1); 21930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) { 21940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_INVALIDATE 21950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("INVALIDATE virtual reg %d type %d", reg+1, LowOpndRegType_ss); 21960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 21970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].physicalReg = PhysicalReg_Null; 21980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 21990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 22000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 22010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! bookkeeping when a VR is updated 22020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 22030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! invalidate contents of some physical registers, clear nullCheckDone, and update inMemory; 22040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! check whether there exist tranfer points for this bytecode, if yes, perform the transfer 22050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint updateVirtualReg(int reg, LowOpndRegType pType) { 22060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 22070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen OpndSize size = getRegSize(pType); 22080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //WAS only invalidate xmm VRs for the following cases: 22090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //if def reaches a use of vA,xmm and (the def is not xmm or is misaligned xmm) 22100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen // invalidate "vA,xmm" 22110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen invalidateVR(reg, pType); 22120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen clearVRNullCheck(reg, size); 22130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen clearVRBoundCheck(reg, size); 22140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(pType == LowOpndRegType_fs || pType == LowOpndRegType_fs_s) 22150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen setVRToMemory(reg, size); 22160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 22170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen clearVRToMemory(reg, size); 22180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 22190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < currentBB->num_xfer_points; k++) { 22200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB->xferPoints[k].offsetPC == offsetPC && 22210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[k].regNum == reg && 22220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[k].physicalType == pType && 22230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[k].xtype != XFER_MEM_TO_XMM) { 22240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //perform the corresponding action for the def 22250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen PhysicalReg regAll; 22260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB->xferPoints[k].xtype == XFER_DEF_IS_XMM) { 22270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //def at fs: content of xmm is out-dated 22280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //def at xmm: content of misaligned xmm is out-dated 22290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //invalidateXmmVR(currentBB->xferPoints[k].tableIndex); 22300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_XFER_POINTS 22310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB->xferPoints[k].dumpToXmm) ALOGI("XFER set_virtual_reg to xmm: xmm VR %d", reg); 22320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 22330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(pType == LowOpndRegType_xmm) { 22340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_XFER_POINTS 22350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("XFER set_virtual_reg to memory: xmm VR %d", reg); 22360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 22370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen PhysicalReg regAll = (PhysicalReg)checkVirtualReg(reg, LowOpndRegType_xmm, 0 /* do not update*/); 22380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpToMem(reg, LowOpndRegType_xmm, regAll); 22390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 22400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB->xferPoints[k].vr_gpl >= 0) { // 22410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 22420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB->xferPoints[k].vr_gph >= 0) { 22430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 22440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 22450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((pType == LowOpndRegType_gp || pType == LowOpndRegType_ss) && 22460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (currentBB->xferPoints[k].xtype == XFER_DEF_TO_MEM || 22470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[k].xtype == XFER_DEF_TO_GP_MEM)) { 22480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //the defined gp VR already in register 22490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //invalidateXmmVR(currentBB->xferPoints[k].tableIndex); 22500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen regAll = (PhysicalReg)checkVirtualReg(reg, pType, 0 /* do not update*/); 22510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpToMem(reg, pType, regAll); 22520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_XFER_POINTS 22530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("XFER set_virtual_reg to memory: gp VR %d", reg); 22540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 22550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 22560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((pType == LowOpndRegType_fs_s || pType == LowOpndRegType_ss) && 22570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[k].xtype == XFER_DEF_TO_GP_MEM) { 22580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 22590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 22600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 22610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return -1; 22620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 22630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//////////////////////////////////////////////////////////////// 22640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//REGISTER ALLOCATION 22650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint spillForHardReg(int regNum, int type); 22660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid decreaseRefCount(int index); 22670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint getFreeReg(int type, int reg, int indexToCompileTable); 22680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenPhysicalReg spillForLogicalReg(int type, int reg, int indexToCompileTable); 22690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint unspillLogicalReg(int spill_index, int physicalReg); 22700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint searchVirtualInfoOfBB(LowOpndRegType type, int regNum, BasicBlock_O1* bb); 22710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool isTemp8Bit(int type, int reg); 22720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool matchType(int typeA, int typeB); 22730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint getNextAccess(int compileIndex); 22740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid dumpCompileTable(); 22750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 22760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! allocate a register for a variable 22770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 22780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!if no physical register is free, call spillForLogicalReg to free up a physical register; 22790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!if the variable is a temporary and it was spilled, call unspillLogicalReg to load from spill location to the allocated physical register; 22800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!if updateRefCount is true, reduce reference count of the variable by 1 22810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint registerAlloc(int type, int reg, bool isPhysical, bool updateRefCount) { 22820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REGALLOC 22830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("%p: try to allocate register %d type %d isPhysical %d", currentBB, reg, type, isPhysical); 22840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 22850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB == NULL) { 22860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(type & LowOpndRegType_virtual) return PhysicalReg_Null; 22870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isPhysical) return reg; //for helper functions 22880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return PhysicalReg_Null; 22890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 22900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //ignore EDI, ESP, EBP (glue) 22910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isPhysical && (reg == PhysicalReg_EDI || reg == PhysicalReg_ESP || 22920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg == PhysicalReg_EBP || reg == PhysicalReg_Null)) 22930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return reg; 22940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 22950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int newType = convertType(type, reg, isPhysical); 22960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(newType & LowOpndRegType_scratch) reg = reg - PhysicalReg_SCRATCH_1 + 1; 22970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int tIndex = searchCompileTable(newType, reg); 22980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(tIndex < 0) { 22990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("reg %d type %d not found in registerAlloc", reg, newType); 23000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return PhysicalReg_Null; 23010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 23020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 23030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //physical register 23040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isPhysical) { 23050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(allRegs[reg].isUsed) { //if used by a non hard-coded register 23060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen spillForHardReg(reg, newType); 23070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 23080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen allRegs[reg].isUsed = true; 23090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REG_USED 23100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("REGALLOC: allocate a reg %d", reg); 23110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 23120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[tIndex].physicalReg = reg; 23130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(updateRefCount) 23140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen decreaseRefCount(tIndex); 23150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REGALLOC 23160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("REGALLOC: allocate register %d for logical register %d %d", 23170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[tIndex].physicalReg, reg, newType); 23180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 23190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return reg; 23200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 23210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //already allocated 23220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[tIndex].physicalReg != PhysicalReg_Null) { 23230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REGALLOC 23240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("already allocated to physical register %d", compileTable[tIndex].physicalReg); 23250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 23260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(updateRefCount) 23270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen decreaseRefCount(tIndex); 23280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return compileTable[tIndex].physicalReg; 23290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 23300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 23310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //at this point, the logical register is not hard-coded and is mapped to Reg_Null 23320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //first check whether there is a free reg 23330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //if not, call spillForLogicalReg 23340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index = getFreeReg(newType, reg, tIndex); 23350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index >= 0 && index < PhysicalReg_Null) { 23360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //update compileTable & allRegs 23370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[tIndex].physicalReg = allRegs[index].physicalReg; 23380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen allRegs[index].isUsed = true; 23390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REG_USED 23400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("REGALLOC: register %d is free", allRegs[index].physicalReg); 23410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 23420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 23430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen PhysicalReg allocR = spillForLogicalReg(newType, reg, tIndex); 23440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[tIndex].physicalReg = allocR; 23450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 23460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[tIndex].spill_loc_index >= 0) { 23470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen unspillLogicalReg(tIndex, compileTable[tIndex].physicalReg); 23480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 23490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(updateRefCount) 23500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen decreaseRefCount(tIndex); 23510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REGALLOC 23520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("REGALLOC: allocate register %d for logical register %d %d", 23530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[tIndex].physicalReg, reg, newType); 23540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 23550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return compileTable[tIndex].physicalReg; 23560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 23570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!a variable will use a physical register allocated for another variable 23580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 23590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!This is used when MOVE_OPT is on, it tries to alias a virtual register with a temporary to remove a move 23600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint registerAllocMove(int reg, int type, bool isPhysical, int srcReg) { 23610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(srcReg == PhysicalReg_EDI || srcReg == PhysicalReg_ESP || srcReg == PhysicalReg_EBP) 23620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("can't move from srcReg EDI or ESP or EBP"); 23630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REGALLOC 23640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("in registerAllocMove: reg %d type %d srcReg %d", reg, type, srcReg); 23650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 23660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int newType = convertType(type, reg, isPhysical); 23670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(newType & LowOpndRegType_scratch) reg = reg - PhysicalReg_SCRATCH_1 + 1; 23680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index = searchCompileTable(newType, reg); 23690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) { 23700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("reg %d type %d not found in registerAllocMove", reg, newType); 23710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return -1; 23720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 23730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 23740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen decreaseRefCount(index); 23750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].physicalReg = srcReg; 23760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REGALLOC 23770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("REGALLOC: registerAllocMove %d for logical register %d %d", 23780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].physicalReg, reg, newType); 23790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 23800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return srcReg; 23810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 23820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 23830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! check whether a physical register is available to be used by a variable 23840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 23850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! data structures accessed: 23860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 1> currentBB->infoBasicBlock[index].allocConstraintsSorted 23870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! sorted from high count to low count 23880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 2> currentBB->allocConstraintsSorted 23890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! sorted from low count to high count 23900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 3> allRegs: whether a physical register is available, indexed by PhysicalReg 23910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! NOTE: if a temporary variable is 8-bit, only %eax, %ebx, %ecx, %edx can be used 23920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint getFreeReg(int type, int reg, int indexToCompileTable) { 23930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen syncAllRegs(); 23940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* handles requests for xmm or ss registers */ 23950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 23960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(((type & MASK_FOR_TYPE) == LowOpndRegType_xmm) || 23970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ((type & MASK_FOR_TYPE) == LowOpndRegType_ss)) { 23980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = PhysicalReg_XMM0; k <= PhysicalReg_XMM7; k++) { 23990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!allRegs[k].isUsed) return k; 24000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 24010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return -1; 24020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 24030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REGALLOC 24040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("USED registers: "); 24050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < 8; k++) 24060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("%d used: %d time freed: %d callee-saveld: %d", k, allRegs[k].isUsed, 24070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen allRegs[k].freeTimeStamp, allRegs[k].isCalleeSaved); 24080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI(""); 24090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 24100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 24110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* a VR is requesting a physical register */ 24120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isVirtualReg(type)) { //find a callee-saved register 24130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* if VR is type GG, check the pre-allocated physical register first */ 24140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool isGGVR = compileTable[indexToCompileTable].gType == GLOBALTYPE_GG; 24150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isGGVR) { 24160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regCandidateT = compileTable[indexToCompileTable].physicalReg_prev; 24170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!allRegs[regCandidateT].isUsed) return regCandidateT; 24180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 24190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 24200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index = searchVirtualInfoOfBB((LowOpndRegType)(type&MASK_FOR_TYPE), reg, currentBB); 24210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) { 24220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("VR %d %d not found in infoBasicBlock of currentBB %d (num of VRs %d)", 24230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg, type, currentBB->bb_index, currentBB->num_regs); 24240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dvmAbort(); 24250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 24260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 24270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* check allocConstraints for this VR, 24280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return an available physical register with the highest constraint > 0 */ 24290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < 8; k++) { 24300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB->infoBasicBlock[index].allocConstraintsSorted[k].count == 0) break; 24310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regCandidateT = currentBB->infoBasicBlock[index].allocConstraintsSorted[k].physicalReg; 24320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen assert(regCandidateT < PhysicalReg_Null); 24330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!allRegs[regCandidateT].isUsed) return regCandidateT; 24340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 24350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 24360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* WAS: return an available physical register with the lowest constraint 24370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen NOW: consider a new factor (freeTime) when there is a tie 24380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if 2 available physical registers have the same number of constraints 24390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen choose the one with smaller free time stamp */ 24400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int currentCount = -1; 24410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index1 = -1; 24420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int smallestTime = -1; 24430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < 8; k++) { 24440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regCandidateT = currentBB->allocConstraintsSorted[k].physicalReg; 24450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen assert(regCandidateT < PhysicalReg_Null); 24460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index1 >= 0 && currentBB->allocConstraintsSorted[k].count > currentCount) 24470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; //candidate has higher count than index1 24480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!allRegs[regCandidateT].isUsed) { 24490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index1 < 0) { 24500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index1 = k; 24510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentCount = currentBB->allocConstraintsSorted[k].count; 24520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen smallestTime = allRegs[regCandidateT].freeTimeStamp; 24530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else if(allRegs[regCandidateT].freeTimeStamp < smallestTime) { 24540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index1 = k; 24550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen smallestTime = allRegs[regCandidateT].freeTimeStamp; 24560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 24570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 24580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 24590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index1 >= 0) return currentBB->allocConstraintsSorted[index1].physicalReg; 24600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return -1; 24610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 24620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* handle request from a temporary variable or a glue variable */ 24630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 24640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool is8Bit = isTemp8Bit(type, reg); 24650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 24660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* if the temporary variable is linked to a VR and 24670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen the VR is not yet allocated to any physical register */ 24680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int vr_num = compileTable[indexToCompileTable].linkageToVR; 24690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(vr_num >= 0) { 24700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index3 = searchCompileTable(LowOpndRegType_gp | LowOpndRegType_virtual, vr_num); 24710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index3 < 0) { 24720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("2 in tracing linkage to VR %d", vr_num); 24730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dvmAbort(); 24740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 24750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 24760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[index3].physicalReg == PhysicalReg_Null) { 24770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index2 = searchVirtualInfoOfBB(LowOpndRegType_gp, vr_num, currentBB); 24780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index2 < 0) { 24790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("1 in tracing linkage to VR %d", vr_num); 24800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dvmAbort(); 24810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 24820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REGALLOC 24830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("in getFreeReg for temporary reg %d, trace the linkage to VR %d", 24840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg, vr_num); 24850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 24860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 24870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* check allocConstraints on the VR 24880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return an available physical register with the highest constraint > 0 24890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 24900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < 8; k++) { 24910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB->infoBasicBlock[index2].allocConstraintsSorted[k].count == 0) break; 24920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regCandidateT = currentBB->infoBasicBlock[index2].allocConstraintsSorted[k].physicalReg; 24930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REGALLOC 24940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("check register %d with count %d", regCandidateT, 24950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->infoBasicBlock[index2].allocConstraintsSorted[k].count); 24960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 24970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* if the requesting variable is 8 bit */ 24980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(is8Bit && regCandidateT > PhysicalReg_EDX) continue; 24990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen assert(regCandidateT < PhysicalReg_Null); 25000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!allRegs[regCandidateT].isUsed) return regCandidateT; 25010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 25020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 25030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 25040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* check allocConstraints of the basic block 25050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if 2 available physical registers have the same constraint count, 25060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return the non callee-saved physical reg */ 25070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* enhancement: record the time when a register is freed (freeTimeStamp) 25080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen the purpose is to reduce false dependency 25090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen priority: constraint count, non callee-saved, time freed 25100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen let x be the lowest constraint count 25110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen set A be available callee-saved physical registers with count == x 25120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen set B be available non callee-saved physical registers with count == x 25130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if set B is not null, return the one with smallest free time 25140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen otherwise, return the one in A with smallest free time 25150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen To ignore whether it is callee-saved, add all candidates to set A 25160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 25170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int setAIndex[8]; 25180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int num_A = 0; 25190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int setBIndex[8]; 25200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int num_B = 0; 25210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index1 = -1; //points to an available physical reg with lowest count 25220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int currentCount = -1; 25230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < 8; k++) { 25240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regCandidateT = currentBB->allocConstraintsSorted[k].physicalReg; 25250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(is8Bit && regCandidateT > PhysicalReg_EDX) continue; 25260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 25270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index1 >= 0 && currentBB->allocConstraintsSorted[k].count > currentCount) 25280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; //candidate has higher count than index1 25290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen assert(regCandidateT < PhysicalReg_Null); 25300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!allRegs[regCandidateT].isUsed) { 25310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /*To ignore whether it is callee-saved, add all candidates to set A */ 25320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(false) {//!allRegs[regCandidateT].isCalleeSaved) { //add to set B 25330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen setBIndex[num_B++] = k; 25340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { //add to set A 25350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen setAIndex[num_A++] = k; 25360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 25370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index1 < 0) { 25380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* index1 points to a physical reg with lowest count */ 25390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index1 = k; 25400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentCount = currentBB->allocConstraintsSorted[k].count; 25410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 25420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 25430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 25440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 25450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int kk; 25460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int smallestTime = -1; 25470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index1 = -1; 25480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(kk = 0; kk < num_B; kk++) { 25490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen k = setBIndex[kk]; 25500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regCandidateT = currentBB->allocConstraintsSorted[k].physicalReg; 25510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen assert(regCandidateT < PhysicalReg_Null); 25520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(kk == 0 || allRegs[regCandidateT].freeTimeStamp < smallestTime) { 25530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index1 = k; 25540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen smallestTime = allRegs[regCandidateT].freeTimeStamp; 25550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 25560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 25570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index1 >= 0) 25580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return currentBB->allocConstraintsSorted[index1].physicalReg; 25590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index1 = -1; 25600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(kk = 0; kk < num_A; kk++) { 25610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen k = setAIndex[kk]; 25620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regCandidateT = currentBB->allocConstraintsSorted[k].physicalReg; 25630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(kk == 0 || allRegs[regCandidateT].freeTimeStamp < smallestTime) { 25640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index1 = k; 25650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen smallestTime = allRegs[regCandidateT].freeTimeStamp; 25660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 25670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 25680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index1 >= 0) return currentBB->allocConstraintsSorted[index1].physicalReg; 25690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return -1; 25700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 25710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return -1; 25720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 25730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 25740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! find a candidate physical register for a variable and spill all variables that are mapped to the candidate 25750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 25760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 25770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenPhysicalReg spillForLogicalReg(int type, int reg, int indexToCompileTable) { 25780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //choose a used register to spill 25790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //when a GG virtual register is spilled, write it to interpretd stack, set physicalReg to Null 25800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen // at end of the basic block, load spilled GG VR to physical reg 25810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //when other types of VR is spilled, write it to interpreted stack, set physicalReg to Null 25820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //when a temporary (non-virtual) register is spilled, write it to stack, set physicalReg to Null 25830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //can we spill a hard-coded temporary register? YES 25840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k, k2; 25850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen PhysicalReg allocR; 25860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 25870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //do not try to free a physical reg that is used by more than one logical registers 25880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //fix on sep 28, 2009 25890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //do not try to spill a hard-coded logical register 25900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //do not try to free a physical reg that is outside of the range for 8-bit logical reg 25910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* for each physical register, 25920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen collect number of non-hardcode entries that are mapped to the physical register */ 25930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int numOfUses[PhysicalReg_Null]; 25940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = PhysicalReg_EAX; k < PhysicalReg_Null; k++) 25950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen numOfUses[k] = 0; 25960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_compile_entries; k++) { 25970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((compileTable[k].physicalReg != PhysicalReg_Null) && 25980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen matchType(type, compileTable[k].physicalType) && 25990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (compileTable[k].physicalType & LowOpndRegType_hard) == 0) { 26000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen numOfUses[compileTable[k].physicalReg]++; 26010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 26020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 26030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 26040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* candidates: all non-hardcode entries that are mapped to 26050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen a physical register that is used by only one entry*/ 26060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool is8Bit = isTemp8Bit(type, reg); 26070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int candidates[COMPILE_TABLE_SIZE]; 26080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int num_cand = 0; 26090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_compile_entries; k++) { 26100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(matchType(type, compileTable[k].physicalType) && 26110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].physicalReg != PhysicalReg_Null) { 26120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(is8Bit && compileTable[k].physicalReg > PhysicalReg_EDX) continue; //not a candidate 26130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!canSpillReg[compileTable[k].physicalReg]) continue; //not a candidate 26140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((compileTable[k].physicalType & LowOpndRegType_hard) == 0 && 26150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen numOfUses[compileTable[k].physicalReg] <= 1) { 26160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen candidates[num_cand++] = k; 26170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 26180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 26190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 26200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 26210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* go through all candidates: 26220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen first check GLUE-related entries */ 26230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int spill_index = -1; 26240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k2 = 0; k2 < num_cand; k2++) { 26250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen k = candidates[k2]; 26260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((compileTable[k].physicalReg != PhysicalReg_Null) && 26270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen matchType(type, compileTable[k].physicalType) && 26280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (compileTable[k].regNum >= PhysicalReg_GLUE_DVMDEX && 26290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].regNum != PhysicalReg_GLUE)) { 26300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen allocR = (PhysicalReg)spillLogicalReg(k, true); 26310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REGALLOC 26320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("SPILL register used by num %d type %d it is a GLUE register with refCount %d", 26330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].regNum, compileTable[k].physicalType, compileTable[k].refCount); 26340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 26350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return allocR; 26360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 26370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 26380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 26390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* out of the candates, find a VR that has the furthest next use */ 26400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int furthestUse = offsetPC; 26410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k2 = 0; k2 < num_cand; k2++) { 26420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen k = candidates[k2]; 26430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((compileTable[k].physicalReg != PhysicalReg_Null) && 26440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen matchType(type, compileTable[k].physicalType) && 26450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen isVirtualReg(compileTable[k].physicalType)) { 26460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int nextUse = getNextAccess(k); 26470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(spill_index < 0 || nextUse > furthestUse) { 26480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen spill_index = k; 26490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen furthestUse = nextUse; 26500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 26510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 26520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 26530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 26540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* spill the VR with the furthest next use */ 26550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(spill_index >= 0) { 26560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen allocR = (PhysicalReg)spillLogicalReg(spill_index, true); 26570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return allocR; //the register is still being used 26580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 26590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 26600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* spill an entry with the smallest refCount */ 26610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int baseLeftOver = 0; 26620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index = -1; 26630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k2 = 0; k2 < num_cand; k2++) { 26640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen k = candidates[k2]; 26650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(k != indexForGlue && 26660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (compileTable[k].physicalReg != PhysicalReg_Null) && 26670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (compileTable[k].physicalType & LowOpndRegType_hard) == 0 && //not hard-coded 26680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen matchType(type, compileTable[k].physicalType)) { 26690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((index < 0) || (compileTable[k].refCount < baseLeftOver)) { 26700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen baseLeftOver = compileTable[k].refCount; 26710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = k; 26720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 26730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 26740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 26750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) { 26760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpCompileTable(); 26770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("no register to spill for logical %d %d", reg, type); 26780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dvmAbort(); 26790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 26800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen allocR = (PhysicalReg)spillLogicalReg(index, true); 26810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REGALLOC 26820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("SPILL register used by num %d type %d it is a temporary register with refCount %d", 26830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].regNum, compileTable[index].physicalType, compileTable[index].refCount); 26840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 26850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return allocR; 26860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 26870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!spill a variable to memory, the variable is specified by an index to compileTable 26880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 26890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!If the variable is a temporary, get a spill location that is not in use and spill the content to the spill location; 26900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!If updateTable is true, set physicalReg to Null; 26910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!Return the physical register that was allocated to the variable 26920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint spillLogicalReg(int spill_index, bool updateTable) { 26930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((compileTable[spill_index].physicalType & LowOpndRegType_hard) != 0) { 26940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("can't spill a hard-coded register"); 26950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dvmAbort(); 26960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 26970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int physicalReg = compileTable[spill_index].physicalReg; 26980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!canSpillReg[physicalReg]) { 26990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef PRINT_WARNING 27000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGW("can't spill register %d", physicalReg); 27010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 27020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //dvmAbort(); //this happens in get_virtual_reg where VR is allocated to the same reg as the hardcoded temporary 27030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 27040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isVirtualReg(compileTable[spill_index].physicalType)) { 27050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //spill back to memory 27060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpToMem(compileTable[spill_index].regNum, 27070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (LowOpndRegType)(compileTable[spill_index].physicalType&MASK_FOR_TYPE), 27080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[spill_index].physicalReg); 27090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 27100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 27110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //update spill_loc_index 27120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k = getSpillIndex(spill_index == indexForGlue, 27130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen getRegSize(compileTable[spill_index].physicalType)); 27140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[spill_index].spill_loc_index = 4*k; 27150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(k >= 0) 27160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen spillIndexUsed[k] = 1; 27170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen saveToSpillRegion(getRegSize(compileTable[spill_index].physicalType), 27180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[spill_index].physicalReg, 4*k); 27190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 27200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //compileTable[spill_index].physicalReg_prev = compileTable[spill_index].physicalReg; 27210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REGALLOC 27220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("REGALLOC: SPILL logical reg %d %d with refCount %d allocated to %d", 27230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[spill_index].regNum, 27240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[spill_index].physicalType, compileTable[spill_index].refCount, 27250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[spill_index].physicalReg); 27260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 27270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!updateTable) return PhysicalReg_Null; 27280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 27290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int allocR = compileTable[spill_index].physicalReg; 27300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[spill_index].physicalReg = PhysicalReg_Null; 27310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return allocR; 27320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 27330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! load a varible from memory to physical register, the variable is specified with an index to compileTable 27340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 27350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!If the variable is a temporary, load from spill location and set the flag for the spill location to not used 27360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint unspillLogicalReg(int spill_index, int physicalReg) { 27370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //can't un-spill to %eax in afterCall!!! 27380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //what if GG VR is allocated to %eax!!! 27390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isVirtualReg(compileTable[spill_index].physicalType)) { 27400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_virtual_reg_noalloc(compileTable[spill_index].regNum, 27410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen getRegSize(compileTable[spill_index].physicalType), 27420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen physicalReg, true); 27430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 27440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 27450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen loadFromSpillRegion(getRegSize(compileTable[spill_index].physicalType), 27460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen physicalReg, compileTable[spill_index].spill_loc_index); 27470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen spillIndexUsed[compileTable[spill_index].spill_loc_index >> 2] = 0; 27480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[spill_index].spill_loc_index = -1; 27490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 27500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REGALLOC 27510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("REGALLOC: UNSPILL logical reg %d %d with refCount %d", compileTable[spill_index].regNum, 27520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[spill_index].physicalType, compileTable[spill_index].refCount); 27530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 27540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return PhysicalReg_Null; 27550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 27560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 27570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!spill a virtual register to memory 27580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 27590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!if the current value of a VR is constant, write immediate to memory; 27600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!if the current value of a VR is in a physical register, call spillLogicalReg to dump content of the physical register to memory; 27610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!ifupdateTable is true, set the physical register for VR to Null and decrease reference count of the virtual register 27620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint spillVirtualReg(int vrNum, LowOpndRegType type, bool updateTable) { 27630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index = searchCompileTable(type | LowOpndRegType_virtual, vrNum); 27640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) { 27650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("can't find VR %d %d in spillVirtualReg", vrNum, type); 27660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return -1; 27670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 27680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //check whether it is const 27690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int value[2]; 27700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int isConst = isVirtualRegConstant(vrNum, type, value, false); //do not update refCount 27710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isConst == 1 || isConst == 3) { 27720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpImmToMem(vrNum, OpndSize_32, value[0]); 27730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 27740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(getRegSize(type) == OpndSize_64 && (isConst == 2 || isConst == 3)) { 27750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpImmToMem(vrNum+1, OpndSize_32, value[1]); 27760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 27770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isConst != 3 && compileTable[index].physicalReg != PhysicalReg_Null) 27780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen spillLogicalReg(index, updateTable); 27790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(updateTable) decreaseRefCount(index); 27800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return -1; 27810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 27820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 27830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! spill variables that are mapped to physical register (regNum) 27840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 27850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 27860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint spillForHardReg(int regNum, int type) { 27870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //find an entry that uses the physical register 27880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int spill_index = -1; 27890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 27900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_compile_entries; k++) { 27910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(k != indexForGlue && 27920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].physicalReg == regNum && 27930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen matchType(type, compileTable[k].physicalType)) { 27940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen spill_index = k; 27950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].regNum == regNum && compileTable[k].physicalType == type) 27960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen continue; 27970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(inGetVR_num >= 0 && compileTable[k].regNum == inGetVR_num && compileTable[k].physicalType == (type | LowOpndRegType_virtual)) 27980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen continue; 27990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REGALLOC 28000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("SPILL logical reg %d %d to free hard-coded reg %d %d", 28010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[spill_index].regNum, compileTable[spill_index].physicalType, 28020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen regNum, type); 28030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[spill_index].physicalType & LowOpndRegType_hard) dumpCompileTable(); 28040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 28050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen assert(spill_index < COMPILE_TABLE_SIZE); 28060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen spillLogicalReg(spill_index, true); 28070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 28080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 28090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return regNum; 28100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 28110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//////////////////////////////////////////////////////////////// 28120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! update allocConstraints of the current basic block 28130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 28140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! allocConstraints specify how many times a hardcoded register is used in this basic block 28150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid updateCurrentBBWithConstraints(PhysicalReg reg) { 28160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(reg > PhysicalReg_EBP) { 28170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("register %d out of range in updateCurrentBBWithConstraints", reg); 28180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 28190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->allocConstraints[reg].count++; 28200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 28210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! sort allocConstraints and save the result in allocConstraintsSorted 28220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 28230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! allocConstraints specify how many times a virtual register is linked to a hardcode register 28240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! it is updated in getVirtualRegInfo and merged by mergeEntry2 28250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint sortAllocConstraint(RegAllocConstraint* allocConstraints, 28260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen RegAllocConstraint* allocConstraintsSorted, bool fromHighToLow) { 28270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int ii, jj; 28280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int num_sorted = 0; 28290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(jj = 0; jj < 8; jj++) { 28300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //figure out where to insert allocConstraints[jj] 28310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int count = allocConstraints[jj].count; 28320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regT = allocConstraints[jj].physicalReg; 28330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen assert(regT < PhysicalReg_Null); 28340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int insertIndex = -1; 28350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(ii = 0; ii < num_sorted; ii++) { 28360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regT2 = allocConstraintsSorted[ii].physicalReg; 28370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen assert(regT2 < PhysicalReg_Null); 28380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(allRegs[regT].isCalleeSaved && 28390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen count == allocConstraintsSorted[ii].count) { 28400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertIndex = ii; 28410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 28420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 28430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!allRegs[regT].isCalleeSaved) && 28440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen count == allocConstraintsSorted[ii].count && 28450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!allRegs[regT2].isCalleeSaved)) { //skip until found one that is not callee-saved 28460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertIndex = ii; 28470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 28480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 28490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((fromHighToLow && count > allocConstraintsSorted[ii].count) || 28500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ((!fromHighToLow) && count < allocConstraintsSorted[ii].count)) { 28510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertIndex = ii; 28520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 28530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 28540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 28550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(insertIndex < 0) { 28560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen allocConstraintsSorted[num_sorted].physicalReg = (PhysicalReg)regT; 28570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen allocConstraintsSorted[num_sorted].count = count; 28580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_sorted++; 28590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 28600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(ii = num_sorted-1; ii >= insertIndex; ii--) { 28610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen allocConstraintsSorted[ii+1] = allocConstraintsSorted[ii]; 28620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 28630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen allocConstraintsSorted[insertIndex] = allocConstraints[jj]; 28640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_sorted++; 28650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 28660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } //for jj 28670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_ALLOC_CONSTRAINT 28680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(jj = 0; jj < 8; jj++) { 28690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(allocConstraintsSorted[jj].count > 0) 28700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("%d: register %d has count %d", jj, allocConstraintsSorted[jj].physicalReg, allocConstraintsSorted[jj].count); 28710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 28720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 28730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 28740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 28750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! find the entry for a given virtual register in compileTable 28760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 28770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 28780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint findVirtualRegInTable(u2 vA, LowOpndRegType type, bool printError) { 28790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k = searchCompileTable(type | LowOpndRegType_virtual, vA); 28800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(k < 0 && printError) { 28810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("findVirtualRegInTable virtual register %d type %d", vA, type); 28820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dvmAbort(); 28830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 28840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return k; 28850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 28860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 28870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! check whether a virtual register is constant 28880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 28890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! the value of the constant is stored in valuePtr; if updateRefCount is true & the VR is constant, reference count for the VR will be reduced by 1 28900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint isVirtualRegConstant(int regNum, LowOpndRegType type, int* valuePtr, bool updateRefCount) { 28910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 28920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen OpndSize size = getRegSize(type); 28930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 28940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexL = -1; 28950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexH = -1; 28960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_const_vr; k++) { 28970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_CONST 28980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("constVRTable VR %d isConst %d value %x", constVRTable[k].regNum, constVRTable[k].isConst, constVRTable[k].value); 28990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 29000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(constVRTable[k].regNum == regNum) { 29010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen indexL = k; 29020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen continue; 29030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 29040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(constVRTable[k].regNum == regNum + 1 && size == OpndSize_64) { 29050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen indexH = k; 29060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen continue; 29070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 29080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 29090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool isConstL = false; 29100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool isConstH = false; 29110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexL >= 0) { 29120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen isConstL = constVRTable[indexL].isConst; 29130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 29140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64 && indexH >= 0) { 29150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen isConstH = constVRTable[indexH].isConst; 29160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 29170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 29180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((isConstL || isConstH)) { 29190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64 && isConstH) 29200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen valuePtr[1] = constVRTable[indexH].value; 29210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isConstL) 29220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen *valuePtr = constVRTable[indexL].value; 29230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 29240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((isConstL && size == OpndSize_32) || (isConstL && isConstH)) { 29250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(updateRefCount) { 29260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexOrig = searchCompileTable(type | LowOpndRegType_virtual, regNum); 29270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexOrig < 0) ALOGE("can't find VR in isVirtualRegConstant num %d type %d", regNum, type); 29280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen decreaseRefCount(indexOrig); 29290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 29300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_CONST 29310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("VR %d %d is const case", regNum, type); 29320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 29330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 3; 29340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 29350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_32) return 0; 29360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isConstL) return 1; 29370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isConstH) return 2; 29380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 29390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 29400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 29410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update RegAccessType of virtual register vB given RegAccessType of vA 29420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 29430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!RegAccessType can be D, L, H 29440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!D means full definition, L means only lower-half is defined, H means only higher half is defined 29450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!we say a VR has no exposed usage in a basic block if the accessType is D or DU 29460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!we say a VR has exposed usage in a basic block if the accessType is not D nor DU 29470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!we say a VR has exposed usage in other basic blocks (hasOtherExposedUsage) if 29480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! there exists another basic block where VR has exposed usage in that basic block 29490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!A can be U, D, L, H, UD, UL, UH, DU, LU, HU (merged result) 29500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!B can be U, D, UD, DU (an entry for the current bytecode) 29510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!input isAPartiallyOverlapB can be any value between -1 to 6 29520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!if A is xmm: gp B lower half of A, (isAPartiallyOverlapB is 1) 29530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! gp B higher half of A, (isAPartiallyOverlapB is 2) 29540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! lower half of A covers the higher half of xmm B (isAPartiallyOverlapB is 4) 29550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! higher half of A covers the lower half of xmm B (isAPartiallyOverlapB is 3) 29560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!if A is gp: A covers the lower half of xmm B, (isAPartiallyOverlapB is 5) 29570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! A covers the higher half of xmm B (isAPartiallyOverlapB is 6) 29580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenRegAccessType updateAccess1(RegAccessType A, OverlapCase isAPartiallyOverlapB) { 29590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(A == REGACCESS_D || A == REGACCESS_DU || A == REGACCESS_UD) { 29600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isAPartiallyOverlapB == OVERLAP_ALIGN) return REGACCESS_D; 29610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isAPartiallyOverlapB == OVERLAP_B_IS_LOW_OF_A || isAPartiallyOverlapB == OVERLAP_B_IS_HIGH_OF_A) 29620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return REGACCESS_D; 29630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isAPartiallyOverlapB == OVERLAP_LOW_OF_A_IS_HIGH_OF_B || isAPartiallyOverlapB == OVERLAP_A_IS_LOW_OF_B) 29640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return REGACCESS_L; 29650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return REGACCESS_H; 29660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 29670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(A == REGACCESS_L || A == REGACCESS_LU || A == REGACCESS_UL) { 29680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isAPartiallyOverlapB == OVERLAP_ALIGN || isAPartiallyOverlapB == OVERLAP_A_IS_LOW_OF_B) 29690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return REGACCESS_L; 29700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isAPartiallyOverlapB == OVERLAP_B_IS_LOW_OF_A) return REGACCESS_D; 29710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isAPartiallyOverlapB == OVERLAP_B_IS_HIGH_OF_A || isAPartiallyOverlapB == OVERLAP_LOW_OF_A_IS_HIGH_OF_B) 29720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return REGACCESS_N; 29730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isAPartiallyOverlapB == OVERLAP_HIGH_OF_A_IS_LOW_OF_B || isAPartiallyOverlapB == OVERLAP_A_IS_HIGH_OF_B) 29740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return REGACCESS_H; 29750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 29760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(A == REGACCESS_H || A == REGACCESS_HU || A == REGACCESS_UH) { 29770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isAPartiallyOverlapB == OVERLAP_ALIGN || isAPartiallyOverlapB == OVERLAP_A_IS_HIGH_OF_B) 29780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return REGACCESS_H; 29790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isAPartiallyOverlapB == OVERLAP_B_IS_LOW_OF_A || isAPartiallyOverlapB == OVERLAP_HIGH_OF_A_IS_LOW_OF_B) 29800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return REGACCESS_N; 29810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isAPartiallyOverlapB == OVERLAP_B_IS_HIGH_OF_A) return REGACCESS_D; 29820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isAPartiallyOverlapB == OVERLAP_LOW_OF_A_IS_HIGH_OF_B || isAPartiallyOverlapB == OVERLAP_A_IS_LOW_OF_B) 29830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return REGACCESS_L; 29840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 29850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return REGACCESS_N; 29860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 29870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! merge RegAccessType C1 with RegAccessType C2 29880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 29890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!C can be N,L,H,D 29900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenRegAccessType updateAccess2(RegAccessType C1, RegAccessType C2) { 29910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(C1 == REGACCESS_D || C2 == REGACCESS_D) return REGACCESS_D; 29920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(C1 == REGACCESS_N) return C2; 29930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(C2 == REGACCESS_N) return C1; 29940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(C1 == REGACCESS_L && C2 == REGACCESS_H) return REGACCESS_D; 29950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(C1 == REGACCESS_H && C2 == REGACCESS_L) return REGACCESS_D; 29960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return C1; 29970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 29980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! merge RegAccessType C with RegAccessType B 29990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 30000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!C can be N,L,H,D 30010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!B can be U, D, UD, DU 30020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenRegAccessType updateAccess3(RegAccessType C, RegAccessType B) { 30030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_D || B == REGACCESS_DU) return B; //no exposed usage 30040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_U || B == REGACCESS_UD) { 30050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(C == REGACCESS_N) return B; 30060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(C == REGACCESS_L) return REGACCESS_LU; 30070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(C == REGACCESS_H) return REGACCESS_HU; 30080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(C == REGACCESS_D) return REGACCESS_DU; 30090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 30100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return B; 30110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 30120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! merge RegAccessType A with RegAccessType B 30130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 30140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!argument isBPartiallyOverlapA can be any value between -1 and 2 30150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!0 means fully overlapping, 1 means B is the lower half, 2 means B is the higher half 30160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenRegAccessType mergeAccess2(RegAccessType A, RegAccessType B, OverlapCase isBPartiallyOverlapA) { 30170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(A == REGACCESS_UD || A == REGACCESS_UL || A == REGACCESS_UH || 30180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen A == REGACCESS_DU || A == REGACCESS_LU || A == REGACCESS_HU) return A; 30190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(A == REGACCESS_D) { 30200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_D) return REGACCESS_D; 30210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_U) return REGACCESS_DU; 30220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_UD) return REGACCESS_DU; 30230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_DU) return B; 30240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 30250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(A == REGACCESS_U) { 30260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_D && isBPartiallyOverlapA == OVERLAP_B_COVER_LOW_OF_A) return REGACCESS_UL; 30270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_D && isBPartiallyOverlapA == OVERLAP_B_COVER_HIGH_OF_A) return REGACCESS_UH; 30280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_D && (isBPartiallyOverlapA == OVERLAP_B_COVER_A)) return REGACCESS_UD; 30290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_U) return A; 30300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_UD && isBPartiallyOverlapA == OVERLAP_B_COVER_LOW_OF_A) return REGACCESS_UL; 30310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_UD && isBPartiallyOverlapA == OVERLAP_B_COVER_HIGH_OF_A) return REGACCESS_UH; 30320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_UD && (isBPartiallyOverlapA == OVERLAP_B_COVER_A)) return REGACCESS_UD; 30330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_DU && isBPartiallyOverlapA == OVERLAP_B_COVER_LOW_OF_A) return REGACCESS_UL; 30340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_DU && isBPartiallyOverlapA == OVERLAP_B_COVER_HIGH_OF_A) return REGACCESS_UH; 30350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_DU && (isBPartiallyOverlapA == OVERLAP_B_COVER_A)) return REGACCESS_UD; 30360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 30370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(A == REGACCESS_L) { 30380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_D && isBPartiallyOverlapA == OVERLAP_B_COVER_LOW_OF_A) return REGACCESS_L; 30390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_D && isBPartiallyOverlapA == OVERLAP_B_COVER_HIGH_OF_A) return REGACCESS_D; 30400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_D && (isBPartiallyOverlapA == OVERLAP_B_COVER_A)) return REGACCESS_D; 30410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_U) return REGACCESS_LU; 30420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_UD) return REGACCESS_LU; 30430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_DU && isBPartiallyOverlapA == OVERLAP_B_COVER_LOW_OF_A) return REGACCESS_LU; 30440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_DU && isBPartiallyOverlapA == OVERLAP_B_COVER_HIGH_OF_A) return REGACCESS_DU; 30450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_DU && (isBPartiallyOverlapA == OVERLAP_B_COVER_A)) return REGACCESS_DU; 30460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 30470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(A == REGACCESS_H) { 30480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_D && isBPartiallyOverlapA == OVERLAP_B_COVER_LOW_OF_A) return REGACCESS_D; 30490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_D && isBPartiallyOverlapA == OVERLAP_B_COVER_HIGH_OF_A) return REGACCESS_H; 30500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_D && (isBPartiallyOverlapA == OVERLAP_B_COVER_A)) return REGACCESS_D; 30510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_U) return REGACCESS_HU; 30520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_UD) return REGACCESS_HU; 30530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_DU && isBPartiallyOverlapA == OVERLAP_B_COVER_LOW_OF_A) return REGACCESS_DU; 30540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_DU && isBPartiallyOverlapA == OVERLAP_B_COVER_HIGH_OF_A) return REGACCESS_HU; 30550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(B == REGACCESS_DU && (isBPartiallyOverlapA == OVERLAP_B_COVER_A)) return REGACCESS_DU; 30560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 30570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return REGACCESS_N; 30580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 30590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 30600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!determines which part of a use is from a given definition 30610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 30620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!reachingDefLive tells us which part of the def is live at this point 30630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!isDefPartiallyOverlapUse can be any value between -1 and 2 30640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenRegAccessType setAccessTypeOfUse(OverlapCase isDefPartiallyOverlapUse, RegAccessType reachingDefLive) { 30650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isDefPartiallyOverlapUse == OVERLAP_B_COVER_A) 30660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return reachingDefLive; 30670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isDefPartiallyOverlapUse == OVERLAP_B_COVER_LOW_OF_A) { //def covers the low half of use 30680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return REGACCESS_L; 30690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 30700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isDefPartiallyOverlapUse == OVERLAP_B_COVER_HIGH_OF_A) { 30710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return REGACCESS_H; 30720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 30730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return REGACCESS_N; 30740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 30750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 30760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! search currentBB->defUseTable to find a def for regNum at offsetPC 30770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 30780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 30790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenDefUsePair* searchDefUseTable(int offsetPC, int regNum, LowOpndRegType pType) { 30800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen DefUsePair* ptr = currentBB->defUseTable; 30810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptr != NULL) { 30820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptr->def.offsetPC == offsetPC && 30830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->def.regNum == regNum && 30840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->def.physicalType == pType) { 30850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return ptr; 30860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 30870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptr->next; 30880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 30890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 30900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 30910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid printDefUseTable() { 30920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("PRINT defUseTable --------"); 30930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen DefUsePair* ptr = currentBB->defUseTable; 30940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptr != NULL) { 30950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI(" def @ %x of VR %d %d has %d uses", ptr->def.offsetPC, 30960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->def.regNum, ptr->def.physicalType, 30970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->num_uses); 30980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen DefOrUseLink* ptr2 = ptr->uses; 30990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptr2 != NULL) { 31000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI(" use @ %x of VR %d %d accessType %d", ptr2->offsetPC, 31010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr2->regNum, 31020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr2->physicalType, 31030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr2->accessType); 31040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr2 = ptr2->next; 31050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 31060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptr->next; 31070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 31080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 31090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! when a VR is used, check whether a transfer from memory to XMM is necessary 31100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 31110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 31120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint updateVRAtUse(int reg, LowOpndRegType pType, int regAll) { 31130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 31140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < currentBB->num_xfer_points; k++) { 31150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB->xferPoints[k].offsetPC == offsetPC && 31160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[k].xtype == XFER_MEM_TO_XMM && 31170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[k].regNum == reg && 31180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen currentBB->xferPoints[k].physicalType == pType) { 31190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_XFER_POINTS 31200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("XFER from memory to xmm %d", reg); 31210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 31220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg_noalloc(OpndSize_64, 31230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 4*currentBB->xferPoints[k].regNum, PhysicalReg_FP, true, 31240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, currentBB->xferPoints[k].regNum, 31250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen regAll, true); 31260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 31270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 31280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 31290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 31300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/////////////////////////////////////////////////////////////////////////////// 31310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen// DEAD/USELESS STATEMENT ELMINATION 31320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen// bytecodes can be removed if a bytecode has no side effect and the defs are not used 31330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen// this optimization is guarded with DSE_OPT 31340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen// currently, this optimization is not on, since it does not provide observable performance improvement 31350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen// and it increases compilation time 31360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 31370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/* we remove a maximal of 40 bytecodes within a single basic block */ 31380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#define MAX_NUM_DEAD_PC_IN_BB 40 31390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint deadPCs[MAX_NUM_DEAD_PC_IN_BB]; 31400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint num_dead_pc = 0; 31410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! collect all PCs that can be removed 31420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 31430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! traverse each byte code in the current basic block and check whether it can be removed, if yes, update deadPCs 31440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid getDeadStmts() { 31450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen BasicBlock_O1* bb = currentBB; 31460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 31470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_dead_pc = 0; 31480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //traverse each bytecode in the basic block 31490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //update offsetPC, rPC & inst 31500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u2* rPC_start = (u2*)currentMethod->insns; 31510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MIR* mir; 31520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(mir = bb->jitBasicBlock->firstMIRInsn; mir; mir = mir->next) { 31530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen offsetPC = mir->seqNum; 31540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen rPC = rPC_start + mir->offset; 31550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(mir->dalvikInsn.opcode >= kNumPackedOpcodes) continue; 31560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_DSE 31570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("DSE: offsetPC %x", offsetPC); 31580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 31590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen inst = FETCH(0); 31600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool isDeadStmt = true; 31610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen getVirtualRegInfo(infoByteCode); 31620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen u2 inst_op = INST_INST(inst); 31630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //skip bytecodes with side effect 31640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(inst_op != OP_CONST_STRING && inst_op != OP_CONST_STRING_JUMBO && 31650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen inst_op != OP_MOVE && inst_op != OP_MOVE_OBJECT && 31660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen inst_op != OP_MOVE_FROM16 && inst_op != OP_MOVE_OBJECT_FROM16 && 31670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen inst_op != OP_MOVE_16 && inst_op != OP_CONST_CLASS && 31680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen inst_op != OP_MOVE_OBJECT_16 && inst_op != OP_MOVE_WIDE && 31690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen inst_op != OP_MOVE_WIDE_FROM16 && inst_op != OP_MOVE_WIDE_16 && 31700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen inst_op != OP_MOVE_RESULT && inst_op != OP_MOVE_RESULT_OBJECT) { 31710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen continue; 31720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 31730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //some statements do not define any VR!!! 31740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int num_defs = 0; 31750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_regs_per_bytecode; k++) { 31760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(infoByteCode[k].accessType == REGACCESS_D || 31770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen infoByteCode[k].accessType == REGACCESS_UD || 31780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen infoByteCode[k].accessType == REGACCESS_DU) { //search defUseTable 31790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_defs++; 31800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen DefUsePair* indexT = searchDefUseTable(offsetPC, infoByteCode[k].regNum, infoByteCode[k].physicalType); 31810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexT == NULL) { 31820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("def at %x of VR %d %d not in table", 31830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen offsetPC, infoByteCode[k].regNum, infoByteCode[k].physicalType); 31840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 31850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 31860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexT->num_uses > 0) { 31870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen isDeadStmt = false; 31880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 31890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 31900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_DSE 31910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("DSE: num_uses is %d for def at %d for VR %d %d", indexT->num_uses, 31920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen offsetPC, infoByteCode[k].regNum, infoByteCode[k].physicalType); 31930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 31940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 31950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 31960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } //for k 31970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(num_defs == 0) isDeadStmt = false; 31980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isDeadStmt && num_dead_pc < MAX_NUM_DEAD_PC_IN_BB) { 31990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_DSE 32000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("DSE: stmt at %x is dead", offsetPC); 32010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 32020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen deadPCs[num_dead_pc++] = offsetPC; 32030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 32040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } //for offsetPC 32050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_DSE 32060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("Dead Stmts: "); 32070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_dead_pc; k++) ALOGI("%x ", deadPCs[k]); 32080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI(""); 32090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 32100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 32110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! entry point to remove dead statements 32120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 32130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! recursively call getDeadStmts and remove uses in defUseTable that are from a dead PC 32140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! until there is no change to number of dead PCs 32150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid removeDeadDefs() { 32160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 32170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int deadPCs_2[MAX_NUM_DEAD_PC_IN_BB]; 32180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int num_dead_pc_2 = 0; 32190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen getDeadStmts(); 32200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(num_dead_pc == 0) return; 32210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen DefUsePair* ptr = NULL; 32220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen DefOrUseLink* ptrUse = NULL; 32230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen DefOrUseLink* ptrUse_prev = NULL; 32240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(true) { 32250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //check all the uses in defUseTable and remove any use that is from a dead PC 32260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = currentBB->defUseTable; 32270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptr != NULL) { 32280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k3; 32290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrUse = ptr->uses; 32300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrUse_prev = NULL; 32310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptrUse != NULL) { 32320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool isIn = false; 32330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k3 = 0; k3 < num_dead_pc; k3++) { 32340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptrUse->offsetPC == deadPCs[k3]) { 32350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen isIn = true; 32360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 32370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 32380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen }//k3 32390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!isIn) { 32400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrUse_prev = ptrUse; 32410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrUse = ptrUse->next; //next use 32420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 32430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 32440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //go to next use and remove ptrUse 32450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_DSE 32460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("DSE: remove usage at offsetPC %d reached by def at %d", ptrUse->offsetPC, 32470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->def.offsetPC); 32480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 32490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen DefOrUseLink* nextP = ptrUse->next; 32500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptrUse == ptr->useTail) ptr->useTail = ptrUse_prev; 32510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen free(ptrUse); 32520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptrUse_prev == NULL) { 32530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->uses = nextP; 32540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 32550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrUse_prev->next = nextP; 32560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 32570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptrUse = nextP; //do not update ptrUse_prev 32580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr->num_uses--; 32590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 32600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen }//while ptrUse 32610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptr->next; 32620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen }//while ptr 32630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //save deadPCs in deadPCs_2 32640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_dead_pc_2 = num_dead_pc; 32650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_dead_pc_2; k++) 32660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen deadPCs_2[k] = deadPCs[k]; 32670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //update deadPCs 32680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen getDeadStmts(); 32690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //if no change to number of dead PCs, break out of the while loop 32700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(num_dead_pc_2 == num_dead_pc) break; 32710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen }//while 32720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_DSE 32730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("DSE: DEAD STMTS: "); 32740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_dead_pc; k++) { 32750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("%d ", deadPCs[k]); 32760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 32770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI(""); 32780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 32790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 32800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen///////////////////////////////////////////////////////////// 32810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!search memVRTable for a given virtual register 32820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 32830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 32840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint searchMemTable(int regNum) { 32850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 32860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_memory_vr; k++) { 32870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(memVRTable[k].regNum == regNum) { 32880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return k; 32890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 32900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 32910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGW("in searchMemTable can't find VR %d num_memory_vr %d", regNum, num_memory_vr); 32920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return -1; 32930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 32940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen///////////////////////////////////////////////////////////////////////// 32950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen// A VR is already in memory && NULL CHECK 32960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!check whether the latest content of a VR is in memory 32970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 32980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 32990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool isInMemory(int regNum, OpndSize size) { 33000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexL = searchMemTable(regNum); 33010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexH = -1; 33020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64) indexH = searchMemTable(regNum+1); 33030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexL < 0) return false; 33040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64 && indexH < 0) return false; 33050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!memVRTable[indexL].inMemory) return false; 33060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64 && (!memVRTable[indexH].inMemory)) return false; 33070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return true; 33080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 33090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!set field inMemory of memVRTable to true 33100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 33110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 33120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid setVRToMemory(int regNum, OpndSize size) { 33130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexL = searchMemTable(regNum); 33140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexH = -1; 33150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64) indexH = searchMemTable(regNum+1); 33160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexL < 0) { 33170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("VR %d not in memVRTable", regNum); 33180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 33190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 33200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[indexL].inMemory = true; 33210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64) { 33220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexH < 0) { 33230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("VR %d not in memVRTable", regNum+1); 33240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 33250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 33260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[indexH].inMemory = true; 33270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 33280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 33290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! check whether null check for a VR is performed previously 33300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 33310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 33320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool isVRNullCheck(int regNum, OpndSize size) { 33330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size != OpndSize_32) { 33340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("isVRNullCheck size should be 32"); 33350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dvmAbort(); 33360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 33370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexL = searchMemTable(regNum); 33380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexL < 0) { 33390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("VR %d not in memVRTable", regNum); 33400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 33410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 33420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return memVRTable[indexL].nullCheckDone; 33430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 33440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool isVRBoundCheck(int vr_array, int vr_index) { 33450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexL = searchMemTable(vr_array); 33460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexL < 0) { 33470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("isVRBoundCheck: VR %d not in memVRTable", vr_array); 33480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 33490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 33500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(memVRTable[indexL].boundCheck.indexVR == vr_index) 33510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return memVRTable[indexL].boundCheck.checkDone; 33520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 33530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 33540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! set nullCheckDone in memVRTable to true 33550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 33560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 33570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid setVRNullCheck(int regNum, OpndSize size) { 33580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size != OpndSize_32) { 33590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("setVRNullCheck size should be 32"); 33600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dvmAbort(); 33610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 33620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexL = searchMemTable(regNum); 33630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexL < 0) { 33640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("VR %d not in memVRTable", regNum); 33650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 33660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 33670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[indexL].nullCheckDone = true; 33680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 33690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid setVRBoundCheck(int vr_array, int vr_index) { 33700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexL = searchMemTable(vr_array); 33710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexL < 0) { 33720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("setVRBoundCheck: VR %d not in memVRTable", vr_array); 33730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 33740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 33750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[indexL].boundCheck.indexVR = vr_index; 33760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[indexL].boundCheck.checkDone = true; 33770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 33780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid clearVRBoundCheck(int regNum, OpndSize size) { 33790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 33800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_memory_vr; k++) { 33810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(memVRTable[k].regNum == regNum || 33820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (size == OpndSize_64 && memVRTable[k].regNum == regNum+1)) { 33830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[k].boundCheck.checkDone = false; 33840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 33850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(memVRTable[k].boundCheck.indexVR == regNum || 33860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (size == OpndSize_64 && memVRTable[k].boundCheck.indexVR == regNum+1)) { 33870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[k].boundCheck.checkDone = false; 33880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 33890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 33900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 33910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! set inMemory of memVRTable to false 33920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 33930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 33940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid clearVRToMemory(int regNum, OpndSize size) { 33950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexL = searchMemTable(regNum); 33960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexH = -1; 33970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64) indexH = searchMemTable(regNum+1); 33980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexL >= 0) { 33990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[indexL].inMemory = false; 34000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 34010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64 && indexH >= 0) { 34020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[indexH].inMemory = false; 34030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 34040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 34050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! set nullCheckDone of memVRTable to false 34060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 34070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 34080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid clearVRNullCheck(int regNum, OpndSize size) { 34090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexL = searchMemTable(regNum); 34100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexH = -1; 34110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64) indexH = searchMemTable(regNum+1); 34120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexL >= 0) { 34130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[indexL].nullCheckDone = false; 34140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 34150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64 && indexH >= 0) { 34160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[indexH].nullCheckDone = false; 34170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 34180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 34190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 34200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! Extend Virtual Register life 34210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 34220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! Requests that the life of a specific virtual register be extended. This ensures 34230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! that its mapping to a physical register won't be canceled while the extension 34240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! request is valid. NOTE: This does not support 64-bit values (when two adjacent 34250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! VRs are used) 34260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! @see cancelVRFreeDelayRequest 34270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! @see getVRFreeDelayRequested 34280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! @see VRFreeDelayFlags 34290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! @param regNum is the VR number 34300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! @param reason explains why freeing must be delayed. A single or combination 34310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! of VRFreeDelayFlags should be used. 34320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! @return negative value if request failed 34330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint requestVRFreeDelay(int regNum, u4 reason) { 34340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //TODO Add 64-bit operand support when needed 34350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexL = searchMemTable(regNum); 34360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexL >= 0) { 34370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[indexL].delayFreeFlags |= reason; 34380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 34390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("requestVRFreeDelay: VR %d not in memVRTable", regNum); 34400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 34410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return indexL; 34420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 34430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 34440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! Cancel request for virtual register life extension 34450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 34460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! Cancels any outstanding requests to extended liveness of VR. Additionally, 34470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! this ensures that if the VR is no longer life after this point, it will 34480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! no longer be associated with a physical register which can then be reused. 34490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! NOTE: This does not support 64-bit values (when two adjacent VRs are used) 34500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! @see requestVRFreeDelay 34510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! @see getVRFreeDelayRequested 34520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! @see VRFreeDelayFlags 34530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! @param regNum is the VR number 34540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! @param reason explains what freeing delay request should be canceled. A single 34550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! or combination of VRFreeDelayFlags should be used. 34560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid cancelVRFreeDelayRequest(int regNum, u4 reason) { 34570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //TODO Add 64-bit operand support when needed 34580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool needCallToFreeReg = false; 34590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexL = searchMemTable(regNum); 34600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexL >= 0) { 34610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((memVRTable[indexL].delayFreeFlags & reason) != VRDELAY_NONE) { // don't cancel delay if it wasn't requested 34620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[indexL].delayFreeFlags ^= reason; // only cancel this particular reason, not all others 34630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(memVRTable[indexL].delayFreeFlags == VRDELAY_NONE) 34640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen needCallToFreeReg = true; // freeReg might want to free this VR now if there is no longer a valid delay 34650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 34660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 34670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(needCallToFreeReg) 34680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 34690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 34700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 34710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! Gets status of virtual register free delay request 34720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 34730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! Finds out if there was a delay request for freeing this VR. 34740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! NOTE: This does not support 64-bit values (when two adjacent VRs are used) 34750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! @see requestVRFreeDelay 34760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! @see cancelVRFreeDelayRequest 34770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! @param regNum is the VR number 34780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! @return true if VR has an active delay request 34790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool getVRFreeDelayRequested(int regNum) { 34800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //TODO Add 64-bit operand support when needed 34810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexL = searchMemTable(regNum); 34820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexL >= 0) { 34830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(memVRTable[indexL].delayFreeFlags != VRDELAY_NONE) 34840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return true; 34850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 34860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 34870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 34880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 34890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 34900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! find the basic block that a bytecode is in 34910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 34920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 34930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenBasicBlock_O1* findForOffset(int offset) { 34940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 34950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_bbs_for_method; k++) { 34960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(method_bbs_sorted[k]->pc_start <= offset && method_bbs_sorted[k]->pc_end > offset) 34970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return method_bbs_sorted[k]; 34980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 34990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 35000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 35010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid dump_CFG(Method* method); 35020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 35030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint current_bc_size = -1; 35040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 35050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! check whether a virtual register is used in a basic block 35060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 35070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 35080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool isUsedInBB(int regNum, int type, BasicBlock_O1* bb) { 35090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 35100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < bb->num_regs; k++) { 35110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(bb->infoBasicBlock[k].physicalType == (type&MASK_FOR_TYPE) && bb->infoBasicBlock[k].regNum == regNum) 35120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return true; 35130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 35140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 35150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 35160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! return the index to infoBasicBlock for a given virtual register 35170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 35180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! return -1 if not found 35190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint searchVirtualInfoOfBB(LowOpndRegType type, int regNum, BasicBlock_O1* bb) { 35200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 35210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < bb->num_regs; k++) { 35220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(bb->infoBasicBlock[k].physicalType == type && bb->infoBasicBlock[k].regNum == regNum) 35230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return k; 35240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 35250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return -1; 35260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 35270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! return the index to compileTable for a given virtual register 35280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 35290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! return -1 if not found 35300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint searchCompileTable(int type, int regNum) { //returns the index 35310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 35320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_compile_entries; k++) { 35330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].physicalType == type && compileTable[k].regNum == regNum) 35340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return k; 35350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 35360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return -1; 35370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 35380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!check whether a physical register for a variable with typeA will work for another variable with typeB 35390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 35400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!Type LowOpndRegType_ss is compatible with type LowOpndRegType_xmm 35410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool matchType(int typeA, int typeB) { 35420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((typeA & MASK_FOR_TYPE) == (typeB & MASK_FOR_TYPE)) return true; 35430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((typeA & MASK_FOR_TYPE) == LowOpndRegType_ss && 35440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (typeB & MASK_FOR_TYPE) == LowOpndRegType_xmm) return true; 35450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((typeA & MASK_FOR_TYPE) == LowOpndRegType_xmm && 35460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (typeB & MASK_FOR_TYPE) == LowOpndRegType_ss) return true; 35470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 35480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 35490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!check whether a virtual register is used in the current bytecode 35500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 35510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 35520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool isUsedInByteCode(int regNum, int type) { 35530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen getVirtualRegInfo(infoByteCode); 35540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 35550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_regs_per_bytecode; k++) { 35560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(infoByteCode[k].physicalType == (type&MASK_FOR_TYPE) && infoByteCode[k].regNum == regNum) 35570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return true; 35580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 35590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 35600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 35610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! obsolete 35620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool defineFirst(int atype) { 35630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(atype == REGACCESS_D || atype == REGACCESS_L || atype == REGACCESS_H || atype == REGACCESS_DU) 35640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return true; 35650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 35660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 35670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!check whether a virtual register is updated in a basic block 35680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 35690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 35700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool notUpdated(RegAccessType atype) { 35710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(atype == REGACCESS_U) return true; 35720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 35730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 35740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!check whether a virtual register has exposed usage within a given basic block 35750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 35760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 35770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool hasExposedUsage2(BasicBlock_O1* bb, int index) { 35780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen RegAccessType atype = bb->infoBasicBlock[index].accessType; 35790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(atype == REGACCESS_D || atype == REGACCESS_L || atype == REGACCESS_H || atype == REGACCESS_DU) 35800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 35810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return true; 35820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 35830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! return the spill location that is not used 35840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 35850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 35860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint getSpillIndex(bool isGLUE, OpndSize size) { 35870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isGLUE) return 0; 35880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 35890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 1; k <= MAX_SPILL_JIT_IA-1; k++) { 35900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(size == OpndSize_64) { 35910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(k < MAX_SPILL_JIT_IA-1 && spillIndexUsed[k] == 0 && spillIndexUsed[k+1] == 0) 35920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return k; 35930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 35940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(spillIndexUsed[k] == 0) { 35950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return k; 35960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 35970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 35980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("can't find spill position in spillLogicalReg"); 35990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return -1; 36000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 36010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!this is called before generating a native code, it sets entries in array canSpillReg to true 36020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 36030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!startNativeCode must be paired with endNativeCode 36040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid startNativeCode(int vr_num, int vr_type) { 36050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 36060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < PhysicalReg_Null; k++) { 36070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen canSpillReg[k] = true; 36080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 36090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen inGetVR_num = vr_num; 36100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen inGetVR_type = vr_type; 36110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 36120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! called right after generating a native code 36130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 36140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!It sets entries in array canSpillReg to true and reset inGetVR_num to -1 36150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid endNativeCode() { 36160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 36170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < PhysicalReg_Null; k++) { 36180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen canSpillReg[k] = true; 36190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 36200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen inGetVR_num = -1; 36210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 36220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! set canSpillReg[physicalReg] to false 36230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 36240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 36250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid donotSpillReg(int physicalReg) { 36260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen canSpillReg[physicalReg] = false; 36270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 36280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! set canSpillReg[physicalReg] to true 36290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 36300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 36310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid doSpillReg(int physicalReg) { 36320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen canSpillReg[physicalReg] = true; 36330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 36340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! touch hardcoded register %ecx and reduce its reference count 36350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 36360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 36370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint touchEcx() { 36380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //registerAlloc will spill logical reg that is mapped to ecx 36390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //registerAlloc will reduce refCount 36400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen registerAlloc(LowOpndRegType_gp, PhysicalReg_ECX, true, true); 36410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 36420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 36430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! touch hardcoded register %eax and reduce its reference count 36440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 36450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 36460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint touchEax() { 36470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen registerAlloc(LowOpndRegType_gp, PhysicalReg_EAX, true, true); 36480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 36490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 36500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint touchEsi() { 36510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen registerAlloc(LowOpndRegType_gp, PhysicalReg_ESI, true, true); 36520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 36530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 36540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint touchXmm1() { 36550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen registerAlloc(LowOpndRegType_xmm, XMM_1, true, true); 36560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 36570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 36580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint touchEbx() { 36590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen registerAlloc(LowOpndRegType_gp, PhysicalReg_EBX, true, true); 36600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 36610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 36620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 36630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! touch hardcoded register %edx and reduce its reference count 36640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 36650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 36660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint touchEdx() { 36670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen registerAlloc(LowOpndRegType_gp, PhysicalReg_EDX, true, true); 36680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 36690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 36700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 36710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef HACK_FOR_DEBUG 36720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//for debugging purpose, instructions are added at a certain place 36730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool hacked = false; 36740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid hackBug() { 36750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!hacked && iget_obj_inst == 13) { 36760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#if 0 36770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_reg_noalloc(OpndSize_32, PhysicalReg_EBX, true, PhysicalReg_ECX, true); 36780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //move from ebx to ecx & update compileTable for v3 36790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int tIndex = searchCompileTable(LowOpndRegType_virtual | LowOpndRegType_gp, 3); 36800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(tIndex < 0) ALOGE("hack can't find VR3"); 36810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[tIndex].physicalReg = PhysicalReg_ECX; 36820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#else 36830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_mem_noalloc(OpndSize_32, PhysicalReg_EBX, true, 12, PhysicalReg_FP, true); 36840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 36850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 36860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 36870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid hackBug2() { 36880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!hacked && iget_obj_inst == 13) { 36890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump_imm_mem_noalloc(Mnemonic_MOV, OpndSize_32, 0, 12, PhysicalReg_FP, true); 36900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen hacked = true; 36910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 36920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 36930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 36940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 36950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! this function is called before calling a helper function or a vm function 36960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint beforeCall(const char* target) { //spill all live registers 36970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB == NULL) return -1; 36980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 36990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* special case for ncgGetEIP: this function only updates %edx */ 37000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!strcmp(target, "ncgGetEIP")) { 37010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEdx(); 37020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return -1; 37030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 37040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 37050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* these functions use %eax for the return value */ 37060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, "dvmInstanceofNonTrivial")) || 37070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!strcmp(target, "dvmUnlockObject")) || 37080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!strcmp(target, "dvmAllocObject")) || 37090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!strcmp(target, "dvmAllocArrayByClass")) || 37100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!strcmp(target, "dvmAllocPrimitiveArray")) || 37110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!strcmp(target, "dvmInterpHandleFillArrayData")) || 37120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!strcmp(target, "dvmFindInterfaceMethodInCache2")) || 37130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!strcmp(target, "dvmNcgHandlePackedSwitch")) || 37140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!strcmp(target, "dvmNcgHandleSparseSwitch")) || 37150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!strcmp(target, "dvmCanPutArrayElement")) || 37160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!strcmp(target, "moddi3")) || (!strcmp(target, "divdi3")) || 37170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!strcmp(target, "execute_inline")) 37180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen || (!strcmp(target, "dvmJitToPatchPredictedChain")) 37190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen || (!strcmp(target, "dvmJitHandlePackedSwitch")) 37200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen || (!strcmp(target, "dvmJitHandleSparseSwitch")) 37210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ) { 37220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEax(); 37230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 37240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 37250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //these two functions also use %edx for the return value 37260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, "moddi3")) || (!strcmp(target, "divdi3"))) { 37270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEdx(); 37280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 37290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".new_instance_helper"))) { 37300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEsi(); touchEax(); 37310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 37320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#if defined(ENABLE_TRACING) 37330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, "common_periodicChecks4"))) { 37340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEdx(); 37350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 37360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 37370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".const_string_helper"))) { 37380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEcx(); touchEax(); 37390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 37400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".check_cast_helper"))) { 37410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEbx(); touchEsi(); 37420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 37430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".instance_of_helper"))) { 37440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEbx(); touchEsi(); touchEcx(); 37450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 37460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".monitor_enter_helper"))) { 37470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEbx(); 37480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 37490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".monitor_exit_helper"))) { 37500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEbx(); 37510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 37520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".aget_wide_helper"))) { 37530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEbx(); touchEcx(); touchXmm1(); 37540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 37550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".aget_helper")) || (!strcmp(target, ".aget_char_helper")) || 37560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!strcmp(target, ".aget_short_helper")) || (!strcmp(target, ".aget_bool_helper")) || 37570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!strcmp(target, ".aget_byte_helper"))) { 37580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEbx(); touchEcx(); touchEdx(); 37590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 37600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".aput_helper")) || (!strcmp(target, ".aput_char_helper")) || 37610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!strcmp(target, ".aput_short_helper")) || (!strcmp(target, ".aput_bool_helper")) || 37620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!strcmp(target, ".aput_byte_helper")) || (!strcmp(target, ".aput_wide_helper"))) { 37630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEbx(); touchEcx(); touchEdx(); 37640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 37650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".sput_helper")) || (!strcmp(target, ".sput_wide_helper"))) { 37660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEdx(); touchEax(); 37670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 37680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".sget_helper"))) { 37690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEdx(); touchEcx(); 37700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 37710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".sget_wide_helper"))) { 37720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEdx(); touchXmm1(); 37730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 37740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".aput_obj_helper"))) { 37750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEdx(); touchEcx(); touchEax(); 37760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 37770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".iput_helper")) || (!strcmp(target, ".iput_wide_helper"))) { 37780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEbx(); touchEcx(); touchEsi(); 37790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 37800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".iget_helper"))) { 37810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEbx(); touchEcx(); touchEdx(); 37820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 37830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".iget_wide_helper"))) { 37840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEbx(); touchEcx(); touchXmm1(); 37850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 37860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".new_array_helper"))) { 37870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEbx(); touchEdx(); touchEax(); 37880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 37890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".invoke_virtual_helper"))) { 37900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEbx(); touchEcx(); 37910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 37920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".invoke_direct_helper"))) { 37930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEsi(); touchEcx(); 37940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 37950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".invoke_super_helper"))) { 37960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEbx(); touchEcx(); 37970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 37980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".invoke_interface_helper"))) { 37990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEbx(); touchEcx(); 38000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 38010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".invokeMethodNoRange_5_helper")) || 38020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!strcmp(target, ".invokeMethodNoRange_4_helper"))) { 38030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEbx(); touchEsi(); touchEax(); touchEdx(); 38040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 38050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".invokeMethodNoRange_3_helper"))) { 38060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEbx(); touchEsi(); touchEax(); 38070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 38080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".invokeMethodNoRange_2_helper"))) { 38090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEbx(); touchEsi(); 38100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 38110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".invokeMethodNoRange_1_helper"))) { 38120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEbx(); 38130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 38140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".invokeMethodRange_helper"))) { 38150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen touchEdx(); touchEsi(); 38160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 38170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REGALLOC 38180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("enter beforeCall"); 38190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 38200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!strncmp(target, ".invokeArgsDone", 15)) resetGlue(PhysicalReg_GLUE_DVMDEX); 38210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 38220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); //to avoid spilling dead logical registers 38230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 38240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_compile_entries; k++) { 38250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* before throwing an exception, if GLUE is spilled, load to %ebp 38260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen this should happen at last */ 38270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(k == indexForGlue) continue; 38280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].physicalReg != PhysicalReg_Null && 38290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (compileTable[k].physicalType & LowOpndRegType_hard) == 0) { 38300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* handles non hardcoded variables that are in physical registers */ 38310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!strcmp(target, "exception")) { 38320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* before throwing an exception 38330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen update contents of all VRs in Java stack */ 38340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!isVirtualReg(compileTable[k].physicalType)) continue; 38350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* to have correct GC, we should update contents for L VRs as well */ 38360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //if(compileTable[k].gType == GLOBALTYPE_L) continue; 38370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 38380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strcmp(target, ".const_string_resolve")) || 38390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!strcmp(target, ".static_field_resolve")) || 38400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!strcmp(target, ".inst_field_resolve")) || 38410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!strcmp(target, ".class_resolve")) || 38420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!strcmp(target, ".direct_method_resolve")) || 38430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!strcmp(target, ".virtual_method_resolve")) || 38440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!strcmp(target, ".static_method_resolve"))) { 38450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* physical register %ebx will keep its content 38460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen but to have correct GC, we should dump content of a VR 38470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen that is mapped to %ebx */ 38480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].physicalReg == PhysicalReg_EBX && 38490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!isVirtualReg(compileTable[k].physicalType))) 38500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen continue; 38510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 38520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!strncmp(target, "dvm", 3)) || (!strcmp(target, "moddi3")) || 38530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!strcmp(target, "divdi3")) || 38540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!strcmp(target, "fmod")) || (!strcmp(target, "fmodf"))) { 38550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* callee-saved registers (%ebx, %esi, %ebp, %edi) will keep the content 38560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen but to have correct GC, we should dump content of a VR 38570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen that is mapped to a callee-saved register */ 38580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((compileTable[k].physicalReg == PhysicalReg_EBX || 38590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].physicalReg == PhysicalReg_ESI) && 38600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (!isVirtualReg(compileTable[k].physicalType))) 38610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen continue; 38620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 38630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REGALLOC 38640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("SPILL logical register %d %d in beforeCall", 38650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].regNum, compileTable[k].physicalType); 38660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 38670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen spillLogicalReg(k, true); 38680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 38690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 38700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexForGlue >= 0 && !strcmp(target, "exception") && 38710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[indexForGlue].physicalReg == PhysicalReg_Null) { 38720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen unspillLogicalReg(indexForGlue, PhysicalReg_EBP); //load %ebp 38730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 38740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REGALLOC 38750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("exit beforeCall"); 38760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 38770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 38780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 38790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint getFreeReg(int type, int reg, int indexToCompileTable); 38800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! after calling a helper function or a VM function 38810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 38820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 38830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint afterCall(const char* target) { //un-spill 38840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB == NULL) return -1; 38850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!strcmp(target, "ncgGetEIP")) return -1; 38860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 38870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 38880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 38890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! check whether a temporary is 8-bit 38900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 38910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 38920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool isTemp8Bit(int type, int reg) { 38930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB == NULL) return false; 38940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!isTemporary(type, reg)) return false; 38950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 38960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_temp_regs_per_bytecode; k++) { 38970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(infoByteCodeTemp[k].physicalType == type && 38980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen infoByteCodeTemp[k].regNum == reg) { 38990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return infoByteCodeTemp[k].is8Bit; 39000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 39010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 39020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("isTemp8Bit %d %d", type, reg); 39030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 39040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 39050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 39060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/* functions to access live ranges of a VR 39070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Live range info is stored in memVRTable[].ranges, which is a linked list 39080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 39090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! check whether a VR is live at the current bytecode 39100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 39110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 39120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool isVRLive(int vA) { 39130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index = searchMemTable(vA); 39140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) { 39150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("couldn't find VR %d in memTable", vA); 39160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 39170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 39180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LiveRange* ptr = memVRTable[index].ranges; 39190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptr != NULL) { 39200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(offsetPC >= ptr->start && offsetPC <= ptr->end) return true; 39210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptr->next; 39220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 39230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 39240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 39250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 39260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! check whether the current bytecode is the last access to a VR within a live range 39270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 39280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!for 64-bit VR, return true only when true for both low half and high half 39290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool isLastByteCodeOfLiveRange(int compileIndex) { 39300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k = compileIndex; 39310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen OpndSize tSize = getRegSize(compileTable[k].physicalType); 39320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index; 39330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LiveRange* ptr = NULL; 39340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(tSize == OpndSize_32) { 39350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* check live ranges for the VR */ 39360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchMemTable(compileTable[k].regNum); 39370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) { 39380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("couldn't find VR %d in memTable", compileTable[k].regNum); 39390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 39400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 39410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = memVRTable[index].ranges; 39420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptr != NULL) { 39430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(offsetPC == ptr->end) return true; 39440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptr->next; 39450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 39460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 39470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 39480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* size of the VR is 64 */ 39490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* check live ranges of the low half */ 39500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchMemTable(compileTable[k].regNum); 39510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool tmpB = false; 39520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) { 39530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("couldn't find VR %d in memTable", compileTable[k].regNum); 39540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 39550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 39560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = memVRTable[index].ranges; 39570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptr != NULL) { 39580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(offsetPC == ptr->end) { 39590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen tmpB = true; 39600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 39610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 39620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptr->next; 39630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 39640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!tmpB) return false; 39650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* check live ranges of the high half */ 39660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchMemTable(compileTable[k].regNum+1); 39670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) { 39680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("couldn't find VR %d in memTable", compileTable[k].regNum+1); 39690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 39700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 39710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = memVRTable[index].ranges; 39720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptr != NULL) { 39730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(offsetPC == ptr->end) { 39740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return true; 39750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 39760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptr->next; 39770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 39780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 39790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 39800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 39810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! check whether the current bytecode is in a live range that extends to end of a basic block 39820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 39830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!for 64 bit, return true if true for both low half and high half 39840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool reachEndOfBB(int compileIndex) { 39850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k = compileIndex; 39860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen OpndSize tSize = getRegSize(compileTable[k].physicalType); 39870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index; 39880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool retCode = false; 39890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* check live ranges of the low half */ 39900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchMemTable(compileTable[k].regNum); 39910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) { 39920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("couldn't find VR %d in memTable", compileTable[k].regNum); 39930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 39940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 39950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LiveRange* ptr = memVRTable[index].ranges; 39960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptr != NULL) { 39970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(offsetPC >= ptr->start && 39980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen offsetPC <= ptr->end) { 39990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptr->end == currentBB->pc_end) { 40000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen retCode = true; 40010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 40020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 40030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 40040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptr->next; 40050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 40060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!retCode) return false; 40070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(tSize == OpndSize_32) return true; 40080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* check live ranges of the high half */ 40090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchMemTable(compileTable[k].regNum+1); 40100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) { 40110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("couldn't find VR %d in memTable", compileTable[k].regNum+1); 40120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 40130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 40140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = memVRTable[index].ranges; 40150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptr != NULL) { 40160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(offsetPC >= ptr->start && 40170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen offsetPC <= ptr->end) { 40180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptr->end == currentBB->pc_end) return true; 40190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 40200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 40210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptr->next; 40220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 40230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef PRINT_WARNING 40240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGW("offsetPC %d not in live range of VR %d", offsetPC, compileTable[k].regNum+1); 40250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 40260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 40270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 40280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 40290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!check whether the current bytecode is the next to last access to a VR within a live range 40300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 40310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!for 64 bit, return true if true for both low half and high half 40320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool isNextToLastAccess(int compileIndex) { 40330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k = compileIndex; 40340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen OpndSize tSize = getRegSize(compileTable[k].physicalType); 40350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index; 40360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* check live ranges for the low half */ 40370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool retCode = false; 40380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchMemTable(compileTable[k].regNum); 40390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) { 40400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("couldn't find VR %d in memTable", compileTable[k].regNum); 40410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 40420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 40430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LiveRange* ptr = memVRTable[index].ranges; 40440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptr != NULL) { 40450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int num_access = ptr->num_access; 40460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 40470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(num_access < 2) { 40480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptr->next; 40490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen continue; 40500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 40510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 40520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(offsetPC == ptr->accessPC[num_access-2]) { 40530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen retCode = true; 40540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 40550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 40560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptr->next; 40570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 40580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!retCode) return false; 40590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(tSize == OpndSize_32) return true; 40600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* check live ranges for the high half */ 40610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchMemTable(compileTable[k].regNum+1); 40620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) { 40630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("couldn't find VR %d in memTable", compileTable[k].regNum+1); 40640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 40650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 40660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = memVRTable[index].ranges; 40670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptr != NULL) { 40680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int num_access = ptr->num_access; 40690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 40700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(num_access < 2) { 40710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptr->next; 40720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen continue; 40730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 40740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 40750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(offsetPC == ptr->accessPC[num_access-2]) return true; 40760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptr->next; 40770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 40780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 40790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 40800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 40810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** return the start of the next live range 40820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if there does not exist a next live range, return pc_end of the basic block 40830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for 64 bits, return the larger one for low half and high half 40840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Assume live ranges are sorted in order 40850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 40860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint getNextLiveRange(int compileIndex) { 40870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k = compileIndex; 40880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen OpndSize tSize = getRegSize(compileTable[k].physicalType); 40890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* check live ranges of the low half */ 40900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index; 40910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchMemTable(compileTable[k].regNum); 40920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) { 40930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("couldn't find VR %d in memTable", compileTable[k].regNum); 40940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return offsetPC; 40950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 40960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool found = false; 40970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int nextUse = offsetPC; 40980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LiveRange* ptr = memVRTable[index].ranges; 40990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptr != NULL) { 41000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptr->start > offsetPC) { 41010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen nextUse = ptr->start; 41020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen found = true; 41030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 41040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 41050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptr->next; 41060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 41070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!found) return currentBB->pc_end; 41080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(tSize == OpndSize_32) return nextUse; 41090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 41100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* check live ranges of the high half */ 41110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen found = false; 41120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchMemTable(compileTable[k].regNum+1); 41130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) { 41140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("couldn't find VR %d in memTable", compileTable[k].regNum+1); 41150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return offsetPC; 41160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 41170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int nextUse2 = offsetPC; 41180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = memVRTable[index].ranges; 41190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptr != NULL) { 41200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptr->start > offsetPC) { 41210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen nextUse2 = ptr->start; 41220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen found = true; 41230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 41240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 41250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptr->next; 41260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 41270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!found) return currentBB->pc_end; 41280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* return the larger one */ 41290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return (nextUse2 > nextUse ? nextUse2 : nextUse); 41300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 41310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 41320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** return the next access to a variable 41330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen If variable is 64-bit, get the next access to the lower half and the high half 41340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return the eariler one 41350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 41360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint getNextAccess(int compileIndex) { 41370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k = compileIndex; 41380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen OpndSize tSize = getRegSize(compileTable[k].physicalType); 41390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index, k3; 41400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* check live ranges of the low half */ 41410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchMemTable(compileTable[k].regNum); 41420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) { 41430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("couldn't find VR %d in memTable", compileTable[k].regNum); 41440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return offsetPC; 41450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 41460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool found = false; 41470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int nextUse = offsetPC; 41480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen LiveRange* ptr = memVRTable[index].ranges; 41490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptr != NULL) { 41500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(offsetPC >= ptr->start && 41510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen offsetPC <= ptr->end) { 41520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* offsetPC belongs to this live range */ 41530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k3 = 0; k3 < ptr->num_access; k3++) { 41540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptr->accessPC[k3] > offsetPC) { 41550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen nextUse = ptr->accessPC[k3]; 41560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 41570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 41580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 41590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen found = true; 41600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 41610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 41620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptr->next; 41630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 41640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef PRINT_WARNING 41650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!found) 41660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGW("offsetPC %d not in live range of VR %d", offsetPC, compileTable[k].regNum); 41670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 41680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(tSize == OpndSize_32) return nextUse; 41690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 41700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* check live ranges of the high half */ 41710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen found = false; 41720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchMemTable(compileTable[k].regNum+1); 41730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) { 41740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("couldn't find VR %d in memTable", compileTable[k].regNum+1); 41750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return offsetPC; 41760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 41770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int nextUse2 = offsetPC; 41780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = memVRTable[index].ranges; 41790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(ptr != NULL) { 41800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(offsetPC >= ptr->start && 41810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen offsetPC <= ptr->end) { 41820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k3 = 0; k3 < ptr->num_access; k3++) { 41830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(ptr->accessPC[k3] > offsetPC) { 41840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen nextUse2 = ptr->accessPC[k3]; 41850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 41860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 41870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 41880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen found = true; 41890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 41900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 41910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ptr = ptr->next; 41920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 41930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef PRINT_WARNING 41940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!found) ALOGW("offsetPC %d not in live range of VR %d", offsetPC, compileTable[k].regNum+1); 41950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 41960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* return the earlier one */ 41970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(nextUse2 < nextUse) return nextUse2; 41980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return nextUse; 41990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 42000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 42010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** free variables that are no longer in use 42020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen free a temporary with reference count of zero 42030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen will dump content of a GL VR to memory if necessary 42040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 42050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint freeReg(bool spillGL) { 42060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB == NULL) return 0; 42070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 42080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_compile_entries; k++) { 42090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].refCount == 0 && compileTable[k].physicalReg != PhysicalReg_Null) { 42100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* check entries with reference count of zero and is mapped to a physical register */ 42110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool typeA = !isVirtualReg(compileTable[k].physicalType); 42120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool freeCrit = true, delayFreeing = false; 42130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool typeC = false, typeB = false, reachEnd = false; 42140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isVirtualReg(compileTable[k].physicalType)) { 42150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* VRs in the compile table */ 42160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 42170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* Check if delay for freeing was requested for this VR */ 42180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen delayFreeing = getVRFreeDelayRequested(compileTable[k].regNum); 42190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 42200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeCrit = isLastByteCodeOfLiveRange(k); /* last bytecode of a live range */ 42210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reachEnd = reachEndOfBB(k); /* in a live range that extends to end of a basic block */ 42220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_LIVE_RANGE 42230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("IN freeReg: VR %d offsetPC %x freecrit %d reachEnd %d nextToLast %d", compileTable[k].regNum, offsetPC, freeCrit, reachEnd, isNextToLastAccess(k)); 42240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 42250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* Bug: spilling of VRs after edi(rFP) is updated in RETURN bytecode 42260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen will cause variables for callee to be spilled to the caller stack frame and 42270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen to overwrite varaibles for caller 42280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 42290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* last bytecode of a live range reaching end of BB if not counting the fake usage at end */ 42300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool boolB = reachEnd && isNextToLastAccess(k); 42310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* Bug: when a GG VR is checked at end of a basic block, 42320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeCrit will be true and physicalReg will be set to Null 42330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen Fix: change free condition from freeCrit to (freeCrit && offsetPC != currentBB->pc_end) 42340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 42350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* conditions to free a GG VR: 42360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen last bytecode of a live range reaching end of BB if not counting the fake usage at end && endsWithReturn 42370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen or 42380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen last bytecode of a live range && offsetPC != currentBB->pc_end 42390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen -> last bytecode of a live range not reaching end 42400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 42410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typeC = ((freeCrit && offsetPC != currentBB->pc_end) || 42420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (currentBB->endsWithReturn && boolB)) && 42430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].gType == GLOBALTYPE_GG && 42440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen !delayFreeing; 42450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* conditions to free a L|GL VR: 42460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen last bytecode of a live range 42470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen or 42480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen last bytecode of a live range reaching end of BB if not counting the fake usage at end 42490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 42500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen typeB = (freeCrit || boolB) && 42510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen (compileTable[k].gType != GLOBALTYPE_GG) && 42520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen !delayFreeing; 42530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 42540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(typeA || typeB || typeC) { 42550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REGALLOC 42560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(typeA) 42570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("FREE TEMP %d with type %d allocated to %d", 42580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].regNum, compileTable[k].physicalType, 42590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].physicalReg); 42600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(typeB) 42610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("FREE VR L|GL %d with type %d allocated to %d", 42620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].regNum, compileTable[k].physicalType, 42630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].physicalReg); 42640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(typeC) 42650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("FREE VR GG %d with type %d allocated to %d", 42660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].regNum, compileTable[k].physicalType, 42670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].physicalReg); 42680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 42690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool dumpGL = false; 42700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].gType == GLOBALTYPE_GL && !reachEnd) { 42710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* if the live range does not reach end of basic block 42720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen and there exists a try block from offsetPC to the next live range 42730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dump VR to interpreted stack */ 42740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int tmpPC = getNextLiveRange(k); 42750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(existATryBlock(currentMethod, offsetPC, tmpPC)) dumpGL = true; 42760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 42770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* if the live range reach end of basic block, dump VR to interpreted stack */ 42780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].gType == GLOBALTYPE_GL && reachEnd) dumpGL = true; 42790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(dumpGL) { 42800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(spillGL) { 42810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REGALLOC 42820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("SPILL VR GL %d %d", compileTable[k].regNum, compileTable[k].physicalType); 42830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 42840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen spillLogicalReg(k, true); //will dump VR to memory & update physicalReg 42850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 42860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 42870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 42880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].physicalReg = PhysicalReg_Null; 42890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 42900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(typeA) { 42910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].spill_loc_index >= 0) { 42920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* update spill info for temporaries */ 42930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen spillIndexUsed[compileTable[k].spill_loc_index >> 2] = 0; 42940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].spill_loc_index = -1; 42950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("free a temporary register with TRSTATE_SPILLED"); 42960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 42970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 42980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 42990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 43000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen syncAllRegs(); //sync up allRegs (isUsed & freeTimeStamp) with compileTable 43010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 43020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 43030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 43040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! reduce the reference count by 1 43050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 43060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! input: index to compileTable 43070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid decreaseRefCount(int index) { 43080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REFCOUNT 43090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("REFCOUNT: %d in decreaseRefCount %d %d", compileTable[index].refCount, 43100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].regNum, compileTable[index].physicalType); 43110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 43120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].refCount--; 43130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[index].refCount < 0) { 43140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("refCount is negative for REG %d %d", compileTable[index].regNum, compileTable[index].physicalType); 43150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dvmAbort(); 43160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 43170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 43180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! reduce the reference count of a VR by 1 43190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 43200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! input: reg & type 43210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint updateRefCount(int reg, LowOpndRegType type) { 43220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB == NULL) return 0; 43230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index = searchCompileTable(LowOpndRegType_virtual | type, reg); 43240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) { 43250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("virtual reg %d type %d not found in updateRefCount", reg, type); 43260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return -1; 43270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 43280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen decreaseRefCount(index); 43290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 43300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 43310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! reduce the reference count of a variable by 1 43320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 43330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! The variable is named with lowering module's naming mechanism 43340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint updateRefCount2(int reg, int type, bool isPhysical) { 43350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB == NULL) return 0; 43360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int newType = convertType(type, reg, isPhysical); 43370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(newType & LowOpndRegType_scratch) reg = reg - PhysicalReg_SCRATCH_1 + 1; 43380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index = searchCompileTable(newType, reg); 43390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) { 43400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("reg %d type %d not found in updateRefCount", reg, newType); 43410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return -1; 43420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 43430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen decreaseRefCount(index); 43440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 43450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 43460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! check whether a glue variable is in physical register or spilled 43470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 43480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 43490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool isGlueHandled(int glue_reg) { 43500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB == NULL) return false; 43510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index = searchCompileTable(LowOpndRegType_gp, glue_reg); 43520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) { 43530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("glue reg %d not found in isGlueHandled", glue_reg); 43540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return -1; 43550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 43560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[index].spill_loc_index >= 0 || 43570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].physicalReg != PhysicalReg_Null) { 43580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_GLUE 43590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("GLUE isGlueHandled for %d returns true", glue_reg); 43600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 43610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return true; 43620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 43630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_GLUE 43640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("GLUE isGlueHandled for %d returns false", glue_reg); 43650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 43660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 43670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 43680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! reset the state of a glue variable to not existant (not in physical register nor spilled) 43690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 43700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 43710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid resetGlue(int glue_reg) { 43720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB == NULL) return; 43730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index = searchCompileTable(LowOpndRegType_gp, glue_reg); 43740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) { 43750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("glue reg %d not found in resetGlue", glue_reg); 43760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 43770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 43780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_GLUE 43790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("GLUE reset for %d", glue_reg); 43800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 43810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].physicalReg = PhysicalReg_Null; 43820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[index].spill_loc_index >= 0) 43830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen spillIndexUsed[compileTable[index].spill_loc_index >> 2] = 0; 43840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].spill_loc_index = -1; 43850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 43860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! set a glue variable in a physical register allocated for a variable 43870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 43880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! Variable is using lowering module's naming convention 43890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid updateGlue(int reg, bool isPhysical, int glue_reg) { 43900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB == NULL) return; 43910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index = searchCompileTable(LowOpndRegType_gp, glue_reg); 43920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) { 43930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("glue reg %d not found in updateGlue", glue_reg); 43940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 43950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 43960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* find the compileTable entry for variable <reg, isPhysical> */ 43970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int newType = convertType(LowOpndRegType_gp, reg, isPhysical); 43980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(newType & LowOpndRegType_scratch) reg = reg - PhysicalReg_SCRATCH_1 + 1; 43990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index2 = searchCompileTable(newType, reg); 44000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index2 < 0 || compileTable[index2].physicalReg == PhysicalReg_Null) { 44010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("updateGlue reg %d type %d", reg, newType); 44020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 44030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 44040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_GLUE 44050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("physical register for GLUE %d set to %d", glue_reg, compileTable[index2].physicalReg); 44060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 44070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].physicalReg = compileTable[index2].physicalReg; 44080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].spill_loc_index = -1; 44090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 44100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 44110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! check whether a virtual register is in a physical register 44120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 44130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! If updateRefCount is 0, do not update reference count; 44140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!If updateRefCount is 1, update reference count only when VR is in a physical register 44150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!If updateRefCount is 2, update reference count 44160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint checkVirtualReg(int reg, LowOpndRegType type, int updateRefCount) { 44170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB == NULL) return PhysicalReg_Null; 44180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index = searchCompileTable(LowOpndRegType_virtual | type, reg); 44190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) { 44200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("virtual reg %d type %d not found in checkVirtualReg", reg, type); 44210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return PhysicalReg_Null; 44220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 44230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //reduce reference count 44240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[index].physicalReg != PhysicalReg_Null) { 44250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(updateRefCount != 0) decreaseRefCount(index); 44260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return compileTable[index].physicalReg; 44270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 44280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(updateRefCount == 2) decreaseRefCount(index); 44290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return PhysicalReg_Null; 44300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 44310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!check whether a temporary can share the same physical register with a VR 44320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 44330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!This is called in get_virtual_reg 44340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!If this function returns false, new register will be allocated for this temporary 44350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool checkTempReg2(int reg, int type, bool isPhysical, int physicalRegForVR) { 44360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB == NULL) return false; 44370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isPhysical) return false; 44380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 44390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int newType = convertType(type, reg, isPhysical); 44400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(newType & LowOpndRegType_scratch) reg = reg - PhysicalReg_SCRATCH_1 + 1; 44410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 44420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_temp_regs_per_bytecode; k++) { 44430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(infoByteCodeTemp[k].physicalType == newType && 44440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen infoByteCodeTemp[k].regNum == reg) { 44450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_MOVE_OPT 44460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("MOVE_OPT checkTempRegs for %d %d returns %d %d", 44470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen reg, newType, infoByteCodeTemp[k].shareWithVR, infoByteCodeTemp[k].is8Bit); 44480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 44490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!infoByteCodeTemp[k].is8Bit) return infoByteCodeTemp[k].shareWithVR; 44500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //is8Bit true for gp type only 44510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!infoByteCodeTemp[k].shareWithVR) return false; 44520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //both true 44530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(physicalRegForVR >= PhysicalReg_EAX && physicalRegForVR <= PhysicalReg_EDX) return true; 44540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_MOVE_OPT 44550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("MOVE_OPT registerAllocMove not used for 8-bit register"); 44560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 44570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 44580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 44590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 44600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("checkTempReg2 %d %d", reg, newType); 44610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 44620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 44630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!check whether a temporary can share the same physical register with a VR 44640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 44650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!This is called in set_virtual_reg 44660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint checkTempReg(int reg, int type, bool isPhysical, int vrNum) { 44670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(currentBB == NULL) return PhysicalReg_Null; 44680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 44690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int newType = convertType(type, reg, isPhysical); 44700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(newType & LowOpndRegType_scratch) reg = reg - PhysicalReg_SCRATCH_1 + 1; 44710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index = searchCompileTable(newType, reg); 44720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) { 44730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("temp reg %d type %d not found in checkTempReg", reg, newType); 44740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return PhysicalReg_Null; 44750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 44760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 44770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //a temporary register can share the same physical reg with a VR if registerAllocMove is called 44780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //this will cause problem with move bytecode 44790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //get_VR(v1, t1) t1 and v1 point to the same physical reg 44800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //set_VR(t1, v2) t1 and v2 point to the same physical reg 44810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //this will cause v1 and v2 point to the same physical reg 44820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //FIX: if this temp reg shares a physical reg with another reg 44830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[index].physicalReg != PhysicalReg_Null) { 44840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 44850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_compile_entries; k++) { 44860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(k == index) continue; 44870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].physicalReg == compileTable[index].physicalReg) { 44880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return PhysicalReg_Null; //will allocate a register for VR 44890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 44900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 44910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen decreaseRefCount(index); 44920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return compileTable[index].physicalReg; 44930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 44940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[index].spill_loc_index >= 0) { 44950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //registerAlloc will call unspillLogicalReg (load from memory) 44960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REGALLOC 44970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGW("in checkTempReg, the temporary register %d %d was spilled", reg, type); 44980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 44990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regAll = registerAlloc(type, reg, isPhysical, true/* updateRefCount */); 45000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return regAll; 45010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 45020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return PhysicalReg_Null; 45030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 45040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!check whether a variable has exposed usage in a basic block 45050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 45060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!It calls hasExposedUsage2 45070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool hasExposedUsage(LowOpndRegType type, int regNum, BasicBlock_O1* bb) { 45080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index = searchVirtualInfoOfBB(type, regNum, bb); 45090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index >= 0 && hasExposedUsage2(bb, index)) { 45100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return true; 45110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 45120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 45130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 45140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!check whether a variable has exposed usage in other basic blocks 45150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 45160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 45170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool hasOtherExposedUsage(OpndSize size, int regNum, BasicBlock_O1* bb) { 45180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return true; //assume the worst case 45190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 45200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 45210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! handles constant VRs at end of a basic block 45220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 45230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!If a VR is constant at end of a basic block and (it has exposed usage in other basic blocks or reaches a GG VR), dump immediate to memory 45240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid constVREndOfBB() { 45250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen BasicBlock_O1* bb = currentBB; 45260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k, k2; 45270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //go through GG VRs, update a bool array 45280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int constUsedByGG[MAX_CONST_REG]; 45290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_const_vr; k++) 45300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen constUsedByGG[k] = 0; 45310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_compile_entries; k++) { 45320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isVirtualReg(compileTable[k].physicalType) && compileTable[k].gType == GLOBALTYPE_GG) { 45330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen OpndSize size = getRegSize(compileTable[k].physicalType); 45340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int regNum = compileTable[k].regNum; 45350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexL = -1; 45360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexH = -1; 45370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k2 = 0; k2 < num_const_vr; k2++) { 45380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(constVRTable[k2].regNum == regNum) { 45390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen indexL = k2; 45400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen continue; 45410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 45420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(constVRTable[k2].regNum == regNum + 1 && size == OpndSize_64) { 45430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen indexH = k2; 45440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen continue; 45450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 45460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 45470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexL >= 0) constUsedByGG[indexL] = 1; 45480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexH >= 0) constUsedByGG[indexH] = 1; 45490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } //GG VR 45500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 45510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_const_vr; k++) { 45520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!constVRTable[k].isConst) continue; 45530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool hasExp = false; 45540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(constUsedByGG[k] == 0) 45550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen hasExp = hasOtherExposedUsage(OpndSize_32, constVRTable[k].regNum, bb); 45560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(constUsedByGG[k] != 0 || hasExp) { 45570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpImmToMem(constVRTable[k].regNum, OpndSize_32, constVRTable[k].value); 45580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen setVRToMemory(constVRTable[k].regNum, OpndSize_32); 45590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_ENDOFBB 45600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("ENDOFBB: exposed VR %d is const %d (%x)", 45610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen constVRTable[k].regNum, constVRTable[k].value, constVRTable[k].value); 45620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 45630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 45640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_ENDOFBB 45650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("ENDOFBB: unexposed VR %d is const %d (%x)", 45660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen constVRTable[k].regNum, constVRTable[k].value, constVRTable[k].value); 45670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 45680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 45690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 45700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 45710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 45720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!handles GG VRs at end of a basic block 45730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 45740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!make sure all GG VRs are in pre-defined physical registers 45750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid globalVREndOfBB(const Method* method) { 45760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //fix: freeReg first to write LL VR back to memory to avoid it gets overwritten by GG VRs 45770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(true); 45780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 45790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //spill GG VR first if it is not mapped to the specific reg 45800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //release GLUE regs 45810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_compile_entries; k++) { 45820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].regNum >= PhysicalReg_GLUE_DVMDEX && 45830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].regNum != PhysicalReg_GLUE) { 45840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].physicalReg = PhysicalReg_Null; 45850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].spill_loc_index = -1; 45860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 45870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //if part of a GG VR is const, the physical reg is set to null 45880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isVirtualReg(compileTable[k].physicalType) && 45890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].gType == GLOBALTYPE_GG && compileTable[k].physicalReg != PhysicalReg_Null && 45900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].physicalReg != compileTable[k].physicalReg_prev) { 45910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_ENDOFBB 45920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGW("end of BB GG VR is not mapped to the specific reg: %d %d %d", 45930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].regNum, compileTable[k].physicalType, compileTable[k].physicalReg); 45940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGW("ENDOFBB SPILL VR %d %d", compileTable[k].regNum, compileTable[k].physicalType); 45950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 45960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen spillLogicalReg(k, true); //the next section will load VR from memory to the specific reg 45970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 45980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 45990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen syncAllRegs(); 46000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_compile_entries; k++) { 46010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isVirtualReg(compileTable[k].physicalType)) { 46020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].gType == GLOBALTYPE_GG && 46030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].physicalReg == PhysicalReg_Null && (!currentBB->endsWithReturn)) { 46040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_ENDOFBB 46050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("ENDOFBB GET GG VR %d %d to physical register %d", compileTable[k].regNum, 46060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].physicalType, compileTable[k].physicalReg_prev); 46070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 46080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].physicalReg = compileTable[k].physicalReg_prev; 46090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(allRegs[compileTable[k].physicalReg_prev].isUsed) { 46100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("physical register for GG VR is still used"); 46110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 46120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen get_virtual_reg_noalloc(compileTable[k].regNum, 46130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen getRegSize(compileTable[k].physicalType), 46140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].physicalReg_prev, 46150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen true); 46160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 46170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen }//not const 46180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 46190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexForGlue >= 0 && 46200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[indexForGlue].physicalReg == PhysicalReg_Null) { 46210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen unspillLogicalReg(indexForGlue, PhysicalReg_EBP); //load %ebp 46220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 46230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 46240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 46250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! get ready for the next version of a hard-coded register 46260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 46270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!set its physicalReg to Null and update its reference count 46280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint nextVersionOfHardReg(PhysicalReg pReg, int refCount) { 46290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int indexT = searchCompileTable(LowOpndRegType_gp | LowOpndRegType_hard, pReg); 46300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(indexT < 0) 46310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return -1; 46320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[indexT].physicalReg = PhysicalReg_Null; 46330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_REFCOUNT 46340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("REFCOUNT: to %d in nextVersionOfHardReg %d", refCount, pReg); 46350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 46360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[indexT].refCount = refCount; 46370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return 0; 46380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 46390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 46400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** update compileTable with bb->infoBasicBlock[k] 46410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 46420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid insertFromVirtualInfo(BasicBlock_O1* bb, int k) { 46430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index = searchCompileTable(LowOpndRegType_virtual | bb->infoBasicBlock[k].physicalType, bb->infoBasicBlock[k].regNum); 46440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) { 46450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* the virtual register is not in compileTable, insert it */ 46460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = num_compile_entries; 46470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[num_compile_entries].physicalType = (LowOpndRegType_virtual | bb->infoBasicBlock[k].physicalType); 46480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[num_compile_entries].regNum = bb->infoBasicBlock[k].regNum; 46490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[num_compile_entries].physicalReg = PhysicalReg_Null; 46500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[num_compile_entries].bb = bb; 46510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[num_compile_entries].indexToInfoBB = k; 46520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[num_compile_entries].spill_loc_index = -1; 46530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[num_compile_entries].gType = bb->infoBasicBlock[k].gType; 46540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_compile_entries++; 46550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(num_compile_entries >= COMPILE_TABLE_SIZE) { 46560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("compileTable overflow"); 46570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dvmAbort(); 46580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 46590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 46600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* re-set reference count of all VRs */ 46610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].refCount = bb->infoBasicBlock[k].refCount; 46620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].accessType = bb->infoBasicBlock[k].accessType; 46630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[index].gType == GLOBALTYPE_GG) 46640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].physicalReg_prev = bb->infoBasicBlock[k].physicalReg_GG; 46650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 46660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 46670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** update compileTable with infoByteCodeTemp[k] 46680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 46690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid insertFromTempInfo(int k) { 46700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index = searchCompileTable(infoByteCodeTemp[k].physicalType, infoByteCodeTemp[k].regNum); 46710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) { 46720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* the temporary is not in compileTable, insert it */ 46730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = num_compile_entries; 46740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[num_compile_entries].physicalType = infoByteCodeTemp[k].physicalType; 46750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[num_compile_entries].regNum = infoByteCodeTemp[k].regNum; 46760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_compile_entries++; 46770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(num_compile_entries >= COMPILE_TABLE_SIZE) { 46780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("compileTable overflow"); 46790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dvmAbort(); 46800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 46810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 46820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].physicalReg = PhysicalReg_Null; 46830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].refCount = infoByteCodeTemp[k].refCount; 46840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].linkageToVR = infoByteCodeTemp[k].linkageToVR; 46850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].gType = GLOBALTYPE_L; 46860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].spill_loc_index = -1; 46870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 46880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 46890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/* insert a glue-related register GLUE_DVMDEX to compileTable */ 46900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid insertGlueReg() { 46910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[num_compile_entries].physicalType = LowOpndRegType_gp; 46920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[num_compile_entries].regNum = PhysicalReg_GLUE_DVMDEX; 46930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[num_compile_entries].refCount = 2; 46940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[num_compile_entries].physicalReg = PhysicalReg_Null; 46950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[num_compile_entries].bb = NULL; 46960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[num_compile_entries].spill_loc_index = -1; 46970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[num_compile_entries].accessType = REGACCESS_N; 46980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[num_compile_entries].linkageToVR = -1; 46990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[num_compile_entries].gType = GLOBALTYPE_L; 47000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 47010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_compile_entries++; 47020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(num_compile_entries >= COMPILE_TABLE_SIZE) { 47030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("compileTable overflow"); 47040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dvmAbort(); 47050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 47060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 47070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 47080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** print infoBasicBlock of the given basic block 47090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 47100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid dumpVirtualInfoOfBasicBlock(BasicBlock_O1* bb) { 47110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int jj; 47120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("Virtual Info for BB%d --------", bb->bb_index); 47130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(jj = 0; jj < bb->num_regs; jj++) { 47140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("regNum %d physicalType %d accessType %d refCount %d def ", 47150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->infoBasicBlock[jj].regNum, bb->infoBasicBlock[jj].physicalType, 47160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->infoBasicBlock[jj].accessType, bb->infoBasicBlock[jj].refCount); 47170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 47180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < bb->infoBasicBlock[jj].num_reaching_defs; k++) 47190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("[%x %d %d %d] ", bb->infoBasicBlock[jj].reachingDefs[k].offsetPC, 47200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->infoBasicBlock[jj].reachingDefs[k].regNum, 47210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->infoBasicBlock[jj].reachingDefs[k].physicalType, 47220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->infoBasicBlock[jj].reachingDefs[k].accessType); 47230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI(""); 47240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 47250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 47260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 47270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/** print compileTable 47280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen*/ 47290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid dumpCompileTable() { 47300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int jj; 47310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("Compile Table for method ----------"); 47320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(jj = 0; jj < num_compile_entries; jj++) { 47330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("regNum %d physicalType %d refCount %d isConst %d physicalReg %d type %d", 47340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[jj].regNum, compileTable[jj].physicalType, 47350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[jj].refCount, compileTable[jj].isConst, compileTable[jj].physicalReg, compileTable[jj].gType); 47360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 47370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 47380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 47390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!check whether a basic block is the start of an exception handler 47400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 47410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 47420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool isFirstOfHandler(BasicBlock_O1* bb) { 47430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int i; 47440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(i = 0; i < num_exception_handlers; i++) { 47450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(bb->pc_start == exceptionHandlers[i]) return true; 47460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 47470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return false; 47480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 47490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 47500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! create a basic block that starts at src_pc and ends at end_pc 47510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 47520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 47530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenBasicBlock_O1* createBasicBlock(int src_pc, int end_pc) { 47540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen BasicBlock_O1* bb = (BasicBlock_O1*)malloc(sizeof(BasicBlock_O1)); 47550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(bb == NULL) { 47560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("out of memory"); 47570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return NULL; 47580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 47590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->pc_start = src_pc; 47600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bb->bb_index = num_bbs_for_method; 47610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(bb_entry == NULL) bb_entry = bb; 47620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 47630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* insert the basic block to method_bbs_sorted in ascending order of pc_start */ 47640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 47650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index = -1; 47660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_bbs_for_method; k++) 47670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(method_bbs_sorted[k]->pc_start > src_pc) { 47680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = k; 47690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 47700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 47710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index == -1) 47720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen method_bbs_sorted[num_bbs_for_method] = bb; 47730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else { 47740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* push the elements from index by 1 */ 47750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = num_bbs_for_method-1; k >= index; k--) 47760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen method_bbs_sorted[k+1] = method_bbs_sorted[k]; 47770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen method_bbs_sorted[index] = bb; 47780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 47790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_bbs_for_method++; 47800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(num_bbs_for_method >= MAX_NUM_BBS_PER_METHOD) { 47810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("too many basic blocks"); 47820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dvmAbort(); 47830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 47840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return bb; 47850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 47860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 47870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/* BEGIN code to handle state transfers */ 47880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! save the current state of register allocator to a state table 47890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 47900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 47910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid rememberState(int stateNum) { 47920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_STATE 47930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("STATE: remember state %d", stateNum); 47940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 47950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 47960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_compile_entries; k++) { 47970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(stateNum == 1) { 47980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stateTable1_1[k].physicalReg = compileTable[k].physicalReg; 47990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stateTable1_1[k].spill_loc_index = compileTable[k].spill_loc_index; 48000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 48010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(stateNum == 2) { 48020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stateTable1_2[k].physicalReg = compileTable[k].physicalReg; 48030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stateTable1_2[k].spill_loc_index = compileTable[k].spill_loc_index; 48040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 48050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(stateNum == 3) { 48060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stateTable1_3[k].physicalReg = compileTable[k].physicalReg; 48070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stateTable1_3[k].spill_loc_index = compileTable[k].spill_loc_index; 48080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 48090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(stateNum == 4) { 48100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stateTable1_4[k].physicalReg = compileTable[k].physicalReg; 48110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stateTable1_4[k].spill_loc_index = compileTable[k].spill_loc_index; 48120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 48130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else ALOGE("state table overflow"); 48140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_STATE 48150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("logical reg %d %d mapped to physical reg %d with spill index %d refCount %d", 48160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].regNum, compileTable[k].physicalType, compileTable[k].physicalReg, 48170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].spill_loc_index, compileTable[k].refCount); 48180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 48190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 48200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_memory_vr; k++) { 48210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(stateNum == 1) { 48220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stateTable2_1[k].regNum = memVRTable[k].regNum; 48230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stateTable2_1[k].inMemory = memVRTable[k].inMemory; 48240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 48250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(stateNum == 2) { 48260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stateTable2_2[k].regNum = memVRTable[k].regNum; 48270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stateTable2_2[k].inMemory = memVRTable[k].inMemory; 48280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 48290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(stateNum == 3) { 48300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stateTable2_3[k].regNum = memVRTable[k].regNum; 48310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stateTable2_3[k].inMemory = memVRTable[k].inMemory; 48320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 48330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(stateNum == 4) { 48340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stateTable2_4[k].regNum = memVRTable[k].regNum; 48350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stateTable2_4[k].inMemory = memVRTable[k].inMemory; 48360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 48370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else ALOGE("state table overflow"); 48380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_STATE 48390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("virtual reg %d in memory %d", memVRTable[k].regNum, memVRTable[k].inMemory); 48400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 48410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 48420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 48430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 48440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//!update current state of register allocator with a state table 48450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 48460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 48470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid goToState(int stateNum) { 48480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 48490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_STATE 48500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("STATE: go to state %d", stateNum); 48510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 48520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_compile_entries; k++) { 48530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(stateNum == 1) { 48540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].physicalReg = stateTable1_1[k].physicalReg; 48550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].spill_loc_index = stateTable1_1[k].spill_loc_index; 48560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 48570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(stateNum == 2) { 48580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].physicalReg = stateTable1_2[k].physicalReg; 48590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].spill_loc_index = stateTable1_2[k].spill_loc_index; 48600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 48610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(stateNum == 3) { 48620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].physicalReg = stateTable1_3[k].physicalReg; 48630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].spill_loc_index = stateTable1_3[k].spill_loc_index; 48640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 48650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(stateNum == 4) { 48660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].physicalReg = stateTable1_4[k].physicalReg; 48670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].spill_loc_index = stateTable1_4[k].spill_loc_index; 48680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 48690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else ALOGE("state table overflow"); 48700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 48710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen updateSpillIndexUsed(); 48720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen syncAllRegs(); //to sync up allRegs CAN'T call freeReg here 48730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //since it will change the state!!! 48740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_memory_vr; k++) { 48750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(stateNum == 1) { 48760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[k].regNum = stateTable2_1[k].regNum; 48770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[k].inMemory = stateTable2_1[k].inMemory; 48780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 48790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(stateNum == 2) { 48800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[k].regNum = stateTable2_2[k].regNum; 48810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[k].inMemory = stateTable2_2[k].inMemory; 48820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 48830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(stateNum == 3) { 48840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[k].regNum = stateTable2_3[k].regNum; 48850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[k].inMemory = stateTable2_3[k].inMemory; 48860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 48870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(stateNum == 4) { 48880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[k].regNum = stateTable2_4[k].regNum; 48890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen memVRTable[k].inMemory = stateTable2_4[k].inMemory; 48900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 48910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else ALOGE("state table overflow"); 48920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 48930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 48940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chentypedef struct TransferOrder { 48950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int targetReg; 48960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int targetSpill; 48970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int compileIndex; 48980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} TransferOrder; 48990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#define MAX_NUM_DEST 20 49000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! a source register is used as a source in transfer 49010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! it can have a maximum of MAX_NUM_DEST destinations 49020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chentypedef struct SourceReg { 49030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int physicalReg; 49040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int num_dests; //check bound 49050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen TransferOrder dsts[MAX_NUM_DEST]; 49060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} SourceReg; 49070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint num_src_regs = 0; //check bound 49080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! physical registers that are used as a source in transfer 49090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! we allow a maximum of MAX_NUM_DEST sources in a transfer 49100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan ChenSourceReg srcRegs[MAX_NUM_DEST]; 49110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! tell us whether a source register is handled already 49120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool handledSrc[MAX_NUM_DEST]; 49130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! in what order should the source registers be handled 49140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenint handledOrder[MAX_NUM_DEST]; 49150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! insert a source register with a single destination 49160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 49170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 49180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid insertSrcReg(int srcPhysical, int targetReg, int targetSpill, int index) { 49190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k = 0; 49200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_src_regs; k++) { 49210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(srcRegs[k].physicalReg == srcPhysical) { //increase num_dests 49220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(srcRegs[k].num_dests >= MAX_NUM_DEST) { 49230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("exceed number dst regs for a source reg"); 49240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dvmAbort(); 49250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 49260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen srcRegs[k].dsts[srcRegs[k].num_dests].targetReg = targetReg; 49270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen srcRegs[k].dsts[srcRegs[k].num_dests].targetSpill = targetSpill; 49280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen srcRegs[k].dsts[srcRegs[k].num_dests].compileIndex = index; 49290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen srcRegs[k].num_dests++; 49300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return; 49310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 49320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 49330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(num_src_regs >= MAX_NUM_DEST) { 49340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("exceed number of source regs"); 49350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dvmAbort(); 49360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 49370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen srcRegs[num_src_regs].physicalReg = srcPhysical; 49380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen srcRegs[num_src_regs].num_dests = 1; 49390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen srcRegs[num_src_regs].dsts[0].targetReg = targetReg; 49400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen srcRegs[num_src_regs].dsts[0].targetSpill = targetSpill; 49410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen srcRegs[num_src_regs].dsts[0].compileIndex = index; 49420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_src_regs++; 49430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 49440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! check whether a register is a source and the source is not yet handled 49450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 49460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 49470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenbool dstStillInUse(int dstReg) { 49480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(dstReg == PhysicalReg_Null) return false; 49490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 49500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index = -1; 49510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_src_regs; k++) { 49520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(dstReg == srcRegs[k].physicalReg) { 49530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = k; 49540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 49550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 49560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 49570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index < 0) return false; //not in use 49580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(handledSrc[index]) return false; //not in use 49590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen return true; 49600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 49610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! reset the state of glue variables in a state table 49620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 49630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 49640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid resetStateOfGlue(int stateNum, int k) { 49650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_STATE 49660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("resetStateOfGlue state %d regNum %d", stateNum, compileTable[k].regNum); 49670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 49680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(stateNum == 1) { 49690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stateTable1_1[k].physicalReg = PhysicalReg_Null; 49700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stateTable1_1[k].spill_loc_index = -1; 49710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 49720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(stateNum == 2) { 49730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stateTable1_2[k].physicalReg = PhysicalReg_Null; 49740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stateTable1_2[k].spill_loc_index = -1; 49750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 49760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(stateNum == 3) { 49770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stateTable1_3[k].physicalReg = PhysicalReg_Null; 49780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stateTable1_3[k].spill_loc_index = -1; 49790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 49800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(stateNum == 4) { 49810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stateTable1_4[k].physicalReg = PhysicalReg_Null; 49820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen stateTable1_4[k].spill_loc_index = -1; 49830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 49840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 49850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! construct a legal order of the source registers in this transfer 49860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 49870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 49880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid constructSrcRegs(int stateNum) { 49890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 49900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_src_regs = 0; 49910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_STATE 49920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("IN constructSrcRegs"); 49930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 49940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 49950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_compile_entries; k++) { 49960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_STATE 49970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("logical reg %d %d mapped to physical reg %d with spill index %d refCount %d", 49980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].regNum, compileTable[k].physicalType, compileTable[k].physicalReg, 49990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].spill_loc_index, compileTable[k].refCount); 50000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 50010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 50020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int pType = compileTable[k].physicalType; 50030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //ignore hardcoded logical registers 50040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((pType & LowOpndRegType_hard) != 0) continue; 50050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //ignore type _fs 50060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((pType & MASK_FOR_TYPE) == LowOpndRegType_fs) continue; 50070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((pType & MASK_FOR_TYPE) == LowOpndRegType_fs_s) continue; 50080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 50090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //GL VR refCount is zero, can't ignore 50100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //L VR refCount is zero, ignore 50110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //GG VR refCount is zero, can't ignore 50120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //temporary refCount is zero, ignore 50130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 50140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //for GLUE variables, if they do not exist, reset the entries in state table 50150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].physicalReg == PhysicalReg_Null && 50160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].regNum >= PhysicalReg_GLUE_DVMDEX && 50170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].regNum != PhysicalReg_GLUE && 50180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].spill_loc_index < 0) { 50190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen resetStateOfGlue(stateNum, k); 50200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 50210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 50220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* get the target state */ 50230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int targetReg = PhysicalReg_Null; 50240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int targetSpill = -1; 50250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(stateNum == 1) { 50260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen targetReg = stateTable1_1[k].physicalReg; 50270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen targetSpill = stateTable1_1[k].spill_loc_index; 50280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 50290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(stateNum == 2) { 50300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen targetReg = stateTable1_2[k].physicalReg; 50310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen targetSpill = stateTable1_2[k].spill_loc_index; 50320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 50330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(stateNum == 3) { 50340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen targetReg = stateTable1_3[k].physicalReg; 50350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen targetSpill = stateTable1_3[k].spill_loc_index; 50360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 50370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(stateNum == 4) { 50380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen targetReg = stateTable1_4[k].physicalReg; 50390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen targetSpill = stateTable1_4[k].spill_loc_index; 50400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 50410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 50420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* there exists an ordering problem 50430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for example: 50440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for a VR, move from memory to a physical reg esi 50450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for a temporary regsiter, from esi to ecx 50460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if we handle VR first, content of the temporary reg. will be overwritten 50470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen there are 4 cases: 50480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen I: a variable is currently in memory and its target is in physical reg 50490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen II: a variable is currently in a register and its target is in memory 50500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen III: a variable is currently in a different register 50510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen IV: a variable is currently in a different memory location (for non-VRs) 50520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for GLUE, since it can only be allocated to %ebp, we don't have case III 50530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen For now, case IV is not handled since it didn't show 50540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen */ 50550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].physicalReg != targetReg && 50560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen isVirtualReg(compileTable[k].physicalType)) { 50570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* handles VR for case I to III */ 50580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 50590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].physicalReg == PhysicalReg_Null && targetReg != PhysicalReg_Null) { 50600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* handles VR for case I: 50610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insert a xfer order from PhysicalReg_Null to targetReg */ 50620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertSrcReg(PhysicalReg_Null, targetReg, targetSpill, k); 50630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_STATE 50640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("insert for VR Null %d %d %d", targetReg, targetSpill, k); 50650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 50660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 50670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 50680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].physicalReg != PhysicalReg_Null && targetReg != PhysicalReg_Null) { 50690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* handles VR for case III 50700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insert a xfer order from srcReg to targetReg */ 50710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertSrcReg(compileTable[k].physicalReg, targetReg, targetSpill, k); 50720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 50730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 50740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].physicalReg != PhysicalReg_Null && targetReg == PhysicalReg_Null) { 50750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* handles VR for case II 50760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insert a xfer order from srcReg to memory */ 50770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertSrcReg(compileTable[k].physicalReg, targetReg, targetSpill, k); 50780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 50790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 50800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 50810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].physicalReg != targetReg && 50820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen !isVirtualReg(compileTable[k].physicalType)) { 50830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* handles non-VR for case I to III */ 50840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 50850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].physicalReg == PhysicalReg_Null && targetReg != PhysicalReg_Null) { 50860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* handles non-VR for case I */ 50870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].spill_loc_index < 0) { 50880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* this variable is freed, no need to transfer */ 50890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_STATE 50900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGW("in transferToState spill_loc_index is negative for temporary %d", compileTable[k].regNum); 50910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 50920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 50930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* insert a xfer order from memory to targetReg */ 50940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_STATE 50950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("insert Null %d %d %d", targetReg, targetSpill, k); 50960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 50970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertSrcReg(PhysicalReg_Null, targetReg, targetSpill, k); 50980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 50990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 51000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 51010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].physicalReg != PhysicalReg_Null && targetReg != PhysicalReg_Null) { 51020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* handles non-VR for case III 51030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insert a xfer order from srcReg to targetReg */ 51040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertSrcReg(compileTable[k].physicalReg, targetReg, targetSpill, k); 51050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 51060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 51070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].physicalReg != PhysicalReg_Null && targetReg == PhysicalReg_Null) { 51080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* handles non-VR for case II */ 51090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(targetSpill < 0) { 51100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* this variable is freed, no need to transfer */ 51110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_STATE 51120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGW("in transferToState spill_loc_index is negative for temporary %d", compileTable[k].regNum); 51130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 51140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 51150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* insert a xfer order from srcReg to memory */ 51160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen insertSrcReg(compileTable[k].physicalReg, targetReg, targetSpill, k); 51170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 51180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 51190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 51200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 51210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen }//for compile entries 51220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 51230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k2; 51240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_STATE 51250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_src_regs; k++) { 51260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("SRCREG %d: ", srcRegs[k].physicalReg); 51270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k2 = 0; k2 < srcRegs[k].num_dests; k2++) { 51280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index = srcRegs[k].dsts[k2].compileIndex; 51290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("[%d %d %d: %d %d %d] ", srcRegs[k].dsts[k2].targetReg, 51300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen srcRegs[k].dsts[k2].targetSpill, srcRegs[k].dsts[k2].compileIndex, 51310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].regNum, compileTable[index].physicalType, 51320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[index].spill_loc_index); 51330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 51340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI(""); 51350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 51360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 51370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 51380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen /* construct an order: xfers from srcReg first, then xfers from memory */ 51390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int num_handled = 0; 51400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int num_in_order = 0; 51410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_src_regs; k++) { 51420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(srcRegs[k].physicalReg == PhysicalReg_Null) { 51430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen handledSrc[k] = true; 51440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_handled++; 51450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } else { 51460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen handledSrc[k] = false; 51470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 51480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 51490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen while(num_handled < num_src_regs) { 51500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int prev_handled = num_handled; 51510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_src_regs; k++) { 51520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(handledSrc[k]) continue; 51530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool canHandleNow = true; 51540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k2 = 0; k2 < srcRegs[k].num_dests; k2++) { 51550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(dstStillInUse(srcRegs[k].dsts[k2].targetReg)) { 51560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen canHandleNow = false; 51570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen break; 51580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 51590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 51600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(canHandleNow) { 51610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen handledSrc[k] = true; 51620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_handled++; 51630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen handledOrder[num_in_order] = k; 51640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_in_order++; 51650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 51660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } //for k 51670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(num_handled == prev_handled) { 51680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("no progress in selecting order"); 51690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dvmAbort(); 51700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 51710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } //while 51720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_src_regs; k++) { 51730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(srcRegs[k].physicalReg == PhysicalReg_Null) { 51740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen handledOrder[num_in_order] = k; 51750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen num_in_order++; 51760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 51770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 51780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(num_in_order != num_src_regs) { 51790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("num_in_order != num_src_regs"); 51800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dvmAbort(); 51810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 51820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_STATE 51830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("ORDER: "); 51840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_src_regs; k++) { 51850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("%d ", handledOrder[k]); 51860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 51870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI(""); 51880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 51890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 51900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! transfer the state of register allocator to a state specified in a state table 51910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen 51920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen//! 51930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chenvoid transferToState(int stateNum) { 51940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen freeReg(false); //do not spill GL 51950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k; 51960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_STATE 51970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("STATE: transfer to state %d", stateNum); 51980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 51990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(stateNum > 4 || stateNum < 1) ALOGE("state table overflow"); 52000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen constructSrcRegs(stateNum); 52010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k4, k3; 52020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k4 = 0; k4 < num_src_regs; k4++) { 52030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int k2 = handledOrder[k4]; //index to srcRegs 52040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k3 = 0; k3 < srcRegs[k2].num_dests; k3++) { 52050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen k = srcRegs[k2].dsts[k3].compileIndex; 52060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int targetReg = srcRegs[k2].dsts[k3].targetReg; 52070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int targetSpill = srcRegs[k2].dsts[k3].targetSpill; 52080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].physicalReg != targetReg && isVirtualReg(compileTable[k].physicalType)) { 52090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen OpndSize oSize = getRegSize(compileTable[k].physicalType); 52100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool isSS = ((compileTable[k].physicalType & MASK_FOR_TYPE) == LowOpndRegType_ss); 52110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].physicalReg == PhysicalReg_Null && targetReg != PhysicalReg_Null) { 52120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(isSS) 52130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_ss_mem_to_reg_noalloc(4*compileTable[k].regNum, 52140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen PhysicalReg_FP, true, 52150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, compileTable[k].regNum, 52160c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen targetReg, true); 52170c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else 52180c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_mem_to_reg_noalloc(oSize, 4*compileTable[k].regNum, 52190c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen PhysicalReg_FP, true, 52200c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen MemoryAccess_VR, compileTable[k].regNum, 52210c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen targetReg, true); 52220c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 52230c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].physicalReg != PhysicalReg_Null && targetReg != PhysicalReg_Null) { 52240c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_reg_noalloc((isSS ? OpndSize_64 : oSize), 52250c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].physicalReg, true, 52260c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen targetReg, true); 52270c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 52280c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].physicalReg != PhysicalReg_Null && targetReg == PhysicalReg_Null) { 52290c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpToMem(compileTable[k].regNum, (LowOpndRegType)(compileTable[k].physicalType & MASK_FOR_TYPE), 52300c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].physicalReg); 52310c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 52320c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } //VR 52330c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].physicalReg != targetReg && !isVirtualReg(compileTable[k].physicalType)) { 52340c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen OpndSize oSize = getRegSize(compileTable[k].physicalType); 52350c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].physicalReg == PhysicalReg_Null && targetReg != PhysicalReg_Null) { 52360c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen loadFromSpillRegion(oSize, targetReg, 52370c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen compileTable[k].spill_loc_index); 52380c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 52390c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //both are not null, move from one to the other 52400c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].physicalReg != PhysicalReg_Null && targetReg != PhysicalReg_Null) { 52410c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen move_reg_to_reg_noalloc(oSize, compileTable[k].physicalReg, true, 52420c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen targetReg, true); 52430c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 52440c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //current is not null, target is null (move from reg to memory) 52450c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(compileTable[k].physicalReg != PhysicalReg_Null && targetReg == PhysicalReg_Null) { 52460c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen saveToSpillRegion(oSize, compileTable[k].physicalReg, targetSpill); 52470c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 52480c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } //temporary 52490c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen }//for 52500c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen }//for 52510c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen for(k = 0; k < num_memory_vr; k++) { 52520c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool targetBool = false; 52530c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int targetReg = -1; 52540c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(stateNum == 1) { 52550c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen targetReg = stateTable2_1[k].regNum; 52560c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen targetBool = stateTable2_1[k].inMemory; 52570c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 52580c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(stateNum == 2) { 52590c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen targetReg = stateTable2_2[k].regNum; 52600c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen targetBool = stateTable2_2[k].inMemory; 52610c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 52620c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(stateNum == 3) { 52630c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen targetReg = stateTable2_3[k].regNum; 52640c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen targetBool = stateTable2_3[k].inMemory; 52650c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 52660c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen else if(stateNum == 4) { 52670c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen targetReg = stateTable2_4[k].regNum; 52680c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen targetBool = stateTable2_4[k].inMemory; 52690c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 52700c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(targetReg != memVRTable[k].regNum) 52710c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGE("regNum mismatch in transferToState"); 52720c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(targetBool && (!memVRTable[k].inMemory)) { 52730c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //dump to memory, check entries in compileTable: vA gp vA xmm vA ss 52740c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_STATE 52750c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGW("inMemory mismatch for VR %d in transferToState", targetReg); 52760c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 52770c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen bool doneXfer = false; 52780c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen int index = searchCompileTable(LowOpndRegType_xmm | LowOpndRegType_virtual, targetReg); 52790c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) { 52800c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpToMem(targetReg, LowOpndRegType_xmm, compileTable[index].physicalReg); 52810c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen doneXfer = true; 52820c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 52830c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!doneXfer) { //vA-1, xmm 52840c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchCompileTable(LowOpndRegType_xmm | LowOpndRegType_virtual, targetReg-1); 52850c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) { 52860c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpToMem(targetReg-1, LowOpndRegType_xmm, compileTable[index].physicalReg); 52870c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen doneXfer = true; 52880c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 52890c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 52900c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!doneXfer) { //vA gp 52910c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchCompileTable(LowOpndRegType_gp | LowOpndRegType_virtual, targetReg); 52920c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) { 52930c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpToMem(targetReg, LowOpndRegType_gp, compileTable[index].physicalReg); 52940c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen doneXfer = true; 52950c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 52960c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 52970c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!doneXfer) { //vA, ss 52980c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen index = searchCompileTable(LowOpndRegType_ss | LowOpndRegType_virtual, targetReg); 52990c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(index >= 0 && compileTable[index].physicalReg != PhysicalReg_Null) { 53000c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen dumpToMem(targetReg, LowOpndRegType_ss, compileTable[index].physicalReg); 53010c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen doneXfer = true; 53020c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 53030c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 53040c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if(!doneXfer) ALOGW("can't match inMemory of VR %d in transferToState", targetReg); 53050c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 53060c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen if((!targetBool) && memVRTable[k].inMemory) { 53070c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen //do nothing 53080c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 53090c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen } 53100c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#ifdef DEBUG_STATE 53110c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen ALOGI("END transferToState %d", stateNum); 53120c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen#endif 53130c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen goToState(stateNum); 53140c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen} 53150c2dc522d0e120f346cf0a40c8cf0c93346131c2Dong-Yuan Chen/* END code to handle state transfers */ 5316