blob: 5750913b926e53750a3f0e415d6d77549e8b7c15 [file] [log] [blame]
buzbee67bf8852011-08-17 17:51:35 -07001/*
2 * Copyright (C) 2011 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 ART_SRC_COMPILER_COMPILER_IR_H_
18#define ART_SRC_COMPILER_COMPILER_IR_H_
19
20#include "codegen/Optimizer.h"
Ian Rogers1bddec32012-02-04 12:27:34 -080021#include "CompilerUtility.h"
buzbeec143c552011-08-20 17:38:58 -070022#include <vector>
buzbee31a4a6f2012-02-28 15:36:15 -080023#include "oat_compilation_unit.h"
buzbee67bf8852011-08-17 17:51:35 -070024
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080025namespace art {
26
buzbee31a4a6f2012-02-28 15:36:15 -080027#define SLOW_FIELD_PATH (cUnit->enableDebug & (1 << kDebugSlowFieldPath))
28#define SLOW_INVOKE_PATH (cUnit->enableDebug & (1 << kDebugSlowInvokePath))
29#define SLOW_STRING_PATH (cUnit->enableDebug & (1 << kDebugSlowStringPath))
30#define SLOW_TYPE_PATH (cUnit->enableDebug & (1 << kDebugSlowTypePath))
31#define EXERCISE_SLOWEST_FIELD_PATH (cUnit->enableDebug & \
32 (1 << kDebugSlowestFieldPath))
33#define EXERCISE_SLOWEST_STRING_PATH (cUnit->enableDebug & \
34 (1 << kDebugSlowestStringPath))
35#define EXERCISE_RESOLVE_METHOD (cUnit->enableDebug & \
36 (1 << kDebugExerciseResolveMethod))
37
Elliott Hughes719ace42012-03-09 18:06:03 -080038enum RegisterClass {
buzbee67bf8852011-08-17 17:51:35 -070039 kCoreReg,
40 kFPReg,
41 kAnyReg,
Elliott Hughes719ace42012-03-09 18:06:03 -080042};
buzbee67bf8852011-08-17 17:51:35 -070043
Elliott Hughes719ace42012-03-09 18:06:03 -080044enum RegLocationType {
buzbee67bf8852011-08-17 17:51:35 -070045 kLocDalvikFrame = 0, // Normal Dalvik register
46 kLocPhysReg,
buzbeee1965672012-03-11 18:39:19 -070047 kLocCompilerTemp,
Elliott Hughes719ace42012-03-09 18:06:03 -080048};
buzbee67bf8852011-08-17 17:51:35 -070049
Elliott Hughes719ace42012-03-09 18:06:03 -080050struct PromotionMap {
buzbee67bc2362011-10-11 18:08:40 -070051 RegLocationType coreLocation:3;
52 u1 coreReg;
53 RegLocationType fpLocation:3;
54 u1 fpReg;
55 bool firstInPair;
Elliott Hughes719ace42012-03-09 18:06:03 -080056};
buzbee67bc2362011-10-11 18:08:40 -070057
Elliott Hughes719ace42012-03-09 18:06:03 -080058struct RegLocation {
buzbee67bc2362011-10-11 18:08:40 -070059 RegLocationType location:3;
buzbee67bf8852011-08-17 17:51:35 -070060 unsigned wide:1;
buzbee67bc2362011-10-11 18:08:40 -070061 unsigned defined:1; // Do we know the type?
62 unsigned fp:1; // Floating point?
63 unsigned core:1; // Non-floating point?
64 unsigned highWord:1; // High word of pair?
65 unsigned home:1; // Does this represent the home location?
66 u1 lowReg; // First physical register
67 u1 highReg; // 2nd physical register (if wide)
buzbeee1965672012-03-11 18:39:19 -070068 int32_t sRegLow; // SSA name for low Dalvik word
69};
70
71struct CompilerTemp {
72 int sReg;
73 ArenaBitVector* bv;
Elliott Hughes719ace42012-03-09 18:06:03 -080074};
buzbee67bf8852011-08-17 17:51:35 -070075
buzbeee3acd072012-02-25 17:03:10 -080076 /*
77 * Data structure tracking the mapping between a Dalvik register (pair) and a
78 * native register (pair). The idea is to reuse the previously loaded value
79 * if possible, otherwise to keep the value in a native register as long as
80 * possible.
81 */
Elliott Hughes719ace42012-03-09 18:06:03 -080082struct RegisterInfo {
buzbeee3acd072012-02-25 17:03:10 -080083 int reg; // Reg number
84 bool inUse; // Has it been allocated?
85 bool isTemp; // Can allocate as temp?
86 bool pair; // Part of a register pair?
87 int partner; // If pair, other reg of pair
88 bool live; // Is there an associated SSA name?
89 bool dirty; // If live, is it dirty?
90 int sReg; // Name of live value
91 struct LIR *defStart; // Starting inst in last def sequence
92 struct LIR *defEnd; // Ending inst in last def sequence
Elliott Hughes719ace42012-03-09 18:06:03 -080093};
buzbeee3acd072012-02-25 17:03:10 -080094
Elliott Hughes719ace42012-03-09 18:06:03 -080095struct RegisterPool {
buzbeee3acd072012-02-25 17:03:10 -080096 int numCoreRegs;
97 RegisterInfo *coreRegs;
98 int nextCoreReg;
99 int numFPRegs;
100 RegisterInfo *FPRegs;
101 int nextFPReg;
Elliott Hughes719ace42012-03-09 18:06:03 -0800102};
buzbeee3acd072012-02-25 17:03:10 -0800103
buzbee67bf8852011-08-17 17:51:35 -0700104#define INVALID_SREG (-1)
buzbee3ddc0d12011-10-05 10:36:21 -0700105#define INVALID_VREG (0xFFFFU)
buzbee67bc2362011-10-11 18:08:40 -0700106#define INVALID_REG (0xFF)
buzbee67bf8852011-08-17 17:51:35 -0700107#define INVALID_OFFSET (-1)
108
buzbeee1965672012-03-11 18:39:19 -0700109/* SSA encodings for special registers */
110#define SSA_METHOD_BASEREG (-1)
111/* First compiler temp basereg, grows smaller */
112#define SSA_CTEMP_BASEREG (-2)
113
buzbee99ba9642012-01-25 14:23:14 -0800114/*
115 * Some code patterns cause the generation of excessively large
116 * methods - in particular initialization sequences. There isn't much
117 * benefit in optimizing these methods, and the cost can be very high.
118 * We attempt to identify these cases, and avoid performing most dataflow
119 * analysis. Two thresholds are used - one for known initializers and one
buzbee5abfa3e2012-01-31 17:01:43 -0800120 * for everything else.
buzbee99ba9642012-01-25 14:23:14 -0800121 */
buzbee5abfa3e2012-01-31 17:01:43 -0800122#define MANY_BLOCKS_INITIALIZER 1000 /* Threshold for switching dataflow off */
123#define MANY_BLOCKS 4000 /* Non-initializer threshold */
buzbee99ba9642012-01-25 14:23:14 -0800124
Elliott Hughes719ace42012-03-09 18:06:03 -0800125enum BBType {
buzbee67bf8852011-08-17 17:51:35 -0700126 kEntryBlock,
127 kDalvikByteCode,
128 kExitBlock,
129 kExceptionHandling,
130 kCatchEntry,
Elliott Hughes719ace42012-03-09 18:06:03 -0800131};
buzbee67bf8852011-08-17 17:51:35 -0700132
buzbee31a4a6f2012-02-28 15:36:15 -0800133/* Utility macros to traverse the LIR list */
134#define NEXT_LIR(lir) (lir->next)
135#define PREV_LIR(lir) (lir->prev)
136
137#define NEXT_LIR_LVALUE(lir) (lir)->next
138#define PREV_LIR_LVALUE(lir) (lir)->prev
139
Elliott Hughes719ace42012-03-09 18:06:03 -0800140struct LIR {
buzbee67bf8852011-08-17 17:51:35 -0700141 int offset; // Offset of this instruction
142 int dalvikOffset; // Offset of Dalvik opcode
143 struct LIR* next;
144 struct LIR* prev;
145 struct LIR* target;
buzbee31a4a6f2012-02-28 15:36:15 -0800146 int opcode;
Ian Rogersb5d09b22012-03-06 22:14:17 -0800147 int operands[5]; // [0..4] = [dest, src1, src2, extra, extra2]
buzbee31a4a6f2012-02-28 15:36:15 -0800148 struct {
149 bool isNop:1; // LIR is optimized away
150 bool pcRelFixup:1; // May need pc-relative fixup
151 unsigned int age:4; // default is 0, set lazily by the optimizer
buzbee71ac9942012-03-01 17:23:10 -0800152 unsigned int size:5; // in bytes
153 unsigned int unused:21;
buzbee31a4a6f2012-02-28 15:36:15 -0800154 } flags;
155 int aliasInfo; // For Dalvik register & litpool disambiguation
156 u8 useMask; // Resource mask for use
157 u8 defMask; // Resource mask for def
Elliott Hughes719ace42012-03-09 18:06:03 -0800158};
buzbee67bf8852011-08-17 17:51:35 -0700159
160enum ExtendedMIROpcode {
161 kMirOpFirst = kNumPackedOpcodes,
162 kMirOpPhi = kMirOpFirst,
163 kMirOpNullNRangeUpCheck,
164 kMirOpNullNRangeDownCheck,
165 kMirOpLowerBound,
buzbeee1965672012-03-11 18:39:19 -0700166 kMirOpCopy,
buzbee67bf8852011-08-17 17:51:35 -0700167 kMirOpLast,
168};
169
170struct SSARepresentation;
171
Elliott Hughes719ace42012-03-09 18:06:03 -0800172enum MIROptimizationFlagPositons {
buzbee67bf8852011-08-17 17:51:35 -0700173 kMIRIgnoreNullCheck = 0,
174 kMIRNullCheckOnly,
175 kMIRIgnoreRangeCheck,
176 kMIRRangeCheckOnly,
177 kMIRInlined, // Invoke is inlined (ie dead)
178 kMIRInlinedPred, // Invoke is inlined via prediction
179 kMIRCallee, // Instruction is inlined from callee
buzbeec1f45042011-09-21 16:03:19 -0700180 kMIRIgnoreSuspendCheck,
buzbeee1965672012-03-11 18:39:19 -0700181 kMIRDup,
Elliott Hughes719ace42012-03-09 18:06:03 -0800182};
buzbee67bf8852011-08-17 17:51:35 -0700183
184#define MIR_IGNORE_NULL_CHECK (1 << kMIRIgnoreNullCheck)
185#define MIR_NULL_CHECK_ONLY (1 << kMIRNullCheckOnly)
186#define MIR_IGNORE_RANGE_CHECK (1 << kMIRIgnoreRangeCheck)
187#define MIR_RANGE_CHECK_ONLY (1 << kMIRRangeCheckOnly)
188#define MIR_INLINED (1 << kMIRInlined)
189#define MIR_INLINED_PRED (1 << kMIRInlinedPred)
190#define MIR_CALLEE (1 << kMIRCallee)
buzbeec1f45042011-09-21 16:03:19 -0700191#define MIR_IGNORE_SUSPEND_CHECK (1 << kMIRIgnoreSuspendCheck)
buzbeee1965672012-03-11 18:39:19 -0700192#define MIR_DUP (1 << kMIRDup)
buzbee67bf8852011-08-17 17:51:35 -0700193
Elliott Hughes719ace42012-03-09 18:06:03 -0800194struct CallsiteInfo {
buzbee67bf8852011-08-17 17:51:35 -0700195 const char* classDescriptor;
196 Object* classLoader;
197 const Method* method;
198 LIR* misPredBranchOver;
Elliott Hughes719ace42012-03-09 18:06:03 -0800199};
buzbee67bf8852011-08-17 17:51:35 -0700200
Elliott Hughes719ace42012-03-09 18:06:03 -0800201struct MIR {
buzbee67bf8852011-08-17 17:51:35 -0700202 DecodedInstruction dalvikInsn;
203 unsigned int width;
204 unsigned int offset;
205 struct MIR* prev;
206 struct MIR* next;
207 struct SSARepresentation* ssaRep;
buzbee43a36422011-09-14 14:00:13 -0700208 int optimizationFlags;
buzbee67bf8852011-08-17 17:51:35 -0700209 int seqNum;
210 union {
211 // Used by the inlined insn from the callee to find the mother method
212 const Method* calleeMethod;
213 // Used by the inlined invoke to find the class and method pointers
214 CallsiteInfo* callsiteInfo;
buzbeec0ecd652011-09-25 18:11:54 -0700215 // Used to quickly locate all Phi opcodes
216 struct MIR* phiNext;
buzbee67bf8852011-08-17 17:51:35 -0700217 } meta;
Elliott Hughes719ace42012-03-09 18:06:03 -0800218};
buzbee67bf8852011-08-17 17:51:35 -0700219
220struct BasicBlockDataFlow;
221
222/* For successorBlockList */
Elliott Hughes719ace42012-03-09 18:06:03 -0800223enum BlockListType {
buzbee67bf8852011-08-17 17:51:35 -0700224 kNotUsed = 0,
225 kCatch,
226 kPackedSwitch,
227 kSparseSwitch,
Elliott Hughes719ace42012-03-09 18:06:03 -0800228};
buzbee67bf8852011-08-17 17:51:35 -0700229
Elliott Hughes719ace42012-03-09 18:06:03 -0800230struct BasicBlock {
buzbee67bf8852011-08-17 17:51:35 -0700231 int id;
buzbee5b537102012-01-17 17:33:47 -0800232 int dfsId;
buzbee67bf8852011-08-17 17:51:35 -0700233 bool visited;
234 bool hidden;
buzbee43a36422011-09-14 14:00:13 -0700235 bool catchEntry;
buzbeee1965672012-03-11 18:39:19 -0700236 bool fallThroughTarget; // Reached via fallthrough
buzbee67bf8852011-08-17 17:51:35 -0700237 unsigned int startOffset;
238 const Method* containingMethod; // For blocks from the callee
239 BBType blockType;
240 bool needFallThroughBranch; // For blocks ended due to length limit
241 bool isFallThroughFromInvoke; // True means the block needs alignment
242 MIR* firstMIRInsn;
243 MIR* lastMIRInsn;
244 struct BasicBlock* fallThrough;
245 struct BasicBlock* taken;
246 struct BasicBlock* iDom; // Immediate dominator
247 struct BasicBlockDataFlow* dataFlowInfo;
buzbee5abfa3e2012-01-31 17:01:43 -0800248 GrowableList* predecessors;
buzbee67bf8852011-08-17 17:51:35 -0700249 ArenaBitVector* dominators;
250 ArenaBitVector* iDominated; // Set nodes being immediately dominated
251 ArenaBitVector* domFrontier; // Dominance frontier
252 struct { // For one-to-many successors like
253 BlockListType blockListType; // switch and exception handling
254 GrowableList blocks;
255 } successorBlockList;
Elliott Hughes719ace42012-03-09 18:06:03 -0800256};
buzbee67bf8852011-08-17 17:51:35 -0700257
258/*
259 * The "blocks" field in "successorBlockList" points to an array of
260 * elements with the type "SuccessorBlockInfo".
261 * For catch blocks, key is type index for the exception.
262 * For swtich blocks, key is the case value.
263 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800264struct SuccessorBlockInfo {
buzbee67bf8852011-08-17 17:51:35 -0700265 BasicBlock* block;
266 int key;
Elliott Hughes719ace42012-03-09 18:06:03 -0800267};
buzbee67bf8852011-08-17 17:51:35 -0700268
269struct LoopAnalysis;
270struct RegisterPool;
buzbeeba938cb2012-02-03 14:47:55 -0800271struct ArenaMemBlock;
272struct Memstats;
buzbee67bf8852011-08-17 17:51:35 -0700273
Elliott Hughes719ace42012-03-09 18:06:03 -0800274enum AssemblerStatus {
buzbee67bf8852011-08-17 17:51:35 -0700275 kSuccess,
276 kRetryAll,
277 kRetryHalve
Elliott Hughes719ace42012-03-09 18:06:03 -0800278};
buzbee67bf8852011-08-17 17:51:35 -0700279
buzbee5b537102012-01-17 17:33:47 -0800280#define NOTVISITED (-1)
281
Elliott Hughes719ace42012-03-09 18:06:03 -0800282struct CompilationUnit {
buzbee67bf8852011-08-17 17:51:35 -0700283 int numInsts;
284 int numBlocks;
285 GrowableList blockList;
Ian Rogers996cc582012-02-14 22:23:29 -0800286 Compiler* compiler; // Compiler driving this compiler
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800287 ClassLinker* class_linker; // Linker to resolve fields and methods
288 const DexFile* dex_file; // DexFile containing the method being compiled
289 DexCache* dex_cache; // DexFile's corresponding cache
290 const ClassLoader* class_loader; // compiling method's class loader
Ian Rogersa3760aa2011-11-14 14:32:37 -0800291 uint32_t method_idx; // compiling method's index into method_ids of DexFile
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800292 const DexFile::CodeItem* code_item; // compiling method's DexFile code_item
Ian Rogersa3760aa2011-11-14 14:32:37 -0800293 uint32_t access_flags; // compiling method's access flags
294 const char* shorty; // compiling method's shorty
buzbee67bf8852011-08-17 17:51:35 -0700295 LIR* firstLIRInsn;
296 LIR* lastLIRInsn;
297 LIR* literalList; // Constants
298 LIR* classPointerList; // Relocatable
299 int numClassPointers;
300 LIR* chainCellOffsetLIR;
buzbeece302932011-10-04 14:32:18 -0700301 uint32_t disableOpt; // optControlVector flags
302 uint32_t enableDebug; // debugControlVector flags
buzbee67bf8852011-08-17 17:51:35 -0700303 int headerSize; // bytes before the first code ptr
304 int dataOffset; // starting offset of literal pool
305 int totalSize; // header + code size
306 AssemblerStatus assemblerStatus; // Success or fix and retry
307 int assemblerRetries;
Ian Rogersab058bb2012-03-11 22:19:38 -0700308 std::vector<uint8_t> codeBuffer;
buzbee4ef76522011-09-08 10:00:32 -0700309 std::vector<uint32_t> mappingTable;
buzbee3ddc0d12011-10-05 10:36:21 -0700310 std::vector<uint16_t> coreVmapTable;
311 std::vector<uint16_t> fpVmapTable;
buzbee44b412b2012-02-04 08:50:53 -0800312 bool genDebugger; // Generate code for debugger
buzbee67bf8852011-08-17 17:51:35 -0700313 bool printMe;
buzbee67bf8852011-08-17 17:51:35 -0700314 bool hasClassLiterals; // Contains class ptrs used as literals
315 bool hasLoop; // Contains a loop
316 bool hasInvoke; // Contains an invoke instruction
317 bool heapMemOp; // Mark mem ops for self verification
318 bool usesLinkRegister; // For self-verification only
319 bool methodTraceSupport; // For TraceView profiling
320 struct RegisterPool* regPool;
321 int optRound; // round number to tell an LIR's age
Elliott Hughesb3bd5f02012-03-08 21:05:27 -0800322 InstructionSet instructionSet;
buzbee67bf8852011-08-17 17:51:35 -0700323 /* Number of total regs used in the whole cUnit after SSA transformation */
324 int numSSARegs;
buzbeee1965672012-03-11 18:39:19 -0700325 /* Map SSA reg i to the base virtual register/subscript */
326 GrowableList* ssaBaseVRegs;
327 GrowableList* ssaSubscripts;
buzbee67bf8852011-08-17 17:51:35 -0700328
329 /* The following are new data structures to support SSA representations */
buzbeee1965672012-03-11 18:39:19 -0700330 /* Map original Dalvik virtual reg i to the current SSA name */
331 int* vRegToSSAMap; // length == method->registersSize
buzbeef0cde542011-09-13 14:55:02 -0700332 int* SSALastDefs; // length == method->registersSize
buzbee67bf8852011-08-17 17:51:35 -0700333 ArenaBitVector* isConstantV; // length == numSSAReg
334 int* constantValues; // length == numSSAReg
buzbeec0ecd652011-09-25 18:11:54 -0700335 int* phiAliasMap; // length == numSSAReg
336 MIR* phiList;
buzbee67bf8852011-08-17 17:51:35 -0700337
338 /* Map SSA names to location */
339 RegLocation* regLocation;
340 int sequenceNumber;
341
buzbee67bc2362011-10-11 18:08:40 -0700342 /* Keep track of Dalvik vReg to physical register mappings */
343 PromotionMap* promotionMap;
344
buzbeee1965672012-03-11 18:39:19 -0700345 /* SSA name for Method* */
346 int methodSReg;
347
buzbee67bf8852011-08-17 17:51:35 -0700348 /*
349 * Set to the Dalvik PC of the switch instruction if it has more than
350 * MAX_CHAINED_SWITCH_CASES cases.
351 */
352 const u2* switchOverflowPad;
353
354 int numReachableBlocks;
buzbeee1965672012-03-11 18:39:19 -0700355 int numDalvikRegisters; // method->registersSize
buzbee67bf8852011-08-17 17:51:35 -0700356 BasicBlock* entryBlock;
357 BasicBlock* exitBlock;
358 BasicBlock* curBlock;
359 BasicBlock* nextCodegenBlock; // for extended trace codegen
360 GrowableList dfsOrder;
buzbee5b537102012-01-17 17:33:47 -0800361 GrowableList dfsPostOrder;
buzbee67bf8852011-08-17 17:51:35 -0700362 GrowableList domPostOrderTraversal;
buzbee5ade1d22011-09-09 14:44:52 -0700363 GrowableList throwLaunchpads;
buzbeec1f45042011-09-21 16:03:19 -0700364 GrowableList suspendLaunchpads;
buzbeee1965672012-03-11 18:39:19 -0700365 GrowableList compilerTemps;
buzbee5b537102012-01-17 17:33:47 -0800366 int* iDomList;
buzbee67bf8852011-08-17 17:51:35 -0700367 ArenaBitVector* tryBlockAddr;
368 ArenaBitVector** defBlockMatrix; // numDalvikRegister x numBlocks
369 ArenaBitVector* tempBlockV;
370 ArenaBitVector* tempDalvikRegisterV;
371 ArenaBitVector* tempSSARegisterV; // numSSARegs
372 bool printSSANames;
373 void* blockLabelList;
374 bool quitLoopMode; // cold path/complex bytecode
375 int preservedRegsUsed; // How many callee save regs used
376 /*
buzbee5ade1d22011-09-09 14:44:52 -0700377 * Frame layout details.
378 * NOTE: for debug support it will be necessary to add a structure
379 * to map the Dalvik virtual registers to the promoted registers.
380 * NOTE: "num" fields are in 4-byte words, "Size" and "Offset" in bytes.
buzbee67bf8852011-08-17 17:51:35 -0700381 */
382 int numIns;
383 int numOuts;
Ian Rogersa3760aa2011-11-14 14:32:37 -0800384 int numRegs; // Unlike numDalvikRegisters, does not include ins
buzbeebbaf8942011-10-02 13:08:29 -0700385 int numCoreSpills;
buzbee67bf8852011-08-17 17:51:35 -0700386 int numFPSpills;
buzbeeefccc562012-03-11 11:19:28 -0700387 int numCompilerTemps;
buzbee67bf8852011-08-17 17:51:35 -0700388 int frameSize;
389 unsigned int coreSpillMask;
390 unsigned int fpSpillMask;
buzbeecefd1872011-09-09 09:59:52 -0700391 unsigned int attrs;
buzbee67bf8852011-08-17 17:51:35 -0700392 /*
393 * CLEANUP/RESTRUCTURE: The code generation utilities don't have a built-in
buzbee03fa2632011-09-20 17:10:57 -0700394 * mechanism to propagate the original Dalvik opcode address to the
buzbee67bf8852011-08-17 17:51:35 -0700395 * associated generated instructions. For the trace compiler, this wasn't
396 * necessary because the interpreter handled all throws and debugging
397 * requests. For now we'll handle this by placing the Dalvik offset
398 * in the CompilationUnit struct before codegen for each instruction.
399 * The low-level LIR creation utilites will pull it from here. Should
400 * be rewritten.
401 */
402 int currentDalvikOffset;
403 GrowableList switchTables;
buzbee67bf8852011-08-17 17:51:35 -0700404 GrowableList fillArrayData;
405 const u2* insns;
406 u4 insnsSize;
buzbee99ba9642012-01-25 14:23:14 -0800407 bool disableDataflow; // Skip dataflow analysis if possible
buzbee5b537102012-01-17 17:33:47 -0800408 std::map<unsigned int, BasicBlock*> blockMap; // findBlock lookup cache
buzbee85d8c1e2012-01-27 15:52:35 -0800409 std::map<unsigned int, LIR*> boundaryMap; // boundary lookup cache
buzbee5abfa3e2012-01-31 17:01:43 -0800410 int defCount; // Used to estimate number of SSA names
buzbeeba938cb2012-02-03 14:47:55 -0800411 std::string* compilerMethodMatch;
412 bool compilerFlipMatch;
413 struct ArenaMemBlock* arenaHead;
414 struct ArenaMemBlock* currentArena;
415 int numArenaBlocks;
416 struct Memstats* mstats;
buzbee3d661942012-03-14 17:37:27 -0700417#ifndef NDEBUG
418 /*
419 * Sanity checking for the register temp tracking. The same ssa
420 * name should never be associated with one temp register per
421 * instruction compilation.
422 */
423 int liveSReg;
424#endif
Elliott Hughes719ace42012-03-09 18:06:03 -0800425};
buzbee67bf8852011-08-17 17:51:35 -0700426
Elliott Hughes719ace42012-03-09 18:06:03 -0800427enum OpSize {
buzbeee3acd072012-02-25 17:03:10 -0800428 kWord,
429 kLong,
430 kSingle,
431 kDouble,
432 kUnsignedHalf,
433 kSignedHalf,
434 kUnsignedByte,
435 kSignedByte,
Elliott Hughes719ace42012-03-09 18:06:03 -0800436};
buzbeee3acd072012-02-25 17:03:10 -0800437
Elliott Hughes719ace42012-03-09 18:06:03 -0800438enum OpKind {
buzbee31a4a6f2012-02-28 15:36:15 -0800439 kOpMov,
440 kOpMvn,
441 kOpCmp,
442 kOpLsl,
443 kOpLsr,
444 kOpAsr,
445 kOpRor,
446 kOpNot,
447 kOpAnd,
448 kOpOr,
449 kOpXor,
450 kOpNeg,
451 kOpAdd,
452 kOpAdc,
453 kOpSub,
454 kOpSbc,
455 kOpRsub,
456 kOpMul,
457 kOpDiv,
458 kOpRem,
459 kOpBic,
460 kOpCmn,
461 kOpTst,
462 kOpBkpt,
463 kOpBlx,
464 kOpPush,
465 kOpPop,
466 kOp2Char,
467 kOp2Short,
468 kOp2Byte,
469 kOpCondBr,
470 kOpUncondBr,
buzbee5de34942012-03-01 14:51:57 -0800471 kOpBx,
buzbee31a4a6f2012-02-28 15:36:15 -0800472 kOpInvalid,
Elliott Hughes719ace42012-03-09 18:06:03 -0800473};
buzbee31a4a6f2012-02-28 15:36:15 -0800474
Ian Rogers680b1bd2012-03-07 20:18:49 -0800475std::ostream& operator<<(std::ostream& os, const OpKind& kind);
476
Elliott Hughes719ace42012-03-09 18:06:03 -0800477enum ConditionCode {
Ian Rogersb5d09b22012-03-06 22:14:17 -0800478 kCondEq, // equal
479 kCondNe, // not equal
480 kCondCs, // carry set (unsigned less than)
481 kCondUlt = kCondCs,
482 kCondCc, // carry clear (unsigned greater than or same)
483 kCondUge = kCondCc,
484 kCondMi, // minus
485 kCondPl, // plus, positive or zero
486 kCondVs, // overflow
487 kCondVc, // no overflow
488 kCondHi, // unsigned greater than
489 kCondLs, // unsigned lower or same
490 kCondGe, // signed greater than or equal
491 kCondLt, // signed less than
492 kCondGt, // signed greater than
493 kCondLe, // signed less than or equal
494 kCondAl, // always
495 kCondNv, // never
Elliott Hughes719ace42012-03-09 18:06:03 -0800496};
buzbee31a4a6f2012-02-28 15:36:15 -0800497
Elliott Hughes719ace42012-03-09 18:06:03 -0800498enum ThrowKind {
buzbee31a4a6f2012-02-28 15:36:15 -0800499 kThrowNullPointer,
500 kThrowDivZero,
501 kThrowArrayBounds,
502 kThrowVerificationError,
503 kThrowNegArraySize,
504 kThrowNoSuchMethod,
505 kThrowStackOverflow,
Elliott Hughes719ace42012-03-09 18:06:03 -0800506};
buzbee31a4a6f2012-02-28 15:36:15 -0800507
Elliott Hughes719ace42012-03-09 18:06:03 -0800508struct SwitchTable {
buzbee5de34942012-03-01 14:51:57 -0800509 int offset;
510 const u2* table; // Original dex table
511 int vaddr; // Dalvik offset of switch opcode
buzbeec5159d52012-03-03 11:48:39 -0800512 LIR* anchor; // Reference instruction for relative offsets
buzbee5de34942012-03-01 14:51:57 -0800513 LIR** targets; // Array of case targets
Elliott Hughes719ace42012-03-09 18:06:03 -0800514};
buzbee5de34942012-03-01 14:51:57 -0800515
Elliott Hughes719ace42012-03-09 18:06:03 -0800516struct FillArrayData {
buzbee5de34942012-03-01 14:51:57 -0800517 int offset;
518 const u2* table; // Original dex table
519 int size;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800520 int vaddr; // Dalvik offset of FILL_ARRAY_DATA opcode
Elliott Hughes719ace42012-03-09 18:06:03 -0800521};
buzbee5de34942012-03-01 14:51:57 -0800522
523
buzbee5abfa3e2012-01-31 17:01:43 -0800524BasicBlock* oatNewBB(CompilationUnit* cUnit, BBType blockType, int blockId);
buzbee67bf8852011-08-17 17:51:35 -0700525
526void oatAppendMIR(BasicBlock* bb, MIR* mir);
527
528void oatPrependMIR(BasicBlock* bb, MIR* mir);
529
530void oatInsertMIRAfter(BasicBlock* bb, MIR* currentMIR, MIR* newMIR);
531
532void oatAppendLIR(CompilationUnit* cUnit, LIR* lir);
533
534void oatInsertLIRBefore(LIR* currentLIR, LIR* newLIR);
535
536void oatInsertLIRAfter(LIR* currentLIR, LIR* newLIR);
537
538/* Debug Utilities */
539void oatDumpCompilationUnit(CompilationUnit* cUnit);
540
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800541} // namespace art
542
buzbee67bf8852011-08-17 17:51:35 -0700543#endif // ART_SRC_COMPILER_COMPILER_IR_H_