Home | History | Annotate | Download | only in compiler
      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