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 kEntryBlock, 58 kDalvikByteCode, 59 kExitBlock, 60 kPCReconstruction, 61 kExceptionHandling, 62 } BBType; 63 64 typedef struct ChainCellCounts { 65 union { 66 u1 count[kChainingCellLast]; /* include one more space for the gap # */ 67 u4 dummyForAlignment; 68 } u; 69 } ChainCellCounts; 70 71 typedef struct LIR { 72 int offset; 73 struct LIR *next; 74 struct LIR *prev; 75 struct LIR *target; 76 } LIR; 77 78 enum ExtendedMIROpcode { 79 kMirOpFirst = 256, 80 kMirOpPhi = kMirOpFirst, 81 kMirOpNullNRangeUpCheck, 82 kMirOpNullNRangeDownCheck, 83 kMirOpLowerBound, 84 kMirOpPunt, 85 kMirOpLast, 86 }; 87 88 struct SSARepresentation; 89 90 typedef enum { 91 kMIRIgnoreNullCheck = 0, 92 kMIRNullCheckOnly, 93 kMIRIgnoreRangeCheck, 94 kMIRRangeCheckOnly, 95 } MIROptimizationFlagPositons; 96 97 #define MIR_IGNORE_NULL_CHECK (1 << kMIRIgnoreNullCheck) 98 #define MIR_NULL_CHECK_ONLY (1 << kMIRNullCheckOnly) 99 #define MIR_IGNORE_RANGE_CHECK (1 << kMIRIgnoreRangeCheck) 100 #define MIR_RANGE_CHECK_ONLY (1 << kMIRRangeCheckOnly) 101 102 typedef struct MIR { 103 DecodedInstruction dalvikInsn; 104 unsigned int width; 105 unsigned int offset; 106 struct MIR *prev; 107 struct MIR *next; 108 struct SSARepresentation *ssaRep; 109 int OptimizationFlags; 110 int seqNum; 111 } MIR; 112 113 struct BasicBlockDataFlow; 114 115 typedef struct BasicBlock { 116 int id; 117 int visited; 118 unsigned int startOffset; 119 const Method *containingMethod; // For blocks from the callee 120 BBType blockType; 121 bool needFallThroughBranch; // For blocks ended due to length limit 122 MIR *firstMIRInsn; 123 MIR *lastMIRInsn; 124 struct BasicBlock *fallThrough; 125 struct BasicBlock *taken; 126 struct BasicBlock *next; // Serial link for book keeping purposes 127 struct BasicBlockDataFlow *dataFlowInfo; 128 } BasicBlock; 129 130 struct LoopAnalysis; 131 struct RegisterPool; 132 133 typedef struct CompilationUnit { 134 int numInsts; 135 int numBlocks; 136 BasicBlock **blockList; 137 const Method *method; 138 const JitTraceDescription *traceDesc; 139 LIR *firstLIRInsn; 140 LIR *lastLIRInsn; 141 LIR *wordList; 142 LIR *chainCellOffsetLIR; 143 GrowableList pcReconstructionList; 144 int headerSize; // bytes before the first code ptr 145 int dataOffset; // starting offset of literal pool 146 int totalSize; // header + code size 147 unsigned char *codeBuffer; 148 void *baseAddr; 149 bool printMe; 150 bool allSingleStep; 151 bool halveInstCount; 152 bool executionCount; // Add code to count trace executions 153 bool hasLoop; 154 bool heapMemOp; // Mark mem ops for self verification 155 int numChainingCells[kChainingCellGap]; 156 LIR *firstChainingLIR[kChainingCellGap]; 157 LIR *chainingCellBottom; 158 struct RegisterPool *regPool; 159 int optRound; // round number to tell an LIR's age 160 jmp_buf *bailPtr; 161 JitInstructionSetType instructionSet; 162 /* Number of total regs used in the whole cUnit after SSA transformation */ 163 int numSSARegs; 164 /* Map SSA reg i to the Dalvik[15..0]/Sub[31..16] pair. */ 165 GrowableList *ssaToDalvikMap; 166 167 /* The following are new data structures to support SSA representations */ 168 /* Map original Dalvik reg i to the SSA[15..0]/Sub[31..16] pair */ 169 int *dalvikToSSAMap; // length == method->registersSize 170 BitVector *isConstantV; // length == numSSAReg 171 int *constantValues; // length == numSSAReg 172 173 /* Data structure for loop analysis and optimizations */ 174 struct LoopAnalysis *loopAnalysis; 175 176 /* Map SSA names to location */ 177 RegLocation *regLocation; 178 int sequenceNumber; 179 180 /* 181 * Set to the Dalvik PC of the switch instruction if it has more than 182 * MAX_CHAINED_SWITCH_CASES cases. 183 */ 184 const u2 *switchOverflowPad; 185 } CompilationUnit; 186 187 #if defined(WITH_SELF_VERIFICATION) 188 #define HEAP_ACCESS_SHADOW(_state) cUnit->heapMemOp = _state 189 #else 190 #define HEAP_ACCESS_SHADOW(_state) 191 #endif 192 193 BasicBlock *dvmCompilerNewBB(BBType blockType); 194 195 void dvmCompilerAppendMIR(BasicBlock *bb, MIR *mir); 196 197 void dvmCompilerPrependMIR(BasicBlock *bb, MIR *mir); 198 199 void dvmCompilerAppendLIR(CompilationUnit *cUnit, LIR *lir); 200 201 void dvmCompilerInsertLIRBefore(LIR *currentLIR, LIR *newLIR); 202 203 void dvmCompilerInsertLIRAfter(LIR *currentLIR, LIR *newLIR); 204 205 void dvmCompilerAbort(CompilationUnit *cUnit); 206 207 /* Debug Utilities */ 208 void dvmCompilerDumpCompilationUnit(CompilationUnit *cUnit); 209 210 #endif /* _DALVIK_VM_COMPILER_IR */ 211