blob: 2e43b01de1aa7635034d62c9a9fdc5ff193e4000 [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"
buzbee2cfc6392012-05-07 14:51:40 -070026#if defined(ART_USE_QUICK_COMPILER)
27#include "greenland/ir_builder.h"
28#include "llvm/Module.h"
29#endif
buzbee67bf8852011-08-17 17:51:35 -070030
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080031namespace art {
32
buzbee31a4a6f2012-02-28 15:36:15 -080033#define SLOW_FIELD_PATH (cUnit->enableDebug & (1 << kDebugSlowFieldPath))
34#define SLOW_INVOKE_PATH (cUnit->enableDebug & (1 << kDebugSlowInvokePath))
35#define SLOW_STRING_PATH (cUnit->enableDebug & (1 << kDebugSlowStringPath))
36#define SLOW_TYPE_PATH (cUnit->enableDebug & (1 << kDebugSlowTypePath))
37#define EXERCISE_SLOWEST_FIELD_PATH (cUnit->enableDebug & \
Bill Buzbeea114add2012-05-03 15:00:40 -070038 (1 << kDebugSlowestFieldPath))
buzbee31a4a6f2012-02-28 15:36:15 -080039#define EXERCISE_SLOWEST_STRING_PATH (cUnit->enableDebug & \
Bill Buzbeea114add2012-05-03 15:00:40 -070040 (1 << kDebugSlowestStringPath))
buzbee31a4a6f2012-02-28 15:36:15 -080041#define EXERCISE_RESOLVE_METHOD (cUnit->enableDebug & \
Bill Buzbeea114add2012-05-03 15:00:40 -070042 (1 << kDebugExerciseResolveMethod))
buzbee31a4a6f2012-02-28 15:36:15 -080043
Elliott Hughes719ace42012-03-09 18:06:03 -080044enum RegisterClass {
Bill Buzbeea114add2012-05-03 15:00:40 -070045 kCoreReg,
46 kFPReg,
47 kAnyReg,
Elliott Hughes719ace42012-03-09 18:06:03 -080048};
buzbee67bf8852011-08-17 17:51:35 -070049
Elliott Hughes719ace42012-03-09 18:06:03 -080050enum RegLocationType {
Bill Buzbeea114add2012-05-03 15:00:40 -070051 kLocDalvikFrame = 0, // Normal Dalvik register
52 kLocPhysReg,
53 kLocCompilerTemp,
54 kLocInvalid
Elliott Hughes719ace42012-03-09 18:06:03 -080055};
buzbee67bf8852011-08-17 17:51:35 -070056
Elliott Hughes719ace42012-03-09 18:06:03 -080057struct PromotionMap {
Bill Buzbeea114add2012-05-03 15:00:40 -070058 RegLocationType coreLocation:3;
59 u1 coreReg;
60 RegLocationType fpLocation:3;
61 u1 fpReg;
62 bool firstInPair;
Elliott Hughes719ace42012-03-09 18:06:03 -080063};
buzbee67bc2362011-10-11 18:08:40 -070064
Elliott Hughes719ace42012-03-09 18:06:03 -080065struct RegLocation {
Bill Buzbeea114add2012-05-03 15:00:40 -070066 RegLocationType location:3;
67 unsigned wide:1;
68 unsigned defined:1; // Do we know the type?
buzbee2cfc6392012-05-07 14:51:40 -070069 unsigned isConst:1; // Constant, value in cUnit->constantValues[]
Bill Buzbeea114add2012-05-03 15:00:40 -070070 unsigned fp:1; // Floating point?
71 unsigned core:1; // Non-floating point?
buzbeebff24652012-05-06 16:22:05 -070072 unsigned ref:1; // Something GC cares about
Bill Buzbeea114add2012-05-03 15:00:40 -070073 unsigned highWord:1; // High word of pair?
74 unsigned home:1; // Does this represent the home location?
75 u1 lowReg; // First physical register
76 u1 highReg; // 2nd physical register (if wide)
77 int32_t sRegLow; // SSA name for low Dalvik word
buzbee2cfc6392012-05-07 14:51:40 -070078 int32_t origSReg; // TODO: remove after Bitcode gen complete
79 // and consolodate usage w/ sRegLow
buzbeee1965672012-03-11 18:39:19 -070080};
81
82struct CompilerTemp {
Bill Buzbeea114add2012-05-03 15:00:40 -070083 int sReg;
84 ArenaBitVector* bv;
Elliott Hughes719ace42012-03-09 18:06:03 -080085};
buzbee67bf8852011-08-17 17:51:35 -070086
buzbeee3acd072012-02-25 17:03:10 -080087 /*
88 * Data structure tracking the mapping between a Dalvik register (pair) and a
89 * native register (pair). The idea is to reuse the previously loaded value
90 * if possible, otherwise to keep the value in a native register as long as
91 * possible.
92 */
Elliott Hughes719ace42012-03-09 18:06:03 -080093struct RegisterInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -070094 int reg; // Reg number
95 bool inUse; // Has it been allocated?
96 bool isTemp; // Can allocate as temp?
97 bool pair; // Part of a register pair?
98 int partner; // If pair, other reg of pair
99 bool live; // Is there an associated SSA name?
100 bool dirty; // If live, is it dirty?
101 int sReg; // Name of live value
102 LIR *defStart; // Starting inst in last def sequence
103 LIR *defEnd; // Ending inst in last def sequence
Elliott Hughes719ace42012-03-09 18:06:03 -0800104};
buzbeee3acd072012-02-25 17:03:10 -0800105
Elliott Hughes719ace42012-03-09 18:06:03 -0800106struct RegisterPool {
Bill Buzbeea114add2012-05-03 15:00:40 -0700107 int numCoreRegs;
108 RegisterInfo *coreRegs;
109 int nextCoreReg;
110 int numFPRegs;
111 RegisterInfo *FPRegs;
112 int nextFPReg;
Elliott Hughes719ace42012-03-09 18:06:03 -0800113};
buzbeee3acd072012-02-25 17:03:10 -0800114
buzbee67bf8852011-08-17 17:51:35 -0700115#define INVALID_SREG (-1)
buzbee3ddc0d12011-10-05 10:36:21 -0700116#define INVALID_VREG (0xFFFFU)
buzbee67bc2362011-10-11 18:08:40 -0700117#define INVALID_REG (0xFF)
buzbee67bf8852011-08-17 17:51:35 -0700118#define INVALID_OFFSET (-1)
119
buzbeee1965672012-03-11 18:39:19 -0700120/* SSA encodings for special registers */
buzbee9c044ce2012-03-18 13:24:07 -0700121#define SSA_METHOD_BASEREG (-2)
buzbeee1965672012-03-11 18:39:19 -0700122/* First compiler temp basereg, grows smaller */
buzbee9c044ce2012-03-18 13:24:07 -0700123#define SSA_CTEMP_BASEREG (SSA_METHOD_BASEREG - 1)
buzbee2cfc6392012-05-07 14:51:40 -0700124/* Max SSA name length */
125#define SSA_NAME_MAX 16
buzbeee1965672012-03-11 18:39:19 -0700126
buzbee99ba9642012-01-25 14:23:14 -0800127/*
128 * Some code patterns cause the generation of excessively large
129 * methods - in particular initialization sequences. There isn't much
130 * benefit in optimizing these methods, and the cost can be very high.
131 * We attempt to identify these cases, and avoid performing most dataflow
132 * analysis. Two thresholds are used - one for known initializers and one
buzbee5abfa3e2012-01-31 17:01:43 -0800133 * for everything else.
buzbee99ba9642012-01-25 14:23:14 -0800134 */
buzbee5abfa3e2012-01-31 17:01:43 -0800135#define MANY_BLOCKS_INITIALIZER 1000 /* Threshold for switching dataflow off */
136#define MANY_BLOCKS 4000 /* Non-initializer threshold */
buzbee99ba9642012-01-25 14:23:14 -0800137
Elliott Hughes719ace42012-03-09 18:06:03 -0800138enum BBType {
Bill Buzbeea114add2012-05-03 15:00:40 -0700139 kEntryBlock,
140 kDalvikByteCode,
141 kExitBlock,
142 kExceptionHandling,
143 kCatchEntry,
Elliott Hughes719ace42012-03-09 18:06:03 -0800144};
buzbee67bf8852011-08-17 17:51:35 -0700145
buzbee31a4a6f2012-02-28 15:36:15 -0800146/* Utility macros to traverse the LIR list */
147#define NEXT_LIR(lir) (lir->next)
148#define PREV_LIR(lir) (lir->prev)
149
150#define NEXT_LIR_LVALUE(lir) (lir)->next
151#define PREV_LIR_LVALUE(lir) (lir)->prev
152
Elliott Hughes719ace42012-03-09 18:06:03 -0800153struct LIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700154 int offset; // Offset of this instruction
155 int dalvikOffset; // Offset of Dalvik opcode
156 LIR* next;
157 LIR* prev;
158 LIR* target;
159 int opcode;
160 int operands[5]; // [0..4] = [dest, src1, src2, extra, extra2]
161 struct {
162 bool isNop:1; // LIR is optimized away
163 bool pcRelFixup:1; // May need pc-relative fixup
164 unsigned int age:4; // default is 0, set lazily by the optimizer
165 unsigned int size:5; // in bytes
166 unsigned int unused:21;
167 } flags;
168 int aliasInfo; // For Dalvik register & litpool disambiguation
169 u8 useMask; // Resource mask for use
170 u8 defMask; // Resource mask for def
Elliott Hughes719ace42012-03-09 18:06:03 -0800171};
buzbee67bf8852011-08-17 17:51:35 -0700172
173enum ExtendedMIROpcode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700174 kMirOpFirst = kNumPackedOpcodes,
175 kMirOpPhi = kMirOpFirst,
176 kMirOpCopy,
177 kMirOpFusedCmplFloat,
178 kMirOpFusedCmpgFloat,
179 kMirOpFusedCmplDouble,
180 kMirOpFusedCmpgDouble,
181 kMirOpFusedCmpLong,
182 kMirOpNop,
183 kMirOpNullNRangeUpCheck,
184 kMirOpNullNRangeDownCheck,
185 kMirOpLowerBound,
186 kMirOpLast,
buzbee67bf8852011-08-17 17:51:35 -0700187};
188
189struct SSARepresentation;
190
Elliott Hughes719ace42012-03-09 18:06:03 -0800191enum MIROptimizationFlagPositons {
Bill Buzbeea114add2012-05-03 15:00:40 -0700192 kMIRIgnoreNullCheck = 0,
193 kMIRNullCheckOnly,
194 kMIRIgnoreRangeCheck,
195 kMIRRangeCheckOnly,
196 kMIRInlined, // Invoke is inlined (ie dead)
197 kMIRInlinedPred, // Invoke is inlined via prediction
198 kMIRCallee, // Instruction is inlined from callee
199 kMIRIgnoreSuspendCheck,
200 kMIRDup,
201 kMIRMark, // Temporary node mark
Elliott Hughes719ace42012-03-09 18:06:03 -0800202};
buzbee67bf8852011-08-17 17:51:35 -0700203
204#define MIR_IGNORE_NULL_CHECK (1 << kMIRIgnoreNullCheck)
205#define MIR_NULL_CHECK_ONLY (1 << kMIRNullCheckOnly)
206#define MIR_IGNORE_RANGE_CHECK (1 << kMIRIgnoreRangeCheck)
207#define MIR_RANGE_CHECK_ONLY (1 << kMIRRangeCheckOnly)
208#define MIR_INLINED (1 << kMIRInlined)
209#define MIR_INLINED_PRED (1 << kMIRInlinedPred)
210#define MIR_CALLEE (1 << kMIRCallee)
buzbeec1f45042011-09-21 16:03:19 -0700211#define MIR_IGNORE_SUSPEND_CHECK (1 << kMIRIgnoreSuspendCheck)
buzbeee1965672012-03-11 18:39:19 -0700212#define MIR_DUP (1 << kMIRDup)
buzbee239c4e72012-03-16 08:42:29 -0700213#define MIR_MARK (1 << kMIRMark)
buzbee67bf8852011-08-17 17:51:35 -0700214
Elliott Hughes719ace42012-03-09 18:06:03 -0800215struct CallsiteInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700216 const char* classDescriptor;
217 Object* classLoader;
218 const Method* method;
219 LIR* misPredBranchOver;
Elliott Hughes719ace42012-03-09 18:06:03 -0800220};
buzbee67bf8852011-08-17 17:51:35 -0700221
Elliott Hughes719ace42012-03-09 18:06:03 -0800222struct MIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700223 DecodedInstruction dalvikInsn;
224 unsigned int width;
225 unsigned int offset;
226 MIR* prev;
227 MIR* next;
228 SSARepresentation* ssaRep;
229 int optimizationFlags;
230 int seqNum;
231 union {
232 // Used by the inlined insn from the callee to find the mother method
233 const Method* calleeMethod;
234 // Used by the inlined invoke to find the class and method pointers
235 CallsiteInfo* callsiteInfo;
236 // Used to quickly locate all Phi opcodes
237 MIR* phiNext;
238 } meta;
Elliott Hughes719ace42012-03-09 18:06:03 -0800239};
buzbee67bf8852011-08-17 17:51:35 -0700240
241struct BasicBlockDataFlow;
242
243/* For successorBlockList */
Elliott Hughes719ace42012-03-09 18:06:03 -0800244enum BlockListType {
Bill Buzbeea114add2012-05-03 15:00:40 -0700245 kNotUsed = 0,
246 kCatch,
247 kPackedSwitch,
248 kSparseSwitch,
Elliott Hughes719ace42012-03-09 18:06:03 -0800249};
buzbee67bf8852011-08-17 17:51:35 -0700250
Elliott Hughes719ace42012-03-09 18:06:03 -0800251struct BasicBlock {
Bill Buzbeea114add2012-05-03 15:00:40 -0700252 int id;
253 int dfsId;
254 bool visited;
255 bool hidden;
256 bool catchEntry;
257 bool fallThroughTarget; // Reached via fallthrough
buzbee2cfc6392012-05-07 14:51:40 -0700258#if defined(ART_USE_QUICK_COMPILER)
259 bool hasReturn;
260#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700261 uint16_t startOffset;
262 uint16_t nestingDepth;
263 const Method* containingMethod; // For blocks from the callee
264 BBType blockType;
265 bool needFallThroughBranch; // For blocks ended due to length limit
266 bool isFallThroughFromInvoke; // True means the block needs alignment
267 MIR* firstMIRInsn;
268 MIR* lastMIRInsn;
269 BasicBlock* fallThrough;
270 BasicBlock* taken;
271 BasicBlock* iDom; // Immediate dominator
272 BasicBlockDataFlow* dataFlowInfo;
273 GrowableList* predecessors;
274 ArenaBitVector* dominators;
275 ArenaBitVector* iDominated; // Set nodes being immediately dominated
276 ArenaBitVector* domFrontier; // Dominance frontier
277 struct { // For one-to-many successors like
278 BlockListType blockListType; // switch and exception handling
279 GrowableList blocks;
280 } successorBlockList;
Elliott Hughes719ace42012-03-09 18:06:03 -0800281};
buzbee67bf8852011-08-17 17:51:35 -0700282
283/*
284 * The "blocks" field in "successorBlockList" points to an array of
285 * elements with the type "SuccessorBlockInfo".
286 * For catch blocks, key is type index for the exception.
287 * For swtich blocks, key is the case value.
288 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800289struct SuccessorBlockInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700290 BasicBlock* block;
291 int key;
Elliott Hughes719ace42012-03-09 18:06:03 -0800292};
buzbee67bf8852011-08-17 17:51:35 -0700293
294struct LoopAnalysis;
295struct RegisterPool;
buzbeeba938cb2012-02-03 14:47:55 -0800296struct ArenaMemBlock;
297struct Memstats;
buzbee67bf8852011-08-17 17:51:35 -0700298
Elliott Hughes719ace42012-03-09 18:06:03 -0800299enum AssemblerStatus {
Bill Buzbeea114add2012-05-03 15:00:40 -0700300 kSuccess,
301 kRetryAll,
302 kRetryHalve
Elliott Hughes719ace42012-03-09 18:06:03 -0800303};
buzbee67bf8852011-08-17 17:51:35 -0700304
buzbee5b537102012-01-17 17:33:47 -0800305#define NOTVISITED (-1)
306
Elliott Hughes719ace42012-03-09 18:06:03 -0800307struct CompilationUnit {
Elliott Hughese52e49b2012-04-02 16:05:44 -0700308 CompilationUnit()
Bill Buzbeea114add2012-05-03 15:00:40 -0700309 : numBlocks(0),
310 compiler(NULL),
311 class_linker(NULL),
312 dex_file(NULL),
313 dex_cache(NULL),
314 class_loader(NULL),
315 method_idx(0),
316 code_item(NULL),
317 access_flags(0),
318 shorty(NULL),
319 firstLIRInsn(NULL),
320 lastLIRInsn(NULL),
321 literalList(NULL),
322 methodLiteralList(NULL),
323 codeLiteralList(NULL),
324 classPointerList(NULL),
325 numClassPointers(0),
326 chainCellOffsetLIR(NULL),
327 disableOpt(0),
328 enableDebug(0),
329 headerSize(0),
330 dataOffset(0),
331 totalSize(0),
332 assemblerStatus(kSuccess),
333 assemblerRetries(0),
334 genDebugger(false),
335 printMe(false),
336 hasClassLiterals(false),
337 hasLoop(false),
338 hasInvoke(false),
339 heapMemOp(false),
340 qdMode(false),
341 usesLinkRegister(false),
342 methodTraceSupport(false),
343 regPool(NULL),
344 optRound(0),
345 instructionSet(kNone),
346 numSSARegs(0),
347 ssaBaseVRegs(NULL),
348 ssaSubscripts(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700349 ssaStrings(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700350 vRegToSSAMap(NULL),
351 SSALastDefs(NULL),
352 isConstantV(NULL),
353 constantValues(NULL),
354 phiAliasMap(NULL),
355 phiList(NULL),
356 regLocation(NULL),
357 sequenceNumber(0),
358 promotionMap(NULL),
359 methodSReg(0),
360 switchOverflowPad(NULL),
361 numReachableBlocks(0),
362 numDalvikRegisters(0),
363 entryBlock(NULL),
364 exitBlock(NULL),
365 curBlock(NULL),
366 nextCodegenBlock(NULL),
367 iDomList(NULL),
368 tryBlockAddr(NULL),
369 defBlockMatrix(NULL),
370 tempBlockV(NULL),
371 tempDalvikRegisterV(NULL),
372 tempSSARegisterV(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700373 tempSSABlockIdV(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700374 printSSANames(false),
375 blockLabelList(NULL),
376 quitLoopMode(false),
377 preservedRegsUsed(0),
378 numIns(0),
379 numOuts(0),
380 numRegs(0),
381 numCoreSpills(0),
382 numFPSpills(0),
383 numCompilerTemps(0),
384 frameSize(0),
385 coreSpillMask(0U),
386 fpSpillMask(0U),
387 attrs(0U),
388 currentDalvikOffset(0),
389 insns(NULL),
390 insnsSize(0U),
391 disableDataflow(false),
392 defCount(0),
393 compilerFlipMatch(false),
394 arenaHead(NULL),
395 currentArena(NULL),
396 numArenaBlocks(0),
397 mstats(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700398#if defined(ART_USE_QUICK_COMPILER)
399 genBitcode(false),
400 context(NULL),
401 module(NULL),
402 func(NULL),
403 intrinsic_helper(NULL),
404 irb(NULL),
405 placeholderBB(NULL),
406 entryBB(NULL),
407 tempName(0),
Elliott Hughese52e49b2012-04-02 16:05:44 -0700408#endif
buzbee2cfc6392012-05-07 14:51:40 -0700409#ifndef NDEBUG
410 liveSReg(0),
411#endif
412 opcodeCount(NULL) {}
Elliott Hughese52e49b2012-04-02 16:05:44 -0700413
Bill Buzbeea114add2012-05-03 15:00:40 -0700414 int numBlocks;
415 GrowableList blockList;
416 Compiler* compiler; // Compiler driving this compiler
417 ClassLinker* class_linker; // Linker to resolve fields and methods
418 const DexFile* dex_file; // DexFile containing the method being compiled
419 DexCache* dex_cache; // DexFile's corresponding cache
420 const ClassLoader* class_loader; // compiling method's class loader
421 uint32_t method_idx; // compiling method's index into method_ids of DexFile
422 const DexFile::CodeItem* code_item; // compiling method's DexFile code_item
423 uint32_t access_flags; // compiling method's access flags
424 const char* shorty; // compiling method's shorty
425 LIR* firstLIRInsn;
426 LIR* lastLIRInsn;
427 LIR* literalList; // Constants
428 LIR* methodLiteralList; // Method literals requiring patching
429 LIR* codeLiteralList; // Code literals requiring patching
430 LIR* classPointerList; // Relocatable
431 int numClassPointers;
432 LIR* chainCellOffsetLIR;
433 uint32_t disableOpt; // optControlVector flags
434 uint32_t enableDebug; // debugControlVector flags
435 int headerSize; // bytes before the first code ptr
436 int dataOffset; // starting offset of literal pool
437 int totalSize; // header + code size
438 AssemblerStatus assemblerStatus; // Success or fix and retry
439 int assemblerRetries;
440 std::vector<uint8_t> codeBuffer;
441 std::vector<uint32_t> mappingTable;
442 std::vector<uint16_t> coreVmapTable;
443 std::vector<uint16_t> fpVmapTable;
444 bool genDebugger; // Generate code for debugger
445 bool printMe;
446 bool hasClassLiterals; // Contains class ptrs used as literals
447 bool hasLoop; // Contains a loop
448 bool hasInvoke; // Contains an invoke instruction
449 bool heapMemOp; // Mark mem ops for self verification
450 bool qdMode; // Compile for code size/compile time
451 bool usesLinkRegister; // For self-verification only
452 bool methodTraceSupport; // For TraceView profiling
453 RegisterPool* regPool;
454 int optRound; // round number to tell an LIR's age
455 InstructionSet instructionSet;
456 /* Number of total regs used in the whole cUnit after SSA transformation */
457 int numSSARegs;
458 /* Map SSA reg i to the base virtual register/subscript */
459 GrowableList* ssaBaseVRegs;
460 GrowableList* ssaSubscripts;
buzbee2cfc6392012-05-07 14:51:40 -0700461 GrowableList* ssaStrings;
buzbee67bf8852011-08-17 17:51:35 -0700462
Bill Buzbeea114add2012-05-03 15:00:40 -0700463 /* The following are new data structures to support SSA representations */
464 /* Map original Dalvik virtual reg i to the current SSA name */
465 int* vRegToSSAMap; // length == method->registersSize
466 int* SSALastDefs; // length == method->registersSize
467 ArenaBitVector* isConstantV; // length == numSSAReg
468 int* constantValues; // length == numSSAReg
469 int* phiAliasMap; // length == numSSAReg
470 MIR* phiList;
buzbee67bf8852011-08-17 17:51:35 -0700471
Bill Buzbeea114add2012-05-03 15:00:40 -0700472 /* Use counts of ssa names */
473 GrowableList useCounts; // Weighted by nesting depth
474 GrowableList rawUseCounts; // Not weighted
buzbee239c4e72012-03-16 08:42:29 -0700475
Bill Buzbeea114add2012-05-03 15:00:40 -0700476 /* Optimization support */
477 GrowableList loopHeaders;
buzbee239c4e72012-03-16 08:42:29 -0700478
Bill Buzbeea114add2012-05-03 15:00:40 -0700479 /* Map SSA names to location */
480 RegLocation* regLocation;
481 int sequenceNumber;
buzbee67bf8852011-08-17 17:51:35 -0700482
Bill Buzbeea114add2012-05-03 15:00:40 -0700483 /* Keep track of Dalvik vReg to physical register mappings */
484 PromotionMap* promotionMap;
buzbee67bc2362011-10-11 18:08:40 -0700485
Bill Buzbeea114add2012-05-03 15:00:40 -0700486 /* SSA name for Method* */
487 int methodSReg;
buzbeee1965672012-03-11 18:39:19 -0700488
Bill Buzbeea114add2012-05-03 15:00:40 -0700489 /*
490 * Set to the Dalvik PC of the switch instruction if it has more than
491 * MAX_CHAINED_SWITCH_CASES cases.
492 */
493 const u2* switchOverflowPad;
buzbee67bf8852011-08-17 17:51:35 -0700494
Bill Buzbeea114add2012-05-03 15:00:40 -0700495 int numReachableBlocks;
496 int numDalvikRegisters; // method->registersSize
497 BasicBlock* entryBlock;
498 BasicBlock* exitBlock;
499 BasicBlock* curBlock;
500 BasicBlock* nextCodegenBlock; // for extended trace codegen
501 GrowableList dfsOrder;
502 GrowableList dfsPostOrder;
503 GrowableList domPostOrderTraversal;
504 GrowableList throwLaunchpads;
505 GrowableList suspendLaunchpads;
506 GrowableList intrinsicLaunchpads;
507 GrowableList compilerTemps;
508 int* iDomList;
509 ArenaBitVector* tryBlockAddr;
510 ArenaBitVector** defBlockMatrix; // numDalvikRegister x numBlocks
511 ArenaBitVector* tempBlockV;
512 ArenaBitVector* tempDalvikRegisterV;
513 ArenaBitVector* tempSSARegisterV; // numSSARegs
buzbee2cfc6392012-05-07 14:51:40 -0700514 int* tempSSABlockIdV; // working storage for Phi labels
Bill Buzbeea114add2012-05-03 15:00:40 -0700515 bool printSSANames;
516 void* blockLabelList;
517 bool quitLoopMode; // cold path/complex bytecode
518 int preservedRegsUsed; // How many callee save regs used
519 /*
520 * Frame layout details.
521 * NOTE: for debug support it will be necessary to add a structure
522 * to map the Dalvik virtual registers to the promoted registers.
523 * NOTE: "num" fields are in 4-byte words, "Size" and "Offset" in bytes.
524 */
525 int numIns;
526 int numOuts;
527 int numRegs; // Unlike numDalvikRegisters, does not include ins
528 int numCoreSpills;
529 int numFPSpills;
530 int numCompilerTemps;
531 int frameSize;
532 unsigned int coreSpillMask;
533 unsigned int fpSpillMask;
534 unsigned int attrs;
535 /*
536 * CLEANUP/RESTRUCTURE: The code generation utilities don't have a built-in
537 * mechanism to propagate the original Dalvik opcode address to the
538 * associated generated instructions. For the trace compiler, this wasn't
539 * necessary because the interpreter handled all throws and debugging
540 * requests. For now we'll handle this by placing the Dalvik offset
541 * in the CompilationUnit struct before codegen for each instruction.
542 * The low-level LIR creation utilites will pull it from here. Should
543 * be rewritten.
544 */
545 int currentDalvikOffset;
546 GrowableList switchTables;
547 GrowableList fillArrayData;
548 const u2* insns;
549 u4 insnsSize;
550 bool disableDataflow; // Skip dataflow analysis if possible
551 SafeMap<unsigned int, BasicBlock*> blockMap; // findBlock lookup cache
552 SafeMap<unsigned int, LIR*> boundaryMap; // boundary lookup cache
553 int defCount; // Used to estimate number of SSA names
Elliott Hughese52e49b2012-04-02 16:05:44 -0700554
Bill Buzbeea114add2012-05-03 15:00:40 -0700555 // If non-empty, apply optimizer/debug flags only to matching methods.
556 std::string compilerMethodMatch;
557 // Flips sense of compilerMethodMatch - apply flags if doesn't match.
558 bool compilerFlipMatch;
559 ArenaMemBlock* arenaHead;
560 ArenaMemBlock* currentArena;
561 int numArenaBlocks;
562 Memstats* mstats;
buzbee2cfc6392012-05-07 14:51:40 -0700563#if defined(ART_USE_QUICK_COMPILER)
564 bool genBitcode;
565 llvm::LLVMContext* context;
566 llvm::Module* module;
567 llvm::Function* func;
568 greenland::IntrinsicHelper* intrinsic_helper;
569 greenland::IRBuilder* irb;
570 llvm::BasicBlock* placeholderBB;
571 llvm::BasicBlock* entryBB;
572 std::string bitcode_filename;
573 GrowableList llvmValues;
574 int32_t tempName;
575 SafeMap<llvm::BasicBlock*, LIR*> blockToLabelMap; // llvm bb -> LIR label
576 SafeMap<int32_t, llvm::BasicBlock*> idToBlockMap; // block id -> llvm bb
577 SafeMap<llvm::Value*, RegLocation> locMap; // llvm Value to loc rec
578#endif
buzbee3d661942012-03-14 17:37:27 -0700579#ifndef NDEBUG
Bill Buzbeea114add2012-05-03 15:00:40 -0700580 /*
581 * Sanity checking for the register temp tracking. The same ssa
582 * name should never be associated with one temp register per
583 * instruction compilation.
584 */
585 int liveSReg;
buzbee3d661942012-03-14 17:37:27 -0700586#endif
buzbee2cfc6392012-05-07 14:51:40 -0700587 int* opcodeCount; // Count Dalvik opcodes for tuning
Elliott Hughes719ace42012-03-09 18:06:03 -0800588};
buzbee67bf8852011-08-17 17:51:35 -0700589
Elliott Hughes719ace42012-03-09 18:06:03 -0800590enum OpSize {
Bill Buzbeea114add2012-05-03 15:00:40 -0700591 kWord,
592 kLong,
593 kSingle,
594 kDouble,
595 kUnsignedHalf,
596 kSignedHalf,
597 kUnsignedByte,
598 kSignedByte,
Elliott Hughes719ace42012-03-09 18:06:03 -0800599};
buzbeee3acd072012-02-25 17:03:10 -0800600
Elliott Hughes719ace42012-03-09 18:06:03 -0800601enum OpKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700602 kOpMov,
603 kOpMvn,
604 kOpCmp,
605 kOpLsl,
606 kOpLsr,
607 kOpAsr,
608 kOpRor,
609 kOpNot,
610 kOpAnd,
611 kOpOr,
612 kOpXor,
613 kOpNeg,
614 kOpAdd,
615 kOpAdc,
616 kOpSub,
617 kOpSbc,
618 kOpRsub,
619 kOpMul,
620 kOpDiv,
621 kOpRem,
622 kOpBic,
623 kOpCmn,
624 kOpTst,
625 kOpBkpt,
626 kOpBlx,
627 kOpPush,
628 kOpPop,
629 kOp2Char,
630 kOp2Short,
631 kOp2Byte,
632 kOpCondBr,
633 kOpUncondBr,
634 kOpBx,
635 kOpInvalid,
Elliott Hughes719ace42012-03-09 18:06:03 -0800636};
buzbee31a4a6f2012-02-28 15:36:15 -0800637
Ian Rogers680b1bd2012-03-07 20:18:49 -0800638std::ostream& operator<<(std::ostream& os, const OpKind& kind);
639
Elliott Hughes719ace42012-03-09 18:06:03 -0800640enum ConditionCode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700641 kCondEq, // equal
642 kCondNe, // not equal
643 kCondCs, // carry set (unsigned less than)
644 kCondUlt = kCondCs,
645 kCondCc, // carry clear (unsigned greater than or same)
646 kCondUge = kCondCc,
647 kCondMi, // minus
648 kCondPl, // plus, positive or zero
649 kCondVs, // overflow
650 kCondVc, // no overflow
651 kCondHi, // unsigned greater than
652 kCondLs, // unsigned lower or same
653 kCondGe, // signed greater than or equal
654 kCondLt, // signed less than
655 kCondGt, // signed greater than
656 kCondLe, // signed less than or equal
657 kCondAl, // always
658 kCondNv, // never
Elliott Hughes719ace42012-03-09 18:06:03 -0800659};
buzbee31a4a6f2012-02-28 15:36:15 -0800660
Elliott Hughes719ace42012-03-09 18:06:03 -0800661enum ThrowKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700662 kThrowNullPointer,
663 kThrowDivZero,
664 kThrowArrayBounds,
665 kThrowVerificationError,
666 kThrowNoSuchMethod,
667 kThrowStackOverflow,
Elliott Hughes719ace42012-03-09 18:06:03 -0800668};
buzbee31a4a6f2012-02-28 15:36:15 -0800669
Elliott Hughes719ace42012-03-09 18:06:03 -0800670struct SwitchTable {
Bill Buzbeea114add2012-05-03 15:00:40 -0700671 int offset;
672 const u2* table; // Original dex table
673 int vaddr; // Dalvik offset of switch opcode
674 LIR* anchor; // Reference instruction for relative offsets
675 LIR** targets; // Array of case targets
Elliott Hughes719ace42012-03-09 18:06:03 -0800676};
buzbee5de34942012-03-01 14:51:57 -0800677
Elliott Hughes719ace42012-03-09 18:06:03 -0800678struct FillArrayData {
Bill Buzbeea114add2012-05-03 15:00:40 -0700679 int offset;
680 const u2* table; // Original dex table
681 int size;
682 int vaddr; // Dalvik offset of FILL_ARRAY_DATA opcode
Elliott Hughes719ace42012-03-09 18:06:03 -0800683};
buzbee5de34942012-03-01 14:51:57 -0800684
buzbee16da88c2012-03-20 10:38:17 -0700685#define MAX_PATTERN_LEN 5
686
687enum SpecialCaseHandler {
Bill Buzbeea114add2012-05-03 15:00:40 -0700688 kNoHandler,
689 kNullMethod,
690 kConstFunction,
691 kIGet,
692 kIGetBoolean,
693 kIGetObject,
694 kIGetByte,
695 kIGetChar,
696 kIGetShort,
697 kIGetWide,
698 kIPut,
699 kIPutBoolean,
700 kIPutObject,
701 kIPutByte,
702 kIPutChar,
703 kIPutShort,
704 kIPutWide,
705 kIdentity,
buzbee16da88c2012-03-20 10:38:17 -0700706};
707
708struct CodePattern {
Bill Buzbeea114add2012-05-03 15:00:40 -0700709 const Instruction::Code opcodes[MAX_PATTERN_LEN];
710 const SpecialCaseHandler handlerCode;
buzbee16da88c2012-03-20 10:38:17 -0700711};
712
713static const CodePattern specialPatterns[] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700714 {{Instruction::RETURN_VOID}, kNullMethod},
715 {{Instruction::CONST, Instruction::RETURN}, kConstFunction},
716 {{Instruction::CONST_4, Instruction::RETURN}, kConstFunction},
717 {{Instruction::CONST_4, Instruction::RETURN_OBJECT}, kConstFunction},
718 {{Instruction::CONST_16, Instruction::RETURN}, kConstFunction},
719 {{Instruction::IGET, Instruction:: RETURN}, kIGet},
720 {{Instruction::IGET_BOOLEAN, Instruction::RETURN}, kIGetBoolean},
721 {{Instruction::IGET_OBJECT, Instruction::RETURN_OBJECT}, kIGetObject},
722 {{Instruction::IGET_BYTE, Instruction::RETURN}, kIGetByte},
723 {{Instruction::IGET_CHAR, Instruction::RETURN}, kIGetChar},
724 {{Instruction::IGET_SHORT, Instruction::RETURN}, kIGetShort},
725 {{Instruction::IGET_WIDE, Instruction::RETURN_WIDE}, kIGetWide},
726 {{Instruction::IPUT, Instruction::RETURN_VOID}, kIPut},
727 {{Instruction::IPUT_BOOLEAN, Instruction::RETURN_VOID}, kIPutBoolean},
728 {{Instruction::IPUT_OBJECT, Instruction::RETURN_VOID}, kIPutObject},
729 {{Instruction::IPUT_BYTE, Instruction::RETURN_VOID}, kIPutByte},
730 {{Instruction::IPUT_CHAR, Instruction::RETURN_VOID}, kIPutChar},
731 {{Instruction::IPUT_SHORT, Instruction::RETURN_VOID}, kIPutShort},
732 {{Instruction::IPUT_WIDE, Instruction::RETURN_VOID}, kIPutWide},
733 {{Instruction::RETURN}, kIdentity},
734 {{Instruction::RETURN_OBJECT}, kIdentity},
735 {{Instruction::RETURN_WIDE}, kIdentity},
buzbee16da88c2012-03-20 10:38:17 -0700736};
buzbee5de34942012-03-01 14:51:57 -0800737
buzbee5abfa3e2012-01-31 17:01:43 -0800738BasicBlock* oatNewBB(CompilationUnit* cUnit, BBType blockType, int blockId);
buzbee67bf8852011-08-17 17:51:35 -0700739
740void oatAppendMIR(BasicBlock* bb, MIR* mir);
741
742void oatPrependMIR(BasicBlock* bb, MIR* mir);
743
744void oatInsertMIRAfter(BasicBlock* bb, MIR* currentMIR, MIR* newMIR);
745
746void oatAppendLIR(CompilationUnit* cUnit, LIR* lir);
747
748void oatInsertLIRBefore(LIR* currentLIR, LIR* newLIR);
749
750void oatInsertLIRAfter(LIR* currentLIR, LIR* newLIR);
751
buzbeefc9e6fa2012-03-23 15:14:29 -0700752MIR* oatFindMoveResult(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
753 bool wide);
buzbee67bf8852011-08-17 17:51:35 -0700754/* Debug Utilities */
755void oatDumpCompilationUnit(CompilationUnit* cUnit);
756
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800757} // namespace art
758
buzbee67bf8852011-08-17 17:51:35 -0700759#endif // ART_SRC_COMPILER_COMPILER_IR_H_