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 18 #define _DALVIK_VM_COMPILER_IR 19 20 #include "codegen/Optimizer.h" 21 22 typedef enum RegisterClass { 23 kCoreReg, 24 kFPReg, 25 kAnyReg, 26 } RegisterClass; 27 28 typedef enum RegLocationType { 29 kLocDalvikFrame = 0, 30 kLocPhysReg, 31 kLocRetval, // Return region in interpState 32 kLocSpill, 33 } RegLocationType; 34 35 typedef struct RegLocation { 36 RegLocationType location:2; 37 unsigned wide:1; 38 unsigned fp:1; // Hint for float/double 39 u1 lowReg:6; // First physical register 40 u1 highReg:6; // 2nd physical register (if wide) 41 s2 sRegLow; // SSA name for low Dalvik word 42 } RegLocation; 43 44 #define INVALID_SREG (-1) 45 #define INVALID_REG (-1) 46 47 typedef enum BBType { 48 /* For coding convenience reasons chaining cell types should appear first */ 49 kChainingCellNormal = 0, 50 kChainingCellHot, 51 kChainingCellInvokeSingleton, 52 kChainingCellInvokePredicted, 53 kChainingCellBackwardBranch, 54 kChainingCellGap, 55 /* Don't insert new fields between Gap and Last */ 56 kChainingCellLast = kChainingCellGap + 1, 57 kMethodEntryBlock, 58 kTraceEntryBlock, 59 kDalvikByteCode, 60 kTraceExitBlock, 61 kMethodExitBlock, 62 kPCReconstruction, 63 kExceptionHandling, 64 } BBType; 65 66 typedef struct ChainCellCounts { 67 union { 68 u1 count[kChainingCellLast]; /* include one more space for the gap # */ 69 u4 dummyForAlignment; 70 } u; 71 } ChainCellCounts; 72 73 typedef struct LIR { 74 int offset; 75 struct LIR *next; 76 struct LIR *prev; 77 struct LIR *target; 78 } LIR; 79 80 enum ExtendedMIROpcode { 81 kMirOpFirst = 256, 82 kMirOpPhi = kMirOpFirst, 83 kMirOpNullNRangeUpCheck, 84 kMirOpNullNRangeDownCheck, 85 kMirOpLowerBound, 86 kMirOpPunt, 87 kMirOpCheckInlinePrediction, // Gen checks for predicted inlining 88 kMirOpLast, 89 }; 90 91 struct SSARepresentation; 92 93 typedef enum { 94 kMIRIgnoreNullCheck = 0, 95 kMIRNullCheckOnly, 96 kMIRIgnoreRangeCheck, 97 kMIRRangeCheckOnly, 98 kMIRInlined, // Invoke is inlined (ie dead) 99 kMIRInlinedPred, // Invoke is inlined via prediction 100 kMIRCallee, // Instruction is inlined from callee 101 } MIROptimizationFlagPositons; 102 103 #define MIR_IGNORE_NULL_CHECK (1 << kMIRIgnoreNullCheck) 104 #define MIR_NULL_CHECK_ONLY (1 << kMIRNullCheckOnly) 105 #define MIR_IGNORE_RANGE_CHECK (1 << kMIRIgnoreRangeCheck) 106 #define MIR_RANGE_CHECK_ONLY (1 << kMIRRangeCheckOnly) 107 #define MIR_INLINED (1 << kMIRInlined) 108 #define MIR_INLINED_PRED (1 << kMIRInlinedPred) 109 #define MIR_CALLEE (1 << kMIRCallee) 110 111 typedef struct CallsiteInfo { 112 const ClassObject *clazz; 113 const Method *method; 114 LIR *misPredBranchOver; 115 } CallsiteInfo; 116 117 typedef struct MIR { 118 DecodedInstruction dalvikInsn; 119 unsigned int width; 120 unsigned int offset; 121 struct MIR *prev; 122 struct MIR *next; 123 struct SSARepresentation *ssaRep; 124 int OptimizationFlags; 125 int seqNum; 126 union { 127 // Used by the inlined insn from the callee to find the mother method 128 const Method *calleeMethod; 129 // Used by the inlined invoke to find the class and method pointers 130 CallsiteInfo *callsiteInfo; 131 } meta; 132 } MIR; 133 134 struct BasicBlockDataFlow; 135 136 typedef struct BasicBlock { 137 int id; 138 int visited; 139 unsigned int startOffset; 140 const Method *containingMethod; // For blocks from the callee 141 BBType blockType; 142 bool needFallThroughBranch; // For blocks ended due to length limit 143 bool isFallThroughFromInvoke; // True means the block needs alignment 144 MIR *firstMIRInsn; 145 MIR *lastMIRInsn; 146 struct BasicBlock *fallThrough; 147 struct BasicBlock *taken; 148 struct BasicBlock *next; // Serial link for book keeping purposes 149 struct BasicBlockDataFlow *dataFlowInfo; 150 } BasicBlock; 151 152 struct LoopAnalysis; 153 struct RegisterPool; 154 155 typedef enum AssemblerStatus { 156 kSuccess, 157 kRetryAll, 158 kRetryHalve 159 } AssemblerStatus; 160 161 typedef struct CompilationUnit { 162 int numInsts; 163 int numBlocks; 164 BasicBlock **blockList; 165 const Method *method; 166 const JitTraceDescription *traceDesc; 167 LIR *firstLIRInsn; 168 LIR *lastLIRInsn; 169 LIR *wordList; 170 LIR *chainCellOffsetLIR; 171 GrowableList pcReconstructionList; 172 int headerSize; // bytes before the first code ptr 173 int dataOffset; // starting offset of literal pool 174 int totalSize; // header + code size 175 AssemblerStatus assemblerStatus; // Success or fix and retry 176 int assemblerRetries; // How many times tried to fix assembly 177 unsigned char *codeBuffer; 178 void *baseAddr; 179 bool printMe; 180 bool allSingleStep; 181 bool executionCount; // Add code to count trace executions 182 bool hasLoop; // Contains a loop 183 bool hasInvoke; // Contains an invoke instruction 184 bool heapMemOp; // Mark mem ops for self verification 185 bool wholeMethod; 186 int numChainingCells[kChainingCellGap]; 187 LIR *firstChainingLIR[kChainingCellGap]; 188 LIR *chainingCellBottom; 189 struct RegisterPool *regPool; 190 int optRound; // round number to tell an LIR's age 191 jmp_buf *bailPtr; 192 JitInstructionSetType instructionSet; 193 /* Number of total regs used in the whole cUnit after SSA transformation */ 194 int numSSARegs; 195 /* Map SSA reg i to the Dalvik[15..0]/Sub[31..16] pair. */ 196 GrowableList *ssaToDalvikMap; 197 198 /* The following are new data structures to support SSA representations */ 199 /* Map original Dalvik reg i to the SSA[15..0]/Sub[31..16] pair */ 200 int *dalvikToSSAMap; // length == method->registersSize 201 BitVector *isConstantV; // length == numSSAReg 202 int *constantValues; // length == numSSAReg 203 204 /* Data structure for loop analysis and optimizations */ 205 struct LoopAnalysis *loopAnalysis; 206 207 /* Map SSA names to location */ 208 RegLocation *regLocation; 209 int sequenceNumber; 210 211 /* 212 * Set to the Dalvik PC of the switch instruction if it has more than 213 * MAX_CHAINED_SWITCH_CASES cases. 214 */ 215 const u2 *switchOverflowPad; 216 } CompilationUnit; 217 218 #if defined(WITH_SELF_VERIFICATION) 219 #define HEAP_ACCESS_SHADOW(_state) cUnit->heapMemOp = _state 220 #else 221 #define HEAP_ACCESS_SHADOW(_state) 222 #endif 223 224 BasicBlock *dvmCompilerNewBB(BBType blockType); 225 226 void dvmCompilerAppendMIR(BasicBlock *bb, MIR *mir); 227 228 void dvmCompilerPrependMIR(BasicBlock *bb, MIR *mir); 229 230 void dvmCompilerInsertMIRAfter(BasicBlock *bb, MIR *currentMIR, MIR *newMIR); 231 232 void dvmCompilerAppendLIR(CompilationUnit *cUnit, LIR *lir); 233 234 void dvmCompilerInsertLIRBefore(LIR *currentLIR, LIR *newLIR); 235 236 void dvmCompilerInsertLIRAfter(LIR *currentLIR, LIR *newLIR); 237 238 void dvmCompilerAbort(CompilationUnit *cUnit); 239 240 /* Debug Utilities */ 241 void dvmCompilerDumpCompilationUnit(CompilationUnit *cUnit); 242 243 #endif /* _DALVIK_VM_COMPILER_IR */ 244