blob: e9a26562e283ff5d5dd9dfb49e1a57d4b885dcee [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),
buzbeeb03f4872012-06-11 15:22:11 -0700408 requireShadowFrame(false),
409 numShadowFrameEntries(0),
410 shadowMap(NULL),
Elliott Hughese52e49b2012-04-02 16:05:44 -0700411#endif
buzbee2cfc6392012-05-07 14:51:40 -0700412#ifndef NDEBUG
413 liveSReg(0),
414#endif
415 opcodeCount(NULL) {}
Elliott Hughese52e49b2012-04-02 16:05:44 -0700416
Bill Buzbeea114add2012-05-03 15:00:40 -0700417 int numBlocks;
418 GrowableList blockList;
419 Compiler* compiler; // Compiler driving this compiler
420 ClassLinker* class_linker; // Linker to resolve fields and methods
421 const DexFile* dex_file; // DexFile containing the method being compiled
422 DexCache* dex_cache; // DexFile's corresponding cache
423 const ClassLoader* class_loader; // compiling method's class loader
424 uint32_t method_idx; // compiling method's index into method_ids of DexFile
425 const DexFile::CodeItem* code_item; // compiling method's DexFile code_item
426 uint32_t access_flags; // compiling method's access flags
427 const char* shorty; // compiling method's shorty
428 LIR* firstLIRInsn;
429 LIR* lastLIRInsn;
430 LIR* literalList; // Constants
431 LIR* methodLiteralList; // Method literals requiring patching
432 LIR* codeLiteralList; // Code literals requiring patching
433 LIR* classPointerList; // Relocatable
434 int numClassPointers;
435 LIR* chainCellOffsetLIR;
436 uint32_t disableOpt; // optControlVector flags
437 uint32_t enableDebug; // debugControlVector flags
438 int headerSize; // bytes before the first code ptr
439 int dataOffset; // starting offset of literal pool
440 int totalSize; // header + code size
441 AssemblerStatus assemblerStatus; // Success or fix and retry
442 int assemblerRetries;
443 std::vector<uint8_t> codeBuffer;
444 std::vector<uint32_t> mappingTable;
445 std::vector<uint16_t> coreVmapTable;
446 std::vector<uint16_t> fpVmapTable;
447 bool genDebugger; // Generate code for debugger
448 bool printMe;
449 bool hasClassLiterals; // Contains class ptrs used as literals
450 bool hasLoop; // Contains a loop
451 bool hasInvoke; // Contains an invoke instruction
452 bool heapMemOp; // Mark mem ops for self verification
453 bool qdMode; // Compile for code size/compile time
454 bool usesLinkRegister; // For self-verification only
455 bool methodTraceSupport; // For TraceView profiling
456 RegisterPool* regPool;
457 int optRound; // round number to tell an LIR's age
458 InstructionSet instructionSet;
459 /* Number of total regs used in the whole cUnit after SSA transformation */
460 int numSSARegs;
461 /* Map SSA reg i to the base virtual register/subscript */
462 GrowableList* ssaBaseVRegs;
463 GrowableList* ssaSubscripts;
buzbee2cfc6392012-05-07 14:51:40 -0700464 GrowableList* ssaStrings;
buzbee67bf8852011-08-17 17:51:35 -0700465
Bill Buzbeea114add2012-05-03 15:00:40 -0700466 /* The following are new data structures to support SSA representations */
467 /* Map original Dalvik virtual reg i to the current SSA name */
468 int* vRegToSSAMap; // length == method->registersSize
469 int* SSALastDefs; // length == method->registersSize
470 ArenaBitVector* isConstantV; // length == numSSAReg
471 int* constantValues; // length == numSSAReg
472 int* phiAliasMap; // length == numSSAReg
473 MIR* phiList;
buzbee67bf8852011-08-17 17:51:35 -0700474
Bill Buzbeea114add2012-05-03 15:00:40 -0700475 /* Use counts of ssa names */
476 GrowableList useCounts; // Weighted by nesting depth
477 GrowableList rawUseCounts; // Not weighted
buzbee239c4e72012-03-16 08:42:29 -0700478
Bill Buzbeea114add2012-05-03 15:00:40 -0700479 /* Optimization support */
480 GrowableList loopHeaders;
buzbee239c4e72012-03-16 08:42:29 -0700481
Bill Buzbeea114add2012-05-03 15:00:40 -0700482 /* Map SSA names to location */
483 RegLocation* regLocation;
484 int sequenceNumber;
buzbee67bf8852011-08-17 17:51:35 -0700485
Bill Buzbeea114add2012-05-03 15:00:40 -0700486 /* Keep track of Dalvik vReg to physical register mappings */
487 PromotionMap* promotionMap;
buzbee67bc2362011-10-11 18:08:40 -0700488
Bill Buzbeea114add2012-05-03 15:00:40 -0700489 /* SSA name for Method* */
490 int methodSReg;
buzbeee1965672012-03-11 18:39:19 -0700491
Bill Buzbeea114add2012-05-03 15:00:40 -0700492 /*
493 * Set to the Dalvik PC of the switch instruction if it has more than
494 * MAX_CHAINED_SWITCH_CASES cases.
495 */
496 const u2* switchOverflowPad;
buzbee67bf8852011-08-17 17:51:35 -0700497
Bill Buzbeea114add2012-05-03 15:00:40 -0700498 int numReachableBlocks;
499 int numDalvikRegisters; // method->registersSize
500 BasicBlock* entryBlock;
501 BasicBlock* exitBlock;
502 BasicBlock* curBlock;
503 BasicBlock* nextCodegenBlock; // for extended trace codegen
504 GrowableList dfsOrder;
505 GrowableList dfsPostOrder;
506 GrowableList domPostOrderTraversal;
507 GrowableList throwLaunchpads;
508 GrowableList suspendLaunchpads;
509 GrowableList intrinsicLaunchpads;
510 GrowableList compilerTemps;
511 int* iDomList;
512 ArenaBitVector* tryBlockAddr;
513 ArenaBitVector** defBlockMatrix; // numDalvikRegister x numBlocks
514 ArenaBitVector* tempBlockV;
515 ArenaBitVector* tempDalvikRegisterV;
516 ArenaBitVector* tempSSARegisterV; // numSSARegs
buzbee2cfc6392012-05-07 14:51:40 -0700517 int* tempSSABlockIdV; // working storage for Phi labels
Bill Buzbeea114add2012-05-03 15:00:40 -0700518 bool printSSANames;
519 void* blockLabelList;
520 bool quitLoopMode; // cold path/complex bytecode
521 int preservedRegsUsed; // How many callee save regs used
522 /*
523 * Frame layout details.
524 * NOTE: for debug support it will be necessary to add a structure
525 * to map the Dalvik virtual registers to the promoted registers.
526 * NOTE: "num" fields are in 4-byte words, "Size" and "Offset" in bytes.
527 */
528 int numIns;
529 int numOuts;
530 int numRegs; // Unlike numDalvikRegisters, does not include ins
531 int numCoreSpills;
532 int numFPSpills;
533 int numCompilerTemps;
534 int frameSize;
535 unsigned int coreSpillMask;
536 unsigned int fpSpillMask;
537 unsigned int attrs;
538 /*
539 * CLEANUP/RESTRUCTURE: The code generation utilities don't have a built-in
540 * mechanism to propagate the original Dalvik opcode address to the
541 * associated generated instructions. For the trace compiler, this wasn't
542 * necessary because the interpreter handled all throws and debugging
543 * requests. For now we'll handle this by placing the Dalvik offset
544 * in the CompilationUnit struct before codegen for each instruction.
545 * The low-level LIR creation utilites will pull it from here. Should
546 * be rewritten.
547 */
548 int currentDalvikOffset;
549 GrowableList switchTables;
550 GrowableList fillArrayData;
551 const u2* insns;
552 u4 insnsSize;
553 bool disableDataflow; // Skip dataflow analysis if possible
554 SafeMap<unsigned int, BasicBlock*> blockMap; // findBlock lookup cache
555 SafeMap<unsigned int, LIR*> boundaryMap; // boundary lookup cache
556 int defCount; // Used to estimate number of SSA names
Elliott Hughese52e49b2012-04-02 16:05:44 -0700557
Bill Buzbeea114add2012-05-03 15:00:40 -0700558 // If non-empty, apply optimizer/debug flags only to matching methods.
559 std::string compilerMethodMatch;
560 // Flips sense of compilerMethodMatch - apply flags if doesn't match.
561 bool compilerFlipMatch;
562 ArenaMemBlock* arenaHead;
563 ArenaMemBlock* currentArena;
564 int numArenaBlocks;
565 Memstats* mstats;
buzbee2cfc6392012-05-07 14:51:40 -0700566#if defined(ART_USE_QUICK_COMPILER)
567 bool genBitcode;
568 llvm::LLVMContext* context;
569 llvm::Module* module;
570 llvm::Function* func;
571 greenland::IntrinsicHelper* intrinsic_helper;
572 greenland::IRBuilder* irb;
573 llvm::BasicBlock* placeholderBB;
574 llvm::BasicBlock* entryBB;
575 std::string bitcode_filename;
576 GrowableList llvmValues;
577 int32_t tempName;
578 SafeMap<llvm::BasicBlock*, LIR*> blockToLabelMap; // llvm bb -> LIR label
579 SafeMap<int32_t, llvm::BasicBlock*> idToBlockMap; // block id -> llvm bb
580 SafeMap<llvm::Value*, RegLocation> locMap; // llvm Value to loc rec
buzbeeb03f4872012-06-11 15:22:11 -0700581 bool requireShadowFrame;
582 int numShadowFrameEntries;
583 int* shadowMap;
buzbee2cfc6392012-05-07 14:51:40 -0700584#endif
buzbee3d661942012-03-14 17:37:27 -0700585#ifndef NDEBUG
Bill Buzbeea114add2012-05-03 15:00:40 -0700586 /*
587 * Sanity checking for the register temp tracking. The same ssa
588 * name should never be associated with one temp register per
589 * instruction compilation.
590 */
591 int liveSReg;
buzbee3d661942012-03-14 17:37:27 -0700592#endif
buzbee2cfc6392012-05-07 14:51:40 -0700593 int* opcodeCount; // Count Dalvik opcodes for tuning
Elliott Hughes719ace42012-03-09 18:06:03 -0800594};
buzbee67bf8852011-08-17 17:51:35 -0700595
Elliott Hughes719ace42012-03-09 18:06:03 -0800596enum OpSize {
Bill Buzbeea114add2012-05-03 15:00:40 -0700597 kWord,
598 kLong,
599 kSingle,
600 kDouble,
601 kUnsignedHalf,
602 kSignedHalf,
603 kUnsignedByte,
604 kSignedByte,
Elliott Hughes719ace42012-03-09 18:06:03 -0800605};
buzbeee3acd072012-02-25 17:03:10 -0800606
Elliott Hughes719ace42012-03-09 18:06:03 -0800607enum OpKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700608 kOpMov,
609 kOpMvn,
610 kOpCmp,
611 kOpLsl,
612 kOpLsr,
613 kOpAsr,
614 kOpRor,
615 kOpNot,
616 kOpAnd,
617 kOpOr,
618 kOpXor,
619 kOpNeg,
620 kOpAdd,
621 kOpAdc,
622 kOpSub,
623 kOpSbc,
624 kOpRsub,
625 kOpMul,
626 kOpDiv,
627 kOpRem,
628 kOpBic,
629 kOpCmn,
630 kOpTst,
631 kOpBkpt,
632 kOpBlx,
633 kOpPush,
634 kOpPop,
635 kOp2Char,
636 kOp2Short,
637 kOp2Byte,
638 kOpCondBr,
639 kOpUncondBr,
640 kOpBx,
641 kOpInvalid,
Elliott Hughes719ace42012-03-09 18:06:03 -0800642};
buzbee31a4a6f2012-02-28 15:36:15 -0800643
Ian Rogers680b1bd2012-03-07 20:18:49 -0800644std::ostream& operator<<(std::ostream& os, const OpKind& kind);
645
Elliott Hughes719ace42012-03-09 18:06:03 -0800646enum ConditionCode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700647 kCondEq, // equal
648 kCondNe, // not equal
649 kCondCs, // carry set (unsigned less than)
650 kCondUlt = kCondCs,
651 kCondCc, // carry clear (unsigned greater than or same)
652 kCondUge = kCondCc,
653 kCondMi, // minus
654 kCondPl, // plus, positive or zero
655 kCondVs, // overflow
656 kCondVc, // no overflow
657 kCondHi, // unsigned greater than
658 kCondLs, // unsigned lower or same
659 kCondGe, // signed greater than or equal
660 kCondLt, // signed less than
661 kCondGt, // signed greater than
662 kCondLe, // signed less than or equal
663 kCondAl, // always
664 kCondNv, // never
Elliott Hughes719ace42012-03-09 18:06:03 -0800665};
buzbee31a4a6f2012-02-28 15:36:15 -0800666
Elliott Hughes719ace42012-03-09 18:06:03 -0800667enum ThrowKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700668 kThrowNullPointer,
669 kThrowDivZero,
670 kThrowArrayBounds,
671 kThrowVerificationError,
672 kThrowNoSuchMethod,
673 kThrowStackOverflow,
Elliott Hughes719ace42012-03-09 18:06:03 -0800674};
buzbee31a4a6f2012-02-28 15:36:15 -0800675
Elliott Hughes719ace42012-03-09 18:06:03 -0800676struct SwitchTable {
Bill Buzbeea114add2012-05-03 15:00:40 -0700677 int offset;
678 const u2* table; // Original dex table
679 int vaddr; // Dalvik offset of switch opcode
680 LIR* anchor; // Reference instruction for relative offsets
681 LIR** targets; // Array of case targets
Elliott Hughes719ace42012-03-09 18:06:03 -0800682};
buzbee5de34942012-03-01 14:51:57 -0800683
Elliott Hughes719ace42012-03-09 18:06:03 -0800684struct FillArrayData {
Bill Buzbeea114add2012-05-03 15:00:40 -0700685 int offset;
686 const u2* table; // Original dex table
687 int size;
688 int vaddr; // Dalvik offset of FILL_ARRAY_DATA opcode
Elliott Hughes719ace42012-03-09 18:06:03 -0800689};
buzbee5de34942012-03-01 14:51:57 -0800690
buzbee16da88c2012-03-20 10:38:17 -0700691#define MAX_PATTERN_LEN 5
692
693enum SpecialCaseHandler {
Bill Buzbeea114add2012-05-03 15:00:40 -0700694 kNoHandler,
695 kNullMethod,
696 kConstFunction,
697 kIGet,
698 kIGetBoolean,
699 kIGetObject,
700 kIGetByte,
701 kIGetChar,
702 kIGetShort,
703 kIGetWide,
704 kIPut,
705 kIPutBoolean,
706 kIPutObject,
707 kIPutByte,
708 kIPutChar,
709 kIPutShort,
710 kIPutWide,
711 kIdentity,
buzbee16da88c2012-03-20 10:38:17 -0700712};
713
714struct CodePattern {
Bill Buzbeea114add2012-05-03 15:00:40 -0700715 const Instruction::Code opcodes[MAX_PATTERN_LEN];
716 const SpecialCaseHandler handlerCode;
buzbee16da88c2012-03-20 10:38:17 -0700717};
718
719static const CodePattern specialPatterns[] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700720 {{Instruction::RETURN_VOID}, kNullMethod},
721 {{Instruction::CONST, Instruction::RETURN}, kConstFunction},
722 {{Instruction::CONST_4, Instruction::RETURN}, kConstFunction},
723 {{Instruction::CONST_4, Instruction::RETURN_OBJECT}, kConstFunction},
724 {{Instruction::CONST_16, Instruction::RETURN}, kConstFunction},
725 {{Instruction::IGET, Instruction:: RETURN}, kIGet},
726 {{Instruction::IGET_BOOLEAN, Instruction::RETURN}, kIGetBoolean},
727 {{Instruction::IGET_OBJECT, Instruction::RETURN_OBJECT}, kIGetObject},
728 {{Instruction::IGET_BYTE, Instruction::RETURN}, kIGetByte},
729 {{Instruction::IGET_CHAR, Instruction::RETURN}, kIGetChar},
730 {{Instruction::IGET_SHORT, Instruction::RETURN}, kIGetShort},
731 {{Instruction::IGET_WIDE, Instruction::RETURN_WIDE}, kIGetWide},
732 {{Instruction::IPUT, Instruction::RETURN_VOID}, kIPut},
733 {{Instruction::IPUT_BOOLEAN, Instruction::RETURN_VOID}, kIPutBoolean},
734 {{Instruction::IPUT_OBJECT, Instruction::RETURN_VOID}, kIPutObject},
735 {{Instruction::IPUT_BYTE, Instruction::RETURN_VOID}, kIPutByte},
736 {{Instruction::IPUT_CHAR, Instruction::RETURN_VOID}, kIPutChar},
737 {{Instruction::IPUT_SHORT, Instruction::RETURN_VOID}, kIPutShort},
738 {{Instruction::IPUT_WIDE, Instruction::RETURN_VOID}, kIPutWide},
739 {{Instruction::RETURN}, kIdentity},
740 {{Instruction::RETURN_OBJECT}, kIdentity},
741 {{Instruction::RETURN_WIDE}, kIdentity},
buzbee16da88c2012-03-20 10:38:17 -0700742};
buzbee5de34942012-03-01 14:51:57 -0800743
buzbee5abfa3e2012-01-31 17:01:43 -0800744BasicBlock* oatNewBB(CompilationUnit* cUnit, BBType blockType, int blockId);
buzbee67bf8852011-08-17 17:51:35 -0700745
746void oatAppendMIR(BasicBlock* bb, MIR* mir);
747
748void oatPrependMIR(BasicBlock* bb, MIR* mir);
749
750void oatInsertMIRAfter(BasicBlock* bb, MIR* currentMIR, MIR* newMIR);
751
752void oatAppendLIR(CompilationUnit* cUnit, LIR* lir);
753
754void oatInsertLIRBefore(LIR* currentLIR, LIR* newLIR);
755
756void oatInsertLIRAfter(LIR* currentLIR, LIR* newLIR);
757
buzbeefc9e6fa2012-03-23 15:14:29 -0700758MIR* oatFindMoveResult(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
759 bool wide);
buzbee67bf8852011-08-17 17:51:35 -0700760/* Debug Utilities */
761void oatDumpCompilationUnit(CompilationUnit* cUnit);
762
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800763} // namespace art
764
buzbee67bf8852011-08-17 17:51:35 -0700765#endif // ART_SRC_COMPILER_COMPILER_IR_H_