blob: 972bfac4be68d654d63607d3ecba03f6011e4c07 [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
Elliott Hughesa0e18062012-04-13 15:59:59 -070020#include <vector>
21
buzbee67bf8852011-08-17 17:51:35 -070022#include "codegen/Optimizer.h"
Ian Rogers1bddec32012-02-04 12:27:34 -080023#include "CompilerUtility.h"
buzbee31a4a6f2012-02-28 15:36:15 -080024#include "oat_compilation_unit.h"
Elliott Hughesa0e18062012-04-13 15:59:59 -070025#include "safe_map.h"
buzbee67bf8852011-08-17 17:51:35 -070026
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080027namespace art {
28
buzbee31a4a6f2012-02-28 15:36:15 -080029#define SLOW_FIELD_PATH (cUnit->enableDebug & (1 << kDebugSlowFieldPath))
30#define SLOW_INVOKE_PATH (cUnit->enableDebug & (1 << kDebugSlowInvokePath))
31#define SLOW_STRING_PATH (cUnit->enableDebug & (1 << kDebugSlowStringPath))
32#define SLOW_TYPE_PATH (cUnit->enableDebug & (1 << kDebugSlowTypePath))
33#define EXERCISE_SLOWEST_FIELD_PATH (cUnit->enableDebug & \
Bill Buzbeea114add2012-05-03 15:00:40 -070034 (1 << kDebugSlowestFieldPath))
buzbee31a4a6f2012-02-28 15:36:15 -080035#define EXERCISE_SLOWEST_STRING_PATH (cUnit->enableDebug & \
Bill Buzbeea114add2012-05-03 15:00:40 -070036 (1 << kDebugSlowestStringPath))
buzbee31a4a6f2012-02-28 15:36:15 -080037#define EXERCISE_RESOLVE_METHOD (cUnit->enableDebug & \
Bill Buzbeea114add2012-05-03 15:00:40 -070038 (1 << kDebugExerciseResolveMethod))
buzbee31a4a6f2012-02-28 15:36:15 -080039
Elliott Hughes719ace42012-03-09 18:06:03 -080040enum RegisterClass {
Bill Buzbeea114add2012-05-03 15:00:40 -070041 kCoreReg,
42 kFPReg,
43 kAnyReg,
Elliott Hughes719ace42012-03-09 18:06:03 -080044};
buzbee67bf8852011-08-17 17:51:35 -070045
Elliott Hughes719ace42012-03-09 18:06:03 -080046enum RegLocationType {
Bill Buzbeea114add2012-05-03 15:00:40 -070047 kLocDalvikFrame = 0, // Normal Dalvik register
48 kLocPhysReg,
49 kLocCompilerTemp,
50 kLocInvalid
Elliott Hughes719ace42012-03-09 18:06:03 -080051};
buzbee67bf8852011-08-17 17:51:35 -070052
Elliott Hughes719ace42012-03-09 18:06:03 -080053struct PromotionMap {
Bill Buzbeea114add2012-05-03 15:00:40 -070054 RegLocationType coreLocation:3;
55 u1 coreReg;
56 RegLocationType fpLocation:3;
57 u1 fpReg;
58 bool firstInPair;
Elliott Hughes719ace42012-03-09 18:06:03 -080059};
buzbee67bc2362011-10-11 18:08:40 -070060
Elliott Hughes719ace42012-03-09 18:06:03 -080061struct RegLocation {
Bill Buzbeea114add2012-05-03 15:00:40 -070062 RegLocationType location:3;
63 unsigned wide:1;
64 unsigned defined:1; // Do we know the type?
65 unsigned fp:1; // Floating point?
66 unsigned core:1; // Non-floating point?
buzbeebff24652012-05-06 16:22:05 -070067 unsigned ref:1; // Something GC cares about
Bill Buzbeea114add2012-05-03 15:00:40 -070068 unsigned highWord:1; // High word of pair?
69 unsigned home:1; // Does this represent the home location?
70 u1 lowReg; // First physical register
71 u1 highReg; // 2nd physical register (if wide)
72 int32_t sRegLow; // SSA name for low Dalvik word
buzbeee1965672012-03-11 18:39:19 -070073};
74
75struct CompilerTemp {
Bill Buzbeea114add2012-05-03 15:00:40 -070076 int sReg;
77 ArenaBitVector* bv;
Elliott Hughes719ace42012-03-09 18:06:03 -080078};
buzbee67bf8852011-08-17 17:51:35 -070079
buzbeee3acd072012-02-25 17:03:10 -080080 /*
81 * Data structure tracking the mapping between a Dalvik register (pair) and a
82 * native register (pair). The idea is to reuse the previously loaded value
83 * if possible, otherwise to keep the value in a native register as long as
84 * possible.
85 */
Elliott Hughes719ace42012-03-09 18:06:03 -080086struct RegisterInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -070087 int reg; // Reg number
88 bool inUse; // Has it been allocated?
89 bool isTemp; // Can allocate as temp?
90 bool pair; // Part of a register pair?
91 int partner; // If pair, other reg of pair
92 bool live; // Is there an associated SSA name?
93 bool dirty; // If live, is it dirty?
94 int sReg; // Name of live value
95 LIR *defStart; // Starting inst in last def sequence
96 LIR *defEnd; // Ending inst in last def sequence
Elliott Hughes719ace42012-03-09 18:06:03 -080097};
buzbeee3acd072012-02-25 17:03:10 -080098
Elliott Hughes719ace42012-03-09 18:06:03 -080099struct RegisterPool {
Bill Buzbeea114add2012-05-03 15:00:40 -0700100 int numCoreRegs;
101 RegisterInfo *coreRegs;
102 int nextCoreReg;
103 int numFPRegs;
104 RegisterInfo *FPRegs;
105 int nextFPReg;
Elliott Hughes719ace42012-03-09 18:06:03 -0800106};
buzbeee3acd072012-02-25 17:03:10 -0800107
buzbee67bf8852011-08-17 17:51:35 -0700108#define INVALID_SREG (-1)
buzbee3ddc0d12011-10-05 10:36:21 -0700109#define INVALID_VREG (0xFFFFU)
buzbee67bc2362011-10-11 18:08:40 -0700110#define INVALID_REG (0xFF)
buzbee67bf8852011-08-17 17:51:35 -0700111#define INVALID_OFFSET (-1)
112
buzbeee1965672012-03-11 18:39:19 -0700113/* SSA encodings for special registers */
buzbee9c044ce2012-03-18 13:24:07 -0700114#define SSA_METHOD_BASEREG (-2)
buzbeee1965672012-03-11 18:39:19 -0700115/* First compiler temp basereg, grows smaller */
buzbee9c044ce2012-03-18 13:24:07 -0700116#define SSA_CTEMP_BASEREG (SSA_METHOD_BASEREG - 1)
buzbeee1965672012-03-11 18:39:19 -0700117
buzbee99ba9642012-01-25 14:23:14 -0800118/*
119 * Some code patterns cause the generation of excessively large
120 * methods - in particular initialization sequences. There isn't much
121 * benefit in optimizing these methods, and the cost can be very high.
122 * We attempt to identify these cases, and avoid performing most dataflow
123 * analysis. Two thresholds are used - one for known initializers and one
buzbee5abfa3e2012-01-31 17:01:43 -0800124 * for everything else.
buzbee99ba9642012-01-25 14:23:14 -0800125 */
buzbee5abfa3e2012-01-31 17:01:43 -0800126#define MANY_BLOCKS_INITIALIZER 1000 /* Threshold for switching dataflow off */
127#define MANY_BLOCKS 4000 /* Non-initializer threshold */
buzbee99ba9642012-01-25 14:23:14 -0800128
Elliott Hughes719ace42012-03-09 18:06:03 -0800129enum BBType {
Bill Buzbeea114add2012-05-03 15:00:40 -0700130 kEntryBlock,
131 kDalvikByteCode,
132 kExitBlock,
133 kExceptionHandling,
134 kCatchEntry,
Elliott Hughes719ace42012-03-09 18:06:03 -0800135};
buzbee67bf8852011-08-17 17:51:35 -0700136
buzbee31a4a6f2012-02-28 15:36:15 -0800137/* Utility macros to traverse the LIR list */
138#define NEXT_LIR(lir) (lir->next)
139#define PREV_LIR(lir) (lir->prev)
140
141#define NEXT_LIR_LVALUE(lir) (lir)->next
142#define PREV_LIR_LVALUE(lir) (lir)->prev
143
Elliott Hughes719ace42012-03-09 18:06:03 -0800144struct LIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700145 int offset; // Offset of this instruction
146 int dalvikOffset; // Offset of Dalvik opcode
147 LIR* next;
148 LIR* prev;
149 LIR* target;
150 int opcode;
151 int operands[5]; // [0..4] = [dest, src1, src2, extra, extra2]
152 struct {
153 bool isNop:1; // LIR is optimized away
154 bool pcRelFixup:1; // May need pc-relative fixup
155 unsigned int age:4; // default is 0, set lazily by the optimizer
156 unsigned int size:5; // in bytes
157 unsigned int unused:21;
158 } flags;
159 int aliasInfo; // For Dalvik register & litpool disambiguation
160 u8 useMask; // Resource mask for use
161 u8 defMask; // Resource mask for def
Elliott Hughes719ace42012-03-09 18:06:03 -0800162};
buzbee67bf8852011-08-17 17:51:35 -0700163
164enum ExtendedMIROpcode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700165 kMirOpFirst = kNumPackedOpcodes,
166 kMirOpPhi = kMirOpFirst,
167 kMirOpCopy,
168 kMirOpFusedCmplFloat,
169 kMirOpFusedCmpgFloat,
170 kMirOpFusedCmplDouble,
171 kMirOpFusedCmpgDouble,
172 kMirOpFusedCmpLong,
173 kMirOpNop,
174 kMirOpNullNRangeUpCheck,
175 kMirOpNullNRangeDownCheck,
176 kMirOpLowerBound,
177 kMirOpLast,
buzbee67bf8852011-08-17 17:51:35 -0700178};
179
180struct SSARepresentation;
181
Elliott Hughes719ace42012-03-09 18:06:03 -0800182enum MIROptimizationFlagPositons {
Bill Buzbeea114add2012-05-03 15:00:40 -0700183 kMIRIgnoreNullCheck = 0,
184 kMIRNullCheckOnly,
185 kMIRIgnoreRangeCheck,
186 kMIRRangeCheckOnly,
187 kMIRInlined, // Invoke is inlined (ie dead)
188 kMIRInlinedPred, // Invoke is inlined via prediction
189 kMIRCallee, // Instruction is inlined from callee
190 kMIRIgnoreSuspendCheck,
191 kMIRDup,
192 kMIRMark, // Temporary node mark
Elliott Hughes719ace42012-03-09 18:06:03 -0800193};
buzbee67bf8852011-08-17 17:51:35 -0700194
195#define MIR_IGNORE_NULL_CHECK (1 << kMIRIgnoreNullCheck)
196#define MIR_NULL_CHECK_ONLY (1 << kMIRNullCheckOnly)
197#define MIR_IGNORE_RANGE_CHECK (1 << kMIRIgnoreRangeCheck)
198#define MIR_RANGE_CHECK_ONLY (1 << kMIRRangeCheckOnly)
199#define MIR_INLINED (1 << kMIRInlined)
200#define MIR_INLINED_PRED (1 << kMIRInlinedPred)
201#define MIR_CALLEE (1 << kMIRCallee)
buzbeec1f45042011-09-21 16:03:19 -0700202#define MIR_IGNORE_SUSPEND_CHECK (1 << kMIRIgnoreSuspendCheck)
buzbeee1965672012-03-11 18:39:19 -0700203#define MIR_DUP (1 << kMIRDup)
buzbee239c4e72012-03-16 08:42:29 -0700204#define MIR_MARK (1 << kMIRMark)
buzbee67bf8852011-08-17 17:51:35 -0700205
Elliott Hughes719ace42012-03-09 18:06:03 -0800206struct CallsiteInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700207 const char* classDescriptor;
208 Object* classLoader;
209 const Method* method;
210 LIR* misPredBranchOver;
Elliott Hughes719ace42012-03-09 18:06:03 -0800211};
buzbee67bf8852011-08-17 17:51:35 -0700212
Elliott Hughes719ace42012-03-09 18:06:03 -0800213struct MIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700214 DecodedInstruction dalvikInsn;
215 unsigned int width;
216 unsigned int offset;
217 MIR* prev;
218 MIR* next;
219 SSARepresentation* ssaRep;
220 int optimizationFlags;
221 int seqNum;
222 union {
223 // Used by the inlined insn from the callee to find the mother method
224 const Method* calleeMethod;
225 // Used by the inlined invoke to find the class and method pointers
226 CallsiteInfo* callsiteInfo;
227 // Used to quickly locate all Phi opcodes
228 MIR* phiNext;
229 } meta;
Elliott Hughes719ace42012-03-09 18:06:03 -0800230};
buzbee67bf8852011-08-17 17:51:35 -0700231
232struct BasicBlockDataFlow;
233
234/* For successorBlockList */
Elliott Hughes719ace42012-03-09 18:06:03 -0800235enum BlockListType {
Bill Buzbeea114add2012-05-03 15:00:40 -0700236 kNotUsed = 0,
237 kCatch,
238 kPackedSwitch,
239 kSparseSwitch,
Elliott Hughes719ace42012-03-09 18:06:03 -0800240};
buzbee67bf8852011-08-17 17:51:35 -0700241
Elliott Hughes719ace42012-03-09 18:06:03 -0800242struct BasicBlock {
Bill Buzbeea114add2012-05-03 15:00:40 -0700243 int id;
244 int dfsId;
245 bool visited;
246 bool hidden;
247 bool catchEntry;
248 bool fallThroughTarget; // Reached via fallthrough
249 uint16_t startOffset;
250 uint16_t nestingDepth;
251 const Method* containingMethod; // For blocks from the callee
252 BBType blockType;
253 bool needFallThroughBranch; // For blocks ended due to length limit
254 bool isFallThroughFromInvoke; // True means the block needs alignment
255 MIR* firstMIRInsn;
256 MIR* lastMIRInsn;
257 BasicBlock* fallThrough;
258 BasicBlock* taken;
259 BasicBlock* iDom; // Immediate dominator
260 BasicBlockDataFlow* dataFlowInfo;
261 GrowableList* predecessors;
262 ArenaBitVector* dominators;
263 ArenaBitVector* iDominated; // Set nodes being immediately dominated
264 ArenaBitVector* domFrontier; // Dominance frontier
265 struct { // For one-to-many successors like
266 BlockListType blockListType; // switch and exception handling
267 GrowableList blocks;
268 } successorBlockList;
Elliott Hughes719ace42012-03-09 18:06:03 -0800269};
buzbee67bf8852011-08-17 17:51:35 -0700270
271/*
272 * The "blocks" field in "successorBlockList" points to an array of
273 * elements with the type "SuccessorBlockInfo".
274 * For catch blocks, key is type index for the exception.
275 * For swtich blocks, key is the case value.
276 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800277struct SuccessorBlockInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700278 BasicBlock* block;
279 int key;
Elliott Hughes719ace42012-03-09 18:06:03 -0800280};
buzbee67bf8852011-08-17 17:51:35 -0700281
282struct LoopAnalysis;
283struct RegisterPool;
buzbeeba938cb2012-02-03 14:47:55 -0800284struct ArenaMemBlock;
285struct Memstats;
buzbee67bf8852011-08-17 17:51:35 -0700286
Elliott Hughes719ace42012-03-09 18:06:03 -0800287enum AssemblerStatus {
Bill Buzbeea114add2012-05-03 15:00:40 -0700288 kSuccess,
289 kRetryAll,
290 kRetryHalve
Elliott Hughes719ace42012-03-09 18:06:03 -0800291};
buzbee67bf8852011-08-17 17:51:35 -0700292
buzbee5b537102012-01-17 17:33:47 -0800293#define NOTVISITED (-1)
294
Elliott Hughes719ace42012-03-09 18:06:03 -0800295struct CompilationUnit {
Elliott Hughese52e49b2012-04-02 16:05:44 -0700296 CompilationUnit()
Bill Buzbeea114add2012-05-03 15:00:40 -0700297 : numBlocks(0),
298 compiler(NULL),
299 class_linker(NULL),
300 dex_file(NULL),
301 dex_cache(NULL),
302 class_loader(NULL),
303 method_idx(0),
304 code_item(NULL),
305 access_flags(0),
306 shorty(NULL),
307 firstLIRInsn(NULL),
308 lastLIRInsn(NULL),
309 literalList(NULL),
310 methodLiteralList(NULL),
311 codeLiteralList(NULL),
312 classPointerList(NULL),
313 numClassPointers(0),
314 chainCellOffsetLIR(NULL),
315 disableOpt(0),
316 enableDebug(0),
317 headerSize(0),
318 dataOffset(0),
319 totalSize(0),
320 assemblerStatus(kSuccess),
321 assemblerRetries(0),
322 genDebugger(false),
323 printMe(false),
324 hasClassLiterals(false),
325 hasLoop(false),
326 hasInvoke(false),
327 heapMemOp(false),
328 qdMode(false),
329 usesLinkRegister(false),
330 methodTraceSupport(false),
331 regPool(NULL),
332 optRound(0),
333 instructionSet(kNone),
334 numSSARegs(0),
335 ssaBaseVRegs(NULL),
336 ssaSubscripts(NULL),
337 vRegToSSAMap(NULL),
338 SSALastDefs(NULL),
339 isConstantV(NULL),
340 constantValues(NULL),
341 phiAliasMap(NULL),
342 phiList(NULL),
343 regLocation(NULL),
344 sequenceNumber(0),
345 promotionMap(NULL),
346 methodSReg(0),
347 switchOverflowPad(NULL),
348 numReachableBlocks(0),
349 numDalvikRegisters(0),
350 entryBlock(NULL),
351 exitBlock(NULL),
352 curBlock(NULL),
353 nextCodegenBlock(NULL),
354 iDomList(NULL),
355 tryBlockAddr(NULL),
356 defBlockMatrix(NULL),
357 tempBlockV(NULL),
358 tempDalvikRegisterV(NULL),
359 tempSSARegisterV(NULL),
360 printSSANames(false),
361 blockLabelList(NULL),
362 quitLoopMode(false),
363 preservedRegsUsed(0),
364 numIns(0),
365 numOuts(0),
366 numRegs(0),
367 numCoreSpills(0),
368 numFPSpills(0),
369 numCompilerTemps(0),
370 frameSize(0),
371 coreSpillMask(0U),
372 fpSpillMask(0U),
373 attrs(0U),
374 currentDalvikOffset(0),
375 insns(NULL),
376 insnsSize(0U),
377 disableDataflow(false),
378 defCount(0),
379 compilerFlipMatch(false),
380 arenaHead(NULL),
381 currentArena(NULL),
382 numArenaBlocks(0),
383 mstats(NULL),
384 opcodeCount(NULL) {
Elliott Hughese52e49b2012-04-02 16:05:44 -0700385#if !defined(NDEBUG)
386 liveSReg = 0;
387#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700388 }
Elliott Hughese52e49b2012-04-02 16:05:44 -0700389
Bill Buzbeea114add2012-05-03 15:00:40 -0700390 int numBlocks;
391 GrowableList blockList;
392 Compiler* compiler; // Compiler driving this compiler
393 ClassLinker* class_linker; // Linker to resolve fields and methods
394 const DexFile* dex_file; // DexFile containing the method being compiled
395 DexCache* dex_cache; // DexFile's corresponding cache
396 const ClassLoader* class_loader; // compiling method's class loader
397 uint32_t method_idx; // compiling method's index into method_ids of DexFile
398 const DexFile::CodeItem* code_item; // compiling method's DexFile code_item
399 uint32_t access_flags; // compiling method's access flags
400 const char* shorty; // compiling method's shorty
401 LIR* firstLIRInsn;
402 LIR* lastLIRInsn;
403 LIR* literalList; // Constants
404 LIR* methodLiteralList; // Method literals requiring patching
405 LIR* codeLiteralList; // Code literals requiring patching
406 LIR* classPointerList; // Relocatable
407 int numClassPointers;
408 LIR* chainCellOffsetLIR;
409 uint32_t disableOpt; // optControlVector flags
410 uint32_t enableDebug; // debugControlVector flags
411 int headerSize; // bytes before the first code ptr
412 int dataOffset; // starting offset of literal pool
413 int totalSize; // header + code size
414 AssemblerStatus assemblerStatus; // Success or fix and retry
415 int assemblerRetries;
416 std::vector<uint8_t> codeBuffer;
417 std::vector<uint32_t> mappingTable;
418 std::vector<uint16_t> coreVmapTable;
419 std::vector<uint16_t> fpVmapTable;
420 bool genDebugger; // Generate code for debugger
421 bool printMe;
422 bool hasClassLiterals; // Contains class ptrs used as literals
423 bool hasLoop; // Contains a loop
424 bool hasInvoke; // Contains an invoke instruction
425 bool heapMemOp; // Mark mem ops for self verification
426 bool qdMode; // Compile for code size/compile time
427 bool usesLinkRegister; // For self-verification only
428 bool methodTraceSupport; // For TraceView profiling
429 RegisterPool* regPool;
430 int optRound; // round number to tell an LIR's age
431 InstructionSet instructionSet;
432 /* Number of total regs used in the whole cUnit after SSA transformation */
433 int numSSARegs;
434 /* Map SSA reg i to the base virtual register/subscript */
435 GrowableList* ssaBaseVRegs;
436 GrowableList* ssaSubscripts;
buzbee67bf8852011-08-17 17:51:35 -0700437
Bill Buzbeea114add2012-05-03 15:00:40 -0700438 /* The following are new data structures to support SSA representations */
439 /* Map original Dalvik virtual reg i to the current SSA name */
440 int* vRegToSSAMap; // length == method->registersSize
441 int* SSALastDefs; // length == method->registersSize
442 ArenaBitVector* isConstantV; // length == numSSAReg
443 int* constantValues; // length == numSSAReg
444 int* phiAliasMap; // length == numSSAReg
445 MIR* phiList;
buzbee67bf8852011-08-17 17:51:35 -0700446
Bill Buzbeea114add2012-05-03 15:00:40 -0700447 /* Use counts of ssa names */
448 GrowableList useCounts; // Weighted by nesting depth
449 GrowableList rawUseCounts; // Not weighted
buzbee239c4e72012-03-16 08:42:29 -0700450
Bill Buzbeea114add2012-05-03 15:00:40 -0700451 /* Optimization support */
452 GrowableList loopHeaders;
buzbee239c4e72012-03-16 08:42:29 -0700453
Bill Buzbeea114add2012-05-03 15:00:40 -0700454 /* Map SSA names to location */
455 RegLocation* regLocation;
456 int sequenceNumber;
buzbee67bf8852011-08-17 17:51:35 -0700457
Bill Buzbeea114add2012-05-03 15:00:40 -0700458 /* Keep track of Dalvik vReg to physical register mappings */
459 PromotionMap* promotionMap;
buzbee67bc2362011-10-11 18:08:40 -0700460
Bill Buzbeea114add2012-05-03 15:00:40 -0700461 /* SSA name for Method* */
462 int methodSReg;
buzbeee1965672012-03-11 18:39:19 -0700463
Bill Buzbeea114add2012-05-03 15:00:40 -0700464 /*
465 * Set to the Dalvik PC of the switch instruction if it has more than
466 * MAX_CHAINED_SWITCH_CASES cases.
467 */
468 const u2* switchOverflowPad;
buzbee67bf8852011-08-17 17:51:35 -0700469
Bill Buzbeea114add2012-05-03 15:00:40 -0700470 int numReachableBlocks;
471 int numDalvikRegisters; // method->registersSize
472 BasicBlock* entryBlock;
473 BasicBlock* exitBlock;
474 BasicBlock* curBlock;
475 BasicBlock* nextCodegenBlock; // for extended trace codegen
476 GrowableList dfsOrder;
477 GrowableList dfsPostOrder;
478 GrowableList domPostOrderTraversal;
479 GrowableList throwLaunchpads;
480 GrowableList suspendLaunchpads;
481 GrowableList intrinsicLaunchpads;
482 GrowableList compilerTemps;
483 int* iDomList;
484 ArenaBitVector* tryBlockAddr;
485 ArenaBitVector** defBlockMatrix; // numDalvikRegister x numBlocks
486 ArenaBitVector* tempBlockV;
487 ArenaBitVector* tempDalvikRegisterV;
488 ArenaBitVector* tempSSARegisterV; // numSSARegs
489 bool printSSANames;
490 void* blockLabelList;
491 bool quitLoopMode; // cold path/complex bytecode
492 int preservedRegsUsed; // How many callee save regs used
493 /*
494 * Frame layout details.
495 * NOTE: for debug support it will be necessary to add a structure
496 * to map the Dalvik virtual registers to the promoted registers.
497 * NOTE: "num" fields are in 4-byte words, "Size" and "Offset" in bytes.
498 */
499 int numIns;
500 int numOuts;
501 int numRegs; // Unlike numDalvikRegisters, does not include ins
502 int numCoreSpills;
503 int numFPSpills;
504 int numCompilerTemps;
505 int frameSize;
506 unsigned int coreSpillMask;
507 unsigned int fpSpillMask;
508 unsigned int attrs;
509 /*
510 * CLEANUP/RESTRUCTURE: The code generation utilities don't have a built-in
511 * mechanism to propagate the original Dalvik opcode address to the
512 * associated generated instructions. For the trace compiler, this wasn't
513 * necessary because the interpreter handled all throws and debugging
514 * requests. For now we'll handle this by placing the Dalvik offset
515 * in the CompilationUnit struct before codegen for each instruction.
516 * The low-level LIR creation utilites will pull it from here. Should
517 * be rewritten.
518 */
519 int currentDalvikOffset;
520 GrowableList switchTables;
521 GrowableList fillArrayData;
522 const u2* insns;
523 u4 insnsSize;
524 bool disableDataflow; // Skip dataflow analysis if possible
525 SafeMap<unsigned int, BasicBlock*> blockMap; // findBlock lookup cache
526 SafeMap<unsigned int, LIR*> boundaryMap; // boundary lookup cache
527 int defCount; // Used to estimate number of SSA names
Elliott Hughese52e49b2012-04-02 16:05:44 -0700528
Bill Buzbeea114add2012-05-03 15:00:40 -0700529 // If non-empty, apply optimizer/debug flags only to matching methods.
530 std::string compilerMethodMatch;
531 // Flips sense of compilerMethodMatch - apply flags if doesn't match.
532 bool compilerFlipMatch;
533 ArenaMemBlock* arenaHead;
534 ArenaMemBlock* currentArena;
535 int numArenaBlocks;
536 Memstats* mstats;
537 int* opcodeCount; // Count Dalvik opcodes for tuning
buzbee3d661942012-03-14 17:37:27 -0700538#ifndef NDEBUG
Bill Buzbeea114add2012-05-03 15:00:40 -0700539 /*
540 * Sanity checking for the register temp tracking. The same ssa
541 * name should never be associated with one temp register per
542 * instruction compilation.
543 */
544 int liveSReg;
buzbee3d661942012-03-14 17:37:27 -0700545#endif
Elliott Hughes719ace42012-03-09 18:06:03 -0800546};
buzbee67bf8852011-08-17 17:51:35 -0700547
Elliott Hughes719ace42012-03-09 18:06:03 -0800548enum OpSize {
Bill Buzbeea114add2012-05-03 15:00:40 -0700549 kWord,
550 kLong,
551 kSingle,
552 kDouble,
553 kUnsignedHalf,
554 kSignedHalf,
555 kUnsignedByte,
556 kSignedByte,
Elliott Hughes719ace42012-03-09 18:06:03 -0800557};
buzbeee3acd072012-02-25 17:03:10 -0800558
Elliott Hughes719ace42012-03-09 18:06:03 -0800559enum OpKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700560 kOpMov,
561 kOpMvn,
562 kOpCmp,
563 kOpLsl,
564 kOpLsr,
565 kOpAsr,
566 kOpRor,
567 kOpNot,
568 kOpAnd,
569 kOpOr,
570 kOpXor,
571 kOpNeg,
572 kOpAdd,
573 kOpAdc,
574 kOpSub,
575 kOpSbc,
576 kOpRsub,
577 kOpMul,
578 kOpDiv,
579 kOpRem,
580 kOpBic,
581 kOpCmn,
582 kOpTst,
583 kOpBkpt,
584 kOpBlx,
585 kOpPush,
586 kOpPop,
587 kOp2Char,
588 kOp2Short,
589 kOp2Byte,
590 kOpCondBr,
591 kOpUncondBr,
592 kOpBx,
593 kOpInvalid,
Elliott Hughes719ace42012-03-09 18:06:03 -0800594};
buzbee31a4a6f2012-02-28 15:36:15 -0800595
Ian Rogers680b1bd2012-03-07 20:18:49 -0800596std::ostream& operator<<(std::ostream& os, const OpKind& kind);
597
Elliott Hughes719ace42012-03-09 18:06:03 -0800598enum ConditionCode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700599 kCondEq, // equal
600 kCondNe, // not equal
601 kCondCs, // carry set (unsigned less than)
602 kCondUlt = kCondCs,
603 kCondCc, // carry clear (unsigned greater than or same)
604 kCondUge = kCondCc,
605 kCondMi, // minus
606 kCondPl, // plus, positive or zero
607 kCondVs, // overflow
608 kCondVc, // no overflow
609 kCondHi, // unsigned greater than
610 kCondLs, // unsigned lower or same
611 kCondGe, // signed greater than or equal
612 kCondLt, // signed less than
613 kCondGt, // signed greater than
614 kCondLe, // signed less than or equal
615 kCondAl, // always
616 kCondNv, // never
Elliott Hughes719ace42012-03-09 18:06:03 -0800617};
buzbee31a4a6f2012-02-28 15:36:15 -0800618
Elliott Hughes719ace42012-03-09 18:06:03 -0800619enum ThrowKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700620 kThrowNullPointer,
621 kThrowDivZero,
622 kThrowArrayBounds,
623 kThrowVerificationError,
624 kThrowNoSuchMethod,
625 kThrowStackOverflow,
Elliott Hughes719ace42012-03-09 18:06:03 -0800626};
buzbee31a4a6f2012-02-28 15:36:15 -0800627
Elliott Hughes719ace42012-03-09 18:06:03 -0800628struct SwitchTable {
Bill Buzbeea114add2012-05-03 15:00:40 -0700629 int offset;
630 const u2* table; // Original dex table
631 int vaddr; // Dalvik offset of switch opcode
632 LIR* anchor; // Reference instruction for relative offsets
633 LIR** targets; // Array of case targets
Elliott Hughes719ace42012-03-09 18:06:03 -0800634};
buzbee5de34942012-03-01 14:51:57 -0800635
Elliott Hughes719ace42012-03-09 18:06:03 -0800636struct FillArrayData {
Bill Buzbeea114add2012-05-03 15:00:40 -0700637 int offset;
638 const u2* table; // Original dex table
639 int size;
640 int vaddr; // Dalvik offset of FILL_ARRAY_DATA opcode
Elliott Hughes719ace42012-03-09 18:06:03 -0800641};
buzbee5de34942012-03-01 14:51:57 -0800642
buzbee16da88c2012-03-20 10:38:17 -0700643#define MAX_PATTERN_LEN 5
644
645enum SpecialCaseHandler {
Bill Buzbeea114add2012-05-03 15:00:40 -0700646 kNoHandler,
647 kNullMethod,
648 kConstFunction,
649 kIGet,
650 kIGetBoolean,
651 kIGetObject,
652 kIGetByte,
653 kIGetChar,
654 kIGetShort,
655 kIGetWide,
656 kIPut,
657 kIPutBoolean,
658 kIPutObject,
659 kIPutByte,
660 kIPutChar,
661 kIPutShort,
662 kIPutWide,
663 kIdentity,
buzbee16da88c2012-03-20 10:38:17 -0700664};
665
666struct CodePattern {
Bill Buzbeea114add2012-05-03 15:00:40 -0700667 const Instruction::Code opcodes[MAX_PATTERN_LEN];
668 const SpecialCaseHandler handlerCode;
buzbee16da88c2012-03-20 10:38:17 -0700669};
670
671static const CodePattern specialPatterns[] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700672 {{Instruction::RETURN_VOID}, kNullMethod},
673 {{Instruction::CONST, Instruction::RETURN}, kConstFunction},
674 {{Instruction::CONST_4, Instruction::RETURN}, kConstFunction},
675 {{Instruction::CONST_4, Instruction::RETURN_OBJECT}, kConstFunction},
676 {{Instruction::CONST_16, Instruction::RETURN}, kConstFunction},
677 {{Instruction::IGET, Instruction:: RETURN}, kIGet},
678 {{Instruction::IGET_BOOLEAN, Instruction::RETURN}, kIGetBoolean},
679 {{Instruction::IGET_OBJECT, Instruction::RETURN_OBJECT}, kIGetObject},
680 {{Instruction::IGET_BYTE, Instruction::RETURN}, kIGetByte},
681 {{Instruction::IGET_CHAR, Instruction::RETURN}, kIGetChar},
682 {{Instruction::IGET_SHORT, Instruction::RETURN}, kIGetShort},
683 {{Instruction::IGET_WIDE, Instruction::RETURN_WIDE}, kIGetWide},
684 {{Instruction::IPUT, Instruction::RETURN_VOID}, kIPut},
685 {{Instruction::IPUT_BOOLEAN, Instruction::RETURN_VOID}, kIPutBoolean},
686 {{Instruction::IPUT_OBJECT, Instruction::RETURN_VOID}, kIPutObject},
687 {{Instruction::IPUT_BYTE, Instruction::RETURN_VOID}, kIPutByte},
688 {{Instruction::IPUT_CHAR, Instruction::RETURN_VOID}, kIPutChar},
689 {{Instruction::IPUT_SHORT, Instruction::RETURN_VOID}, kIPutShort},
690 {{Instruction::IPUT_WIDE, Instruction::RETURN_VOID}, kIPutWide},
691 {{Instruction::RETURN}, kIdentity},
692 {{Instruction::RETURN_OBJECT}, kIdentity},
693 {{Instruction::RETURN_WIDE}, kIdentity},
buzbee16da88c2012-03-20 10:38:17 -0700694};
buzbee5de34942012-03-01 14:51:57 -0800695
buzbee5abfa3e2012-01-31 17:01:43 -0800696BasicBlock* oatNewBB(CompilationUnit* cUnit, BBType blockType, int blockId);
buzbee67bf8852011-08-17 17:51:35 -0700697
698void oatAppendMIR(BasicBlock* bb, MIR* mir);
699
700void oatPrependMIR(BasicBlock* bb, MIR* mir);
701
702void oatInsertMIRAfter(BasicBlock* bb, MIR* currentMIR, MIR* newMIR);
703
704void oatAppendLIR(CompilationUnit* cUnit, LIR* lir);
705
706void oatInsertLIRBefore(LIR* currentLIR, LIR* newLIR);
707
708void oatInsertLIRAfter(LIR* currentLIR, LIR* newLIR);
709
buzbeefc9e6fa2012-03-23 15:14:29 -0700710MIR* oatFindMoveResult(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
711 bool wide);
buzbee67bf8852011-08-17 17:51:35 -0700712/* Debug Utilities */
713void oatDumpCompilationUnit(CompilationUnit* cUnit);
714
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800715} // namespace art
716
buzbee67bf8852011-08-17 17:51:35 -0700717#endif // ART_SRC_COMPILER_COMPILER_IR_H_