CompilerIR.h revision 0c2dc522d0e120f346cf0a40c8cf0c93346131c2
1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef DALVIK_VM_COMPILER_IR_H_ 18#define DALVIK_VM_COMPILER_IR_H_ 19 20#include "codegen/Optimizer.h" 21#ifdef ARCH_IA32 22#include "CompilerUtility.h" 23#endif 24 25typedef enum RegisterClass { 26 kCoreReg, 27 kFPReg, 28 kAnyReg, 29} RegisterClass; 30 31typedef enum RegLocationType { 32 kLocDalvikFrame = 0, 33 kLocPhysReg, 34 kLocRetval, // Return region in interpState 35 kLocSpill, 36} RegLocationType; 37 38typedef struct RegLocation { 39 RegLocationType location:2; 40 unsigned wide:1; 41 unsigned fp:1; // Hint for float/double 42 u1 lowReg:6; // First physical register 43 u1 highReg:6; // 2nd physical register (if wide) 44 s2 sRegLow; // SSA name for low Dalvik word 45} RegLocation; 46 47#define INVALID_SREG (-1) 48#define INVALID_REG (0x3F) 49 50typedef enum BBType { 51 /* For coding convenience reasons chaining cell types should appear first */ 52 kChainingCellNormal = 0, 53 kChainingCellHot, 54 kChainingCellInvokeSingleton, 55 kChainingCellInvokePredicted, 56 kChainingCellBackwardBranch, 57 kChainingCellGap, 58 /* Don't insert new fields between Gap and Last */ 59 kChainingCellLast = kChainingCellGap + 1, 60 kEntryBlock, 61 kDalvikByteCode, 62 kExitBlock, 63 kPCReconstruction, 64 kExceptionHandling, 65 kCatchEntry, 66} BBType; 67 68typedef enum JitMode { 69 kJitTrace = 0, // Acyclic - all instructions come from the trace descriptor 70 kJitLoop, // Cycle - trace descriptor is used as a hint 71 kJitMethod, // Whole method 72} JitMode; 73 74typedef struct ChainCellCounts { 75 union { 76 u1 count[kChainingCellLast]; /* include one more space for the gap # */ 77 u4 dummyForAlignment; 78 } u; 79} ChainCellCounts; 80 81typedef struct LIR { 82 int offset; 83 struct LIR *next; 84 struct LIR *prev; 85 struct LIR *target; 86} LIR; 87 88enum ExtendedMIROpcode { 89 kMirOpFirst = kNumPackedOpcodes, 90 kMirOpPhi = kMirOpFirst, 91 kMirOpNullNRangeUpCheck, 92 kMirOpNullNRangeDownCheck, 93 kMirOpLowerBound, 94 kMirOpPunt, 95 kMirOpCheckInlinePrediction, // Gen checks for predicted inlining 96 kMirOpLast, 97}; 98 99struct SSARepresentation; 100 101typedef enum { 102 kMIRIgnoreNullCheck = 0, 103 kMIRNullCheckOnly, 104 kMIRIgnoreRangeCheck, 105 kMIRRangeCheckOnly, 106 kMIRInlined, // Invoke is inlined (ie dead) 107 kMIRInlinedPred, // Invoke is inlined via prediction 108 kMIRCallee, // Instruction is inlined from callee 109 kMIRInvokeMethodJIT, // Callee is JIT'ed as a whole method 110} MIROptimizationFlagPositons; 111 112#define MIR_IGNORE_NULL_CHECK (1 << kMIRIgnoreNullCheck) 113#define MIR_NULL_CHECK_ONLY (1 << kMIRNullCheckOnly) 114#define MIR_IGNORE_RANGE_CHECK (1 << kMIRIgnoreRangeCheck) 115#define MIR_RANGE_CHECK_ONLY (1 << kMIRRangeCheckOnly) 116#define MIR_INLINED (1 << kMIRInlined) 117#define MIR_INLINED_PRED (1 << kMIRInlinedPred) 118#define MIR_CALLEE (1 << kMIRCallee) 119#define MIR_INVOKE_METHOD_JIT (1 << kMIRInvokeMethodJIT) 120 121typedef struct CallsiteInfo { 122 const char *classDescriptor; 123 Object *classLoader; 124 const Method *method; 125 LIR *misPredBranchOver; 126} CallsiteInfo; 127 128typedef struct MIR { 129 DecodedInstruction dalvikInsn; 130 unsigned int width; 131 unsigned int offset; 132 struct MIR *prev; 133 struct MIR *next; 134 struct SSARepresentation *ssaRep; 135 int OptimizationFlags; 136 int seqNum; 137 union { 138 // Used by the inlined insn from the callee to find the mother method 139 const Method *calleeMethod; 140 // Used by the inlined invoke to find the class and method pointers 141 CallsiteInfo *callsiteInfo; 142 } meta; 143} MIR; 144 145struct BasicBlockDataFlow; 146 147/* For successorBlockList */ 148typedef enum BlockListType { 149 kNotUsed = 0, 150 kCatch, 151 kPackedSwitch, 152 kSparseSwitch, 153} BlockListType; 154 155typedef struct BasicBlock { 156 int id; 157 bool visited; 158 bool hidden; 159 unsigned int startOffset; 160 const Method *containingMethod; // For blocks from the callee 161 BBType blockType; 162 bool needFallThroughBranch; // For blocks ended due to length limit 163 bool isFallThroughFromInvoke; // True means the block needs alignment 164 MIR *firstMIRInsn; 165 MIR *lastMIRInsn; 166 struct BasicBlock *fallThrough; 167 struct BasicBlock *taken; 168 struct BasicBlock *iDom; // Immediate dominator 169 struct BasicBlockDataFlow *dataFlowInfo; 170 BitVector *predecessors; 171 BitVector *dominators; 172 BitVector *iDominated; // Set nodes being immediately dominated 173 BitVector *domFrontier; // Dominance frontier 174 struct { // For one-to-many successors like 175 BlockListType blockListType; // switch and exception handling 176 GrowableList blocks; 177 } successorBlockList; 178} BasicBlock; 179 180/* 181 * The "blocks" field in "successorBlockList" points to an array of 182 * elements with the type "SuccessorBlockInfo". 183 * For catch blocks, key is type index for the exception. 184 * For swtich blocks, key is the case value. 185 */ 186typedef struct SuccessorBlockInfo { 187 BasicBlock *block; 188 int key; 189} SuccessorBlockInfo; 190 191struct LoopAnalysis; 192struct RegisterPool; 193 194typedef enum AssemblerStatus { 195 kSuccess, 196 kRetryAll, 197 kRetryHalve 198} AssemblerStatus; 199 200typedef struct CompilationUnit { 201 int numInsts; 202 int numBlocks; 203 GrowableList blockList; 204 const Method *method; 205#ifdef ARCH_IA32 206 int exceptionBlockId; // the block corresponding to exception handling 207#endif 208 const JitTraceDescription *traceDesc; 209 LIR *firstLIRInsn; 210 LIR *lastLIRInsn; 211 LIR *literalList; // Constants 212 LIR *classPointerList; // Relocatable 213 int numClassPointers; 214 LIR *chainCellOffsetLIR; 215 GrowableList pcReconstructionList; 216 int headerSize; // bytes before the first code ptr 217 int dataOffset; // starting offset of literal pool 218 int totalSize; // header + code size 219 AssemblerStatus assemblerStatus; // Success or fix and retry 220 int assemblerRetries; // How many times tried to fix assembly 221 unsigned char *codeBuffer; 222 void *baseAddr; 223 bool printMe; 224 bool allSingleStep; 225 bool hasClassLiterals; // Contains class ptrs used as literals 226 bool hasLoop; // Contains a loop 227 bool hasInvoke; // Contains an invoke instruction 228 bool heapMemOp; // Mark mem ops for self verification 229 bool usesLinkRegister; // For self-verification only 230 int profileCodeSize; // Size of the profile prefix in bytes 231 int numChainingCells[kChainingCellGap]; 232 LIR *firstChainingLIR[kChainingCellGap]; 233 LIR *chainingCellBottom; 234 struct RegisterPool *regPool; 235 int optRound; // round number to tell an LIR's age 236 jmp_buf *bailPtr; 237 JitInstructionSetType instructionSet; 238 /* Number of total regs used in the whole cUnit after SSA transformation */ 239 int numSSARegs; 240 /* Map SSA reg i to the Dalvik[15..0]/Sub[31..16] pair. */ 241 GrowableList *ssaToDalvikMap; 242 243 /* The following are new data structures to support SSA representations */ 244 /* Map original Dalvik reg i to the SSA[15..0]/Sub[31..16] pair */ 245 int *dalvikToSSAMap; // length == method->registersSize 246 BitVector *isConstantV; // length == numSSAReg 247 int *constantValues; // length == numSSAReg 248 249 /* Data structure for loop analysis and optimizations */ 250 struct LoopAnalysis *loopAnalysis; 251 252 /* Map SSA names to location */ 253 RegLocation *regLocation; 254 int sequenceNumber; 255 256 /* 257 * Set to the Dalvik PC of the switch instruction if it has more than 258 * MAX_CHAINED_SWITCH_CASES cases. 259 */ 260 const u2 *switchOverflowPad; 261 262 JitMode jitMode; 263 int numReachableBlocks; 264 int numDalvikRegisters; // method->registersSize + inlined 265 BasicBlock *entryBlock; 266 BasicBlock *exitBlock; 267 BasicBlock *puntBlock; // punting to interp for exceptions 268 BasicBlock *backChainBlock; // for loop-trace 269 BasicBlock *curBlock; 270 BasicBlock *nextCodegenBlock; // for extended trace codegen 271 GrowableList dfsOrder; 272 GrowableList domPostOrderTraversal; 273 BitVector *tryBlockAddr; 274 BitVector **defBlockMatrix; // numDalvikRegister x numBlocks 275 BitVector *tempBlockV; 276 BitVector *tempDalvikRegisterV; 277 BitVector *tempSSARegisterV; // numSSARegs 278 bool printSSANames; 279 void *blockLabelList; 280 bool quitLoopMode; // cold path/complex bytecode 281} CompilationUnit; 282 283#if defined(WITH_SELF_VERIFICATION) 284#define HEAP_ACCESS_SHADOW(_state) cUnit->heapMemOp = _state 285#else 286#define HEAP_ACCESS_SHADOW(_state) 287#endif 288 289BasicBlock *dvmCompilerNewBB(BBType blockType, int blockId); 290 291void dvmCompilerAppendMIR(BasicBlock *bb, MIR *mir); 292 293void dvmCompilerPrependMIR(BasicBlock *bb, MIR *mir); 294 295void dvmCompilerInsertMIRAfter(BasicBlock *bb, MIR *currentMIR, MIR *newMIR); 296 297void dvmCompilerAppendLIR(CompilationUnit *cUnit, LIR *lir); 298 299void dvmCompilerInsertLIRBefore(LIR *currentLIR, LIR *newLIR); 300 301void dvmCompilerInsertLIRAfter(LIR *currentLIR, LIR *newLIR); 302 303void dvmCompilerAbort(CompilationUnit *cUnit); 304 305/* Debug Utilities */ 306void dvmCompilerDumpCompilationUnit(CompilationUnit *cUnit); 307 308#endif // DALVIK_VM_COMPILER_IR_H_ 309