blob: 1cbf2b5f194b82d19ff650edb59336b73198527b [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
buzbeeca7a5e42012-08-20 11:12:18 -070044// Minimum field size to contain Dalvik vReg number
45#define VREG_NUM_WIDTH 16
46
Elliott Hughes719ace42012-03-09 18:06:03 -080047enum RegisterClass {
Bill Buzbeea114add2012-05-03 15:00:40 -070048 kCoreReg,
49 kFPReg,
50 kAnyReg,
Elliott Hughes719ace42012-03-09 18:06:03 -080051};
buzbee67bf8852011-08-17 17:51:35 -070052
Elliott Hughes719ace42012-03-09 18:06:03 -080053enum RegLocationType {
Bill Buzbeea114add2012-05-03 15:00:40 -070054 kLocDalvikFrame = 0, // Normal Dalvik register
55 kLocPhysReg,
56 kLocCompilerTemp,
57 kLocInvalid
Elliott Hughes719ace42012-03-09 18:06:03 -080058};
buzbee67bf8852011-08-17 17:51:35 -070059
Elliott Hughes719ace42012-03-09 18:06:03 -080060struct PromotionMap {
Bill Buzbeea114add2012-05-03 15:00:40 -070061 RegLocationType coreLocation:3;
62 u1 coreReg;
63 RegLocationType fpLocation:3;
64 u1 fpReg;
65 bool firstInPair;
Elliott Hughes719ace42012-03-09 18:06:03 -080066};
buzbee67bc2362011-10-11 18:08:40 -070067
Elliott Hughes719ace42012-03-09 18:06:03 -080068struct RegLocation {
Bill Buzbeea114add2012-05-03 15:00:40 -070069 RegLocationType location:3;
70 unsigned wide:1;
71 unsigned defined:1; // Do we know the type?
buzbee2cfc6392012-05-07 14:51:40 -070072 unsigned isConst:1; // Constant, value in cUnit->constantValues[]
Bill Buzbeea114add2012-05-03 15:00:40 -070073 unsigned fp:1; // Floating point?
74 unsigned core:1; // Non-floating point?
buzbeebff24652012-05-06 16:22:05 -070075 unsigned ref:1; // Something GC cares about
Bill Buzbeea114add2012-05-03 15:00:40 -070076 unsigned highWord:1; // High word of pair?
77 unsigned home:1; // Does this represent the home location?
78 u1 lowReg; // First physical register
79 u1 highReg; // 2nd physical register (if wide)
80 int32_t sRegLow; // SSA name for low Dalvik word
buzbee2cfc6392012-05-07 14:51:40 -070081 int32_t origSReg; // TODO: remove after Bitcode gen complete
82 // and consolodate usage w/ sRegLow
buzbeee1965672012-03-11 18:39:19 -070083};
84
85struct CompilerTemp {
Bill Buzbeea114add2012-05-03 15:00:40 -070086 int sReg;
87 ArenaBitVector* bv;
Elliott Hughes719ace42012-03-09 18:06:03 -080088};
buzbee67bf8852011-08-17 17:51:35 -070089
buzbee3b3dbdd2012-06-13 13:39:34 -070090struct CallInfo {
buzbee15bf9802012-06-12 17:49:27 -070091 int numArgWords; // Note: word count, not arg count
92 RegLocation* args; // One for each word of arguments
93 RegLocation result; // Eventual target of MOVE_RESULT
94 int optFlags;
95 InvokeType type;
96 uint32_t dexIdx;
buzbee3b3dbdd2012-06-13 13:39:34 -070097 uint32_t index; // Method idx for invokes, type idx for FilledNewArray
buzbee15bf9802012-06-12 17:49:27 -070098 uintptr_t directCode;
99 uintptr_t directMethod;
100 RegLocation target; // Target of following move_result
101 bool skipThis;
102 bool isRange;
103 int offset; // Dalvik offset
104};
105
buzbeee3acd072012-02-25 17:03:10 -0800106 /*
107 * Data structure tracking the mapping between a Dalvik register (pair) and a
108 * native register (pair). The idea is to reuse the previously loaded value
109 * if possible, otherwise to keep the value in a native register as long as
110 * possible.
111 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800112struct RegisterInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700113 int reg; // Reg number
114 bool inUse; // Has it been allocated?
115 bool isTemp; // Can allocate as temp?
116 bool pair; // Part of a register pair?
117 int partner; // If pair, other reg of pair
118 bool live; // Is there an associated SSA name?
119 bool dirty; // If live, is it dirty?
120 int sReg; // Name of live value
121 LIR *defStart; // Starting inst in last def sequence
122 LIR *defEnd; // Ending inst in last def sequence
Elliott Hughes719ace42012-03-09 18:06:03 -0800123};
buzbeee3acd072012-02-25 17:03:10 -0800124
Elliott Hughes719ace42012-03-09 18:06:03 -0800125struct RegisterPool {
Bill Buzbeea114add2012-05-03 15:00:40 -0700126 int numCoreRegs;
127 RegisterInfo *coreRegs;
128 int nextCoreReg;
129 int numFPRegs;
130 RegisterInfo *FPRegs;
131 int nextFPReg;
Elliott Hughes719ace42012-03-09 18:06:03 -0800132};
buzbeee3acd072012-02-25 17:03:10 -0800133
buzbee67bf8852011-08-17 17:51:35 -0700134#define INVALID_SREG (-1)
buzbee3ddc0d12011-10-05 10:36:21 -0700135#define INVALID_VREG (0xFFFFU)
buzbee67bc2362011-10-11 18:08:40 -0700136#define INVALID_REG (0xFF)
buzbee67bf8852011-08-17 17:51:35 -0700137#define INVALID_OFFSET (-1)
138
buzbeee1965672012-03-11 18:39:19 -0700139/* SSA encodings for special registers */
buzbee9c044ce2012-03-18 13:24:07 -0700140#define SSA_METHOD_BASEREG (-2)
buzbeee1965672012-03-11 18:39:19 -0700141/* First compiler temp basereg, grows smaller */
buzbee9c044ce2012-03-18 13:24:07 -0700142#define SSA_CTEMP_BASEREG (SSA_METHOD_BASEREG - 1)
buzbee2cfc6392012-05-07 14:51:40 -0700143/* Max SSA name length */
144#define SSA_NAME_MAX 16
buzbeee1965672012-03-11 18:39:19 -0700145
buzbee99ba9642012-01-25 14:23:14 -0800146/*
147 * Some code patterns cause the generation of excessively large
148 * methods - in particular initialization sequences. There isn't much
149 * benefit in optimizing these methods, and the cost can be very high.
150 * We attempt to identify these cases, and avoid performing most dataflow
151 * analysis. Two thresholds are used - one for known initializers and one
buzbee5abfa3e2012-01-31 17:01:43 -0800152 * for everything else.
buzbee99ba9642012-01-25 14:23:14 -0800153 */
buzbee5abfa3e2012-01-31 17:01:43 -0800154#define MANY_BLOCKS_INITIALIZER 1000 /* Threshold for switching dataflow off */
155#define MANY_BLOCKS 4000 /* Non-initializer threshold */
buzbee99ba9642012-01-25 14:23:14 -0800156
Elliott Hughes719ace42012-03-09 18:06:03 -0800157enum BBType {
Bill Buzbeea114add2012-05-03 15:00:40 -0700158 kEntryBlock,
159 kDalvikByteCode,
160 kExitBlock,
161 kExceptionHandling,
162 kCatchEntry,
buzbeed1643e42012-09-05 14:06:51 -0700163 kDead,
Elliott Hughes719ace42012-03-09 18:06:03 -0800164};
buzbee67bf8852011-08-17 17:51:35 -0700165
buzbee31a4a6f2012-02-28 15:36:15 -0800166/* Utility macros to traverse the LIR list */
167#define NEXT_LIR(lir) (lir->next)
168#define PREV_LIR(lir) (lir->prev)
169
170#define NEXT_LIR_LVALUE(lir) (lir)->next
171#define PREV_LIR_LVALUE(lir) (lir)->prev
172
Elliott Hughes719ace42012-03-09 18:06:03 -0800173struct LIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700174 int offset; // Offset of this instruction
175 int dalvikOffset; // Offset of Dalvik opcode
176 LIR* next;
177 LIR* prev;
178 LIR* target;
179 int opcode;
180 int operands[5]; // [0..4] = [dest, src1, src2, extra, extra2]
181 struct {
182 bool isNop:1; // LIR is optimized away
183 bool pcRelFixup:1; // May need pc-relative fixup
184 unsigned int age:4; // default is 0, set lazily by the optimizer
185 unsigned int size:5; // in bytes
186 unsigned int unused:21;
187 } flags;
188 int aliasInfo; // For Dalvik register & litpool disambiguation
189 u8 useMask; // Resource mask for use
190 u8 defMask; // Resource mask for def
Elliott Hughes719ace42012-03-09 18:06:03 -0800191};
buzbee67bf8852011-08-17 17:51:35 -0700192
193enum ExtendedMIROpcode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700194 kMirOpFirst = kNumPackedOpcodes,
195 kMirOpPhi = kMirOpFirst,
196 kMirOpCopy,
197 kMirOpFusedCmplFloat,
198 kMirOpFusedCmpgFloat,
199 kMirOpFusedCmplDouble,
200 kMirOpFusedCmpgDouble,
201 kMirOpFusedCmpLong,
202 kMirOpNop,
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700203 kMirOpNullCheck,
204 kMirOpRangeCheck,
205 kMirOpDivZeroCheck,
206 kMirOpCheck,
Bill Buzbeea114add2012-05-03 15:00:40 -0700207 kMirOpLast,
buzbee67bf8852011-08-17 17:51:35 -0700208};
209
210struct SSARepresentation;
211
Elliott Hughes719ace42012-03-09 18:06:03 -0800212enum MIROptimizationFlagPositons {
Bill Buzbeea114add2012-05-03 15:00:40 -0700213 kMIRIgnoreNullCheck = 0,
214 kMIRNullCheckOnly,
215 kMIRIgnoreRangeCheck,
216 kMIRRangeCheckOnly,
217 kMIRInlined, // Invoke is inlined (ie dead)
218 kMIRInlinedPred, // Invoke is inlined via prediction
219 kMIRCallee, // Instruction is inlined from callee
220 kMIRIgnoreSuspendCheck,
221 kMIRDup,
222 kMIRMark, // Temporary node mark
Elliott Hughes719ace42012-03-09 18:06:03 -0800223};
buzbee67bf8852011-08-17 17:51:35 -0700224
225#define MIR_IGNORE_NULL_CHECK (1 << kMIRIgnoreNullCheck)
226#define MIR_NULL_CHECK_ONLY (1 << kMIRNullCheckOnly)
227#define MIR_IGNORE_RANGE_CHECK (1 << kMIRIgnoreRangeCheck)
228#define MIR_RANGE_CHECK_ONLY (1 << kMIRRangeCheckOnly)
229#define MIR_INLINED (1 << kMIRInlined)
230#define MIR_INLINED_PRED (1 << kMIRInlinedPred)
231#define MIR_CALLEE (1 << kMIRCallee)
buzbeec1f45042011-09-21 16:03:19 -0700232#define MIR_IGNORE_SUSPEND_CHECK (1 << kMIRIgnoreSuspendCheck)
buzbeee1965672012-03-11 18:39:19 -0700233#define MIR_DUP (1 << kMIRDup)
buzbee239c4e72012-03-16 08:42:29 -0700234#define MIR_MARK (1 << kMIRMark)
buzbee67bf8852011-08-17 17:51:35 -0700235
Elliott Hughes719ace42012-03-09 18:06:03 -0800236struct CallsiteInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700237 const char* classDescriptor;
238 Object* classLoader;
239 const Method* method;
240 LIR* misPredBranchOver;
Elliott Hughes719ace42012-03-09 18:06:03 -0800241};
buzbee67bf8852011-08-17 17:51:35 -0700242
buzbeed1643e42012-09-05 14:06:51 -0700243struct Checkstats {
244 int nullChecks;
245 int nullChecksEliminated;
246 int rangeChecks;
247 int rangeChecksEliminated;
248};
249
Elliott Hughes719ace42012-03-09 18:06:03 -0800250struct MIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700251 DecodedInstruction dalvikInsn;
252 unsigned int width;
253 unsigned int offset;
254 MIR* prev;
255 MIR* next;
256 SSARepresentation* ssaRep;
257 int optimizationFlags;
258 int seqNum;
259 union {
Bill Buzbeea114add2012-05-03 15:00:40 -0700260 // Used to quickly locate all Phi opcodes
261 MIR* phiNext;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700262 // Establish link between two halves of throwing instructions
263 MIR* throwInsn;
Bill Buzbeea114add2012-05-03 15:00:40 -0700264 } meta;
Elliott Hughes719ace42012-03-09 18:06:03 -0800265};
buzbee67bf8852011-08-17 17:51:35 -0700266
267struct BasicBlockDataFlow;
268
269/* For successorBlockList */
Elliott Hughes719ace42012-03-09 18:06:03 -0800270enum BlockListType {
Bill Buzbeea114add2012-05-03 15:00:40 -0700271 kNotUsed = 0,
272 kCatch,
273 kPackedSwitch,
274 kSparseSwitch,
Elliott Hughes719ace42012-03-09 18:06:03 -0800275};
buzbee67bf8852011-08-17 17:51:35 -0700276
Elliott Hughes719ace42012-03-09 18:06:03 -0800277struct BasicBlock {
Bill Buzbeea114add2012-05-03 15:00:40 -0700278 int id;
279 int dfsId;
280 bool visited;
281 bool hidden;
282 bool catchEntry;
buzbee2cfc6392012-05-07 14:51:40 -0700283#if defined(ART_USE_QUICK_COMPILER)
284 bool hasReturn;
285#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700286 uint16_t startOffset;
287 uint16_t nestingDepth;
288 const Method* containingMethod; // For blocks from the callee
289 BBType blockType;
Bill Buzbeea114add2012-05-03 15:00:40 -0700290 bool isFallThroughFromInvoke; // True means the block needs alignment
291 MIR* firstMIRInsn;
292 MIR* lastMIRInsn;
293 BasicBlock* fallThrough;
294 BasicBlock* taken;
295 BasicBlock* iDom; // Immediate dominator
296 BasicBlockDataFlow* dataFlowInfo;
297 GrowableList* predecessors;
298 ArenaBitVector* dominators;
299 ArenaBitVector* iDominated; // Set nodes being immediately dominated
300 ArenaBitVector* domFrontier; // Dominance frontier
301 struct { // For one-to-many successors like
302 BlockListType blockListType; // switch and exception handling
303 GrowableList blocks;
304 } successorBlockList;
Elliott Hughes719ace42012-03-09 18:06:03 -0800305};
buzbee67bf8852011-08-17 17:51:35 -0700306
307/*
308 * The "blocks" field in "successorBlockList" points to an array of
309 * elements with the type "SuccessorBlockInfo".
310 * For catch blocks, key is type index for the exception.
311 * For swtich blocks, key is the case value.
312 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800313struct SuccessorBlockInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700314 BasicBlock* block;
315 int key;
Elliott Hughes719ace42012-03-09 18:06:03 -0800316};
buzbee67bf8852011-08-17 17:51:35 -0700317
318struct LoopAnalysis;
319struct RegisterPool;
buzbeeba938cb2012-02-03 14:47:55 -0800320struct ArenaMemBlock;
321struct Memstats;
buzbee67bf8852011-08-17 17:51:35 -0700322
Elliott Hughes719ace42012-03-09 18:06:03 -0800323enum AssemblerStatus {
Bill Buzbeea114add2012-05-03 15:00:40 -0700324 kSuccess,
325 kRetryAll,
326 kRetryHalve
Elliott Hughes719ace42012-03-09 18:06:03 -0800327};
buzbee67bf8852011-08-17 17:51:35 -0700328
buzbee5b537102012-01-17 17:33:47 -0800329#define NOTVISITED (-1)
330
Elliott Hughes719ace42012-03-09 18:06:03 -0800331struct CompilationUnit {
Elliott Hughese52e49b2012-04-02 16:05:44 -0700332 CompilationUnit()
Bill Buzbeea114add2012-05-03 15:00:40 -0700333 : numBlocks(0),
334 compiler(NULL),
335 class_linker(NULL),
336 dex_file(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700337 class_loader(NULL),
338 method_idx(0),
339 code_item(NULL),
340 access_flags(0),
Ian Rogers08f753d2012-08-24 14:35:25 -0700341 invoke_type(kDirect),
Bill Buzbeea114add2012-05-03 15:00:40 -0700342 shorty(NULL),
343 firstLIRInsn(NULL),
344 lastLIRInsn(NULL),
345 literalList(NULL),
346 methodLiteralList(NULL),
347 codeLiteralList(NULL),
348 classPointerList(NULL),
349 numClassPointers(0),
350 chainCellOffsetLIR(NULL),
351 disableOpt(0),
352 enableDebug(0),
353 headerSize(0),
354 dataOffset(0),
355 totalSize(0),
356 assemblerStatus(kSuccess),
357 assemblerRetries(0),
358 genDebugger(false),
359 printMe(false),
360 hasClassLiterals(false),
361 hasLoop(false),
362 hasInvoke(false),
363 heapMemOp(false),
364 qdMode(false),
365 usesLinkRegister(false),
366 methodTraceSupport(false),
367 regPool(NULL),
368 optRound(0),
369 instructionSet(kNone),
370 numSSARegs(0),
371 ssaBaseVRegs(NULL),
372 ssaSubscripts(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700373 ssaStrings(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700374 vRegToSSAMap(NULL),
375 SSALastDefs(NULL),
376 isConstantV(NULL),
377 constantValues(NULL),
378 phiAliasMap(NULL),
379 phiList(NULL),
380 regLocation(NULL),
381 sequenceNumber(0),
382 promotionMap(NULL),
383 methodSReg(0),
384 switchOverflowPad(NULL),
385 numReachableBlocks(0),
386 numDalvikRegisters(0),
387 entryBlock(NULL),
388 exitBlock(NULL),
389 curBlock(NULL),
390 nextCodegenBlock(NULL),
391 iDomList(NULL),
392 tryBlockAddr(NULL),
393 defBlockMatrix(NULL),
394 tempBlockV(NULL),
395 tempDalvikRegisterV(NULL),
396 tempSSARegisterV(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700397 tempSSABlockIdV(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700398 printSSANames(false),
399 blockLabelList(NULL),
400 quitLoopMode(false),
401 preservedRegsUsed(0),
402 numIns(0),
403 numOuts(0),
404 numRegs(0),
405 numCoreSpills(0),
406 numFPSpills(0),
407 numCompilerTemps(0),
408 frameSize(0),
409 coreSpillMask(0U),
410 fpSpillMask(0U),
411 attrs(0U),
412 currentDalvikOffset(0),
413 insns(NULL),
414 insnsSize(0U),
415 disableDataflow(false),
416 defCount(0),
417 compilerFlipMatch(false),
418 arenaHead(NULL),
419 currentArena(NULL),
420 numArenaBlocks(0),
421 mstats(NULL),
buzbeed1643e42012-09-05 14:06:51 -0700422 checkstats(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700423#if defined(ART_USE_QUICK_COMPILER)
424 genBitcode(false),
425 context(NULL),
426 module(NULL),
427 func(NULL),
428 intrinsic_helper(NULL),
429 irb(NULL),
430 placeholderBB(NULL),
431 entryBB(NULL),
buzbee4be777b2012-07-12 14:38:18 -0700432 entryTargetBB(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700433 tempName(0),
buzbeeb03f4872012-06-11 15:22:11 -0700434 requireShadowFrame(false),
435 numShadowFrameEntries(0),
436 shadowMap(NULL),
Elliott Hughese52e49b2012-04-02 16:05:44 -0700437#endif
buzbee2cfc6392012-05-07 14:51:40 -0700438#ifndef NDEBUG
439 liveSReg(0),
440#endif
441 opcodeCount(NULL) {}
Elliott Hughese52e49b2012-04-02 16:05:44 -0700442
Bill Buzbeea114add2012-05-03 15:00:40 -0700443 int numBlocks;
444 GrowableList blockList;
445 Compiler* compiler; // Compiler driving this compiler
446 ClassLinker* class_linker; // Linker to resolve fields and methods
447 const DexFile* dex_file; // DexFile containing the method being compiled
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700448 jobject class_loader; // compiling method's class loader
Bill Buzbeea114add2012-05-03 15:00:40 -0700449 uint32_t method_idx; // compiling method's index into method_ids of DexFile
450 const DexFile::CodeItem* code_item; // compiling method's DexFile code_item
451 uint32_t access_flags; // compiling method's access flags
Ian Rogers08f753d2012-08-24 14:35:25 -0700452 InvokeType invoke_type; // compiling method's invocation type
Bill Buzbeea114add2012-05-03 15:00:40 -0700453 const char* shorty; // compiling method's shorty
454 LIR* firstLIRInsn;
455 LIR* lastLIRInsn;
456 LIR* literalList; // Constants
457 LIR* methodLiteralList; // Method literals requiring patching
458 LIR* codeLiteralList; // Code literals requiring patching
459 LIR* classPointerList; // Relocatable
460 int numClassPointers;
461 LIR* chainCellOffsetLIR;
462 uint32_t disableOpt; // optControlVector flags
463 uint32_t enableDebug; // debugControlVector flags
464 int headerSize; // bytes before the first code ptr
465 int dataOffset; // starting offset of literal pool
466 int totalSize; // header + code size
467 AssemblerStatus assemblerStatus; // Success or fix and retry
468 int assemblerRetries;
469 std::vector<uint8_t> codeBuffer;
470 std::vector<uint32_t> mappingTable;
buzbeeca7a5e42012-08-20 11:12:18 -0700471 std::vector<uint32_t> coreVmapTable;
472 std::vector<uint32_t> fpVmapTable;
Bill Buzbeea114add2012-05-03 15:00:40 -0700473 bool genDebugger; // Generate code for debugger
474 bool printMe;
475 bool hasClassLiterals; // Contains class ptrs used as literals
476 bool hasLoop; // Contains a loop
477 bool hasInvoke; // Contains an invoke instruction
478 bool heapMemOp; // Mark mem ops for self verification
479 bool qdMode; // Compile for code size/compile time
480 bool usesLinkRegister; // For self-verification only
481 bool methodTraceSupport; // For TraceView profiling
482 RegisterPool* regPool;
483 int optRound; // round number to tell an LIR's age
484 InstructionSet instructionSet;
485 /* Number of total regs used in the whole cUnit after SSA transformation */
486 int numSSARegs;
487 /* Map SSA reg i to the base virtual register/subscript */
488 GrowableList* ssaBaseVRegs;
489 GrowableList* ssaSubscripts;
buzbee2cfc6392012-05-07 14:51:40 -0700490 GrowableList* ssaStrings;
buzbee67bf8852011-08-17 17:51:35 -0700491
Bill Buzbeea114add2012-05-03 15:00:40 -0700492 /* The following are new data structures to support SSA representations */
493 /* Map original Dalvik virtual reg i to the current SSA name */
494 int* vRegToSSAMap; // length == method->registersSize
495 int* SSALastDefs; // length == method->registersSize
496 ArenaBitVector* isConstantV; // length == numSSAReg
497 int* constantValues; // length == numSSAReg
498 int* phiAliasMap; // length == numSSAReg
499 MIR* phiList;
buzbee67bf8852011-08-17 17:51:35 -0700500
Bill Buzbeea114add2012-05-03 15:00:40 -0700501 /* Use counts of ssa names */
502 GrowableList useCounts; // Weighted by nesting depth
503 GrowableList rawUseCounts; // Not weighted
buzbee239c4e72012-03-16 08:42:29 -0700504
Bill Buzbeea114add2012-05-03 15:00:40 -0700505 /* Optimization support */
506 GrowableList loopHeaders;
buzbee239c4e72012-03-16 08:42:29 -0700507
Bill Buzbeea114add2012-05-03 15:00:40 -0700508 /* Map SSA names to location */
509 RegLocation* regLocation;
510 int sequenceNumber;
buzbee67bf8852011-08-17 17:51:35 -0700511
Bill Buzbeea114add2012-05-03 15:00:40 -0700512 /* Keep track of Dalvik vReg to physical register mappings */
513 PromotionMap* promotionMap;
buzbee67bc2362011-10-11 18:08:40 -0700514
Bill Buzbeea114add2012-05-03 15:00:40 -0700515 /* SSA name for Method* */
516 int methodSReg;
buzbeead8f15e2012-06-18 14:49:45 -0700517 RegLocation methodLoc; // Describes location of method*
buzbeee1965672012-03-11 18:39:19 -0700518
Bill Buzbeea114add2012-05-03 15:00:40 -0700519 /*
520 * Set to the Dalvik PC of the switch instruction if it has more than
521 * MAX_CHAINED_SWITCH_CASES cases.
522 */
523 const u2* switchOverflowPad;
buzbee67bf8852011-08-17 17:51:35 -0700524
Bill Buzbeea114add2012-05-03 15:00:40 -0700525 int numReachableBlocks;
526 int numDalvikRegisters; // method->registersSize
527 BasicBlock* entryBlock;
528 BasicBlock* exitBlock;
529 BasicBlock* curBlock;
530 BasicBlock* nextCodegenBlock; // for extended trace codegen
531 GrowableList dfsOrder;
532 GrowableList dfsPostOrder;
533 GrowableList domPostOrderTraversal;
534 GrowableList throwLaunchpads;
535 GrowableList suspendLaunchpads;
536 GrowableList intrinsicLaunchpads;
537 GrowableList compilerTemps;
538 int* iDomList;
539 ArenaBitVector* tryBlockAddr;
540 ArenaBitVector** defBlockMatrix; // numDalvikRegister x numBlocks
541 ArenaBitVector* tempBlockV;
542 ArenaBitVector* tempDalvikRegisterV;
543 ArenaBitVector* tempSSARegisterV; // numSSARegs
buzbee2cfc6392012-05-07 14:51:40 -0700544 int* tempSSABlockIdV; // working storage for Phi labels
Bill Buzbeea114add2012-05-03 15:00:40 -0700545 bool printSSANames;
buzbeea1da8a52012-07-09 14:00:21 -0700546 LIR* blockLabelList;
Bill Buzbeea114add2012-05-03 15:00:40 -0700547 bool quitLoopMode; // cold path/complex bytecode
548 int preservedRegsUsed; // How many callee save regs used
549 /*
550 * Frame layout details.
551 * NOTE: for debug support it will be necessary to add a structure
552 * to map the Dalvik virtual registers to the promoted registers.
553 * NOTE: "num" fields are in 4-byte words, "Size" and "Offset" in bytes.
554 */
555 int numIns;
556 int numOuts;
557 int numRegs; // Unlike numDalvikRegisters, does not include ins
558 int numCoreSpills;
559 int numFPSpills;
560 int numCompilerTemps;
561 int frameSize;
562 unsigned int coreSpillMask;
563 unsigned int fpSpillMask;
564 unsigned int attrs;
565 /*
566 * CLEANUP/RESTRUCTURE: The code generation utilities don't have a built-in
567 * mechanism to propagate the original Dalvik opcode address to the
568 * associated generated instructions. For the trace compiler, this wasn't
569 * necessary because the interpreter handled all throws and debugging
570 * requests. For now we'll handle this by placing the Dalvik offset
571 * in the CompilationUnit struct before codegen for each instruction.
572 * The low-level LIR creation utilites will pull it from here. Should
573 * be rewritten.
574 */
575 int currentDalvikOffset;
576 GrowableList switchTables;
577 GrowableList fillArrayData;
578 const u2* insns;
579 u4 insnsSize;
580 bool disableDataflow; // Skip dataflow analysis if possible
581 SafeMap<unsigned int, BasicBlock*> blockMap; // findBlock lookup cache
buzbeed1643e42012-09-05 14:06:51 -0700582 SafeMap<unsigned int, unsigned int> blockIdMap; // Block collapse lookup cache
Bill Buzbeea114add2012-05-03 15:00:40 -0700583 SafeMap<unsigned int, LIR*> boundaryMap; // boundary lookup cache
584 int defCount; // Used to estimate number of SSA names
Elliott Hughese52e49b2012-04-02 16:05:44 -0700585
Bill Buzbeea114add2012-05-03 15:00:40 -0700586 // If non-empty, apply optimizer/debug flags only to matching methods.
587 std::string compilerMethodMatch;
588 // Flips sense of compilerMethodMatch - apply flags if doesn't match.
589 bool compilerFlipMatch;
590 ArenaMemBlock* arenaHead;
591 ArenaMemBlock* currentArena;
592 int numArenaBlocks;
593 Memstats* mstats;
buzbeed1643e42012-09-05 14:06:51 -0700594 Checkstats* checkstats;
buzbee2cfc6392012-05-07 14:51:40 -0700595#if defined(ART_USE_QUICK_COMPILER)
596 bool genBitcode;
597 llvm::LLVMContext* context;
598 llvm::Module* module;
599 llvm::Function* func;
600 greenland::IntrinsicHelper* intrinsic_helper;
601 greenland::IRBuilder* irb;
602 llvm::BasicBlock* placeholderBB;
603 llvm::BasicBlock* entryBB;
buzbee4be777b2012-07-12 14:38:18 -0700604 llvm::BasicBlock* entryTargetBB;
buzbee2cfc6392012-05-07 14:51:40 -0700605 std::string bitcode_filename;
606 GrowableList llvmValues;
607 int32_t tempName;
608 SafeMap<llvm::BasicBlock*, LIR*> blockToLabelMap; // llvm bb -> LIR label
609 SafeMap<int32_t, llvm::BasicBlock*> idToBlockMap; // block id -> llvm bb
610 SafeMap<llvm::Value*, RegLocation> locMap; // llvm Value to loc rec
buzbeeb03f4872012-06-11 15:22:11 -0700611 bool requireShadowFrame;
612 int numShadowFrameEntries;
613 int* shadowMap;
buzbee2cfc6392012-05-07 14:51:40 -0700614#endif
buzbee3d661942012-03-14 17:37:27 -0700615#ifndef NDEBUG
Bill Buzbeea114add2012-05-03 15:00:40 -0700616 /*
617 * Sanity checking for the register temp tracking. The same ssa
618 * name should never be associated with one temp register per
619 * instruction compilation.
620 */
621 int liveSReg;
buzbee3d661942012-03-14 17:37:27 -0700622#endif
buzbee2cfc6392012-05-07 14:51:40 -0700623 int* opcodeCount; // Count Dalvik opcodes for tuning
Elliott Hughes719ace42012-03-09 18:06:03 -0800624};
buzbee67bf8852011-08-17 17:51:35 -0700625
Elliott Hughes719ace42012-03-09 18:06:03 -0800626enum OpSize {
Bill Buzbeea114add2012-05-03 15:00:40 -0700627 kWord,
628 kLong,
629 kSingle,
630 kDouble,
631 kUnsignedHalf,
632 kSignedHalf,
633 kUnsignedByte,
634 kSignedByte,
Elliott Hughes719ace42012-03-09 18:06:03 -0800635};
buzbeee3acd072012-02-25 17:03:10 -0800636
Elliott Hughes719ace42012-03-09 18:06:03 -0800637enum OpKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700638 kOpMov,
639 kOpMvn,
640 kOpCmp,
641 kOpLsl,
642 kOpLsr,
643 kOpAsr,
644 kOpRor,
645 kOpNot,
646 kOpAnd,
647 kOpOr,
648 kOpXor,
649 kOpNeg,
650 kOpAdd,
651 kOpAdc,
652 kOpSub,
653 kOpSbc,
654 kOpRsub,
655 kOpMul,
656 kOpDiv,
657 kOpRem,
658 kOpBic,
659 kOpCmn,
660 kOpTst,
661 kOpBkpt,
662 kOpBlx,
663 kOpPush,
664 kOpPop,
665 kOp2Char,
666 kOp2Short,
667 kOp2Byte,
668 kOpCondBr,
669 kOpUncondBr,
670 kOpBx,
671 kOpInvalid,
Elliott Hughes719ace42012-03-09 18:06:03 -0800672};
buzbee31a4a6f2012-02-28 15:36:15 -0800673
Ian Rogers680b1bd2012-03-07 20:18:49 -0800674std::ostream& operator<<(std::ostream& os, const OpKind& kind);
675
Elliott Hughes719ace42012-03-09 18:06:03 -0800676enum ConditionCode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700677 kCondEq, // equal
678 kCondNe, // not equal
679 kCondCs, // carry set (unsigned less than)
680 kCondUlt = kCondCs,
681 kCondCc, // carry clear (unsigned greater than or same)
682 kCondUge = kCondCc,
683 kCondMi, // minus
684 kCondPl, // plus, positive or zero
685 kCondVs, // overflow
686 kCondVc, // no overflow
687 kCondHi, // unsigned greater than
688 kCondLs, // unsigned lower or same
689 kCondGe, // signed greater than or equal
690 kCondLt, // signed less than
691 kCondGt, // signed greater than
692 kCondLe, // signed less than or equal
693 kCondAl, // always
694 kCondNv, // never
Elliott Hughes719ace42012-03-09 18:06:03 -0800695};
buzbee31a4a6f2012-02-28 15:36:15 -0800696
Elliott Hughes719ace42012-03-09 18:06:03 -0800697enum ThrowKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700698 kThrowNullPointer,
699 kThrowDivZero,
700 kThrowArrayBounds,
Bill Buzbeea114add2012-05-03 15:00:40 -0700701 kThrowNoSuchMethod,
702 kThrowStackOverflow,
Elliott Hughes719ace42012-03-09 18:06:03 -0800703};
buzbee31a4a6f2012-02-28 15:36:15 -0800704
Elliott Hughes719ace42012-03-09 18:06:03 -0800705struct SwitchTable {
Bill Buzbeea114add2012-05-03 15:00:40 -0700706 int offset;
707 const u2* table; // Original dex table
708 int vaddr; // Dalvik offset of switch opcode
709 LIR* anchor; // Reference instruction for relative offsets
710 LIR** targets; // Array of case targets
Elliott Hughes719ace42012-03-09 18:06:03 -0800711};
buzbee5de34942012-03-01 14:51:57 -0800712
Elliott Hughes719ace42012-03-09 18:06:03 -0800713struct FillArrayData {
Bill Buzbeea114add2012-05-03 15:00:40 -0700714 int offset;
715 const u2* table; // Original dex table
716 int size;
717 int vaddr; // Dalvik offset of FILL_ARRAY_DATA opcode
Elliott Hughes719ace42012-03-09 18:06:03 -0800718};
buzbee5de34942012-03-01 14:51:57 -0800719
buzbee16da88c2012-03-20 10:38:17 -0700720#define MAX_PATTERN_LEN 5
721
722enum SpecialCaseHandler {
Bill Buzbeea114add2012-05-03 15:00:40 -0700723 kNoHandler,
724 kNullMethod,
725 kConstFunction,
726 kIGet,
727 kIGetBoolean,
728 kIGetObject,
729 kIGetByte,
730 kIGetChar,
731 kIGetShort,
732 kIGetWide,
733 kIPut,
734 kIPutBoolean,
735 kIPutObject,
736 kIPutByte,
737 kIPutChar,
738 kIPutShort,
739 kIPutWide,
740 kIdentity,
buzbee16da88c2012-03-20 10:38:17 -0700741};
742
743struct CodePattern {
Bill Buzbeea114add2012-05-03 15:00:40 -0700744 const Instruction::Code opcodes[MAX_PATTERN_LEN];
745 const SpecialCaseHandler handlerCode;
buzbee16da88c2012-03-20 10:38:17 -0700746};
747
748static const CodePattern specialPatterns[] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700749 {{Instruction::RETURN_VOID}, kNullMethod},
750 {{Instruction::CONST, Instruction::RETURN}, kConstFunction},
751 {{Instruction::CONST_4, Instruction::RETURN}, kConstFunction},
752 {{Instruction::CONST_4, Instruction::RETURN_OBJECT}, kConstFunction},
753 {{Instruction::CONST_16, Instruction::RETURN}, kConstFunction},
754 {{Instruction::IGET, Instruction:: RETURN}, kIGet},
755 {{Instruction::IGET_BOOLEAN, Instruction::RETURN}, kIGetBoolean},
756 {{Instruction::IGET_OBJECT, Instruction::RETURN_OBJECT}, kIGetObject},
757 {{Instruction::IGET_BYTE, Instruction::RETURN}, kIGetByte},
758 {{Instruction::IGET_CHAR, Instruction::RETURN}, kIGetChar},
759 {{Instruction::IGET_SHORT, Instruction::RETURN}, kIGetShort},
760 {{Instruction::IGET_WIDE, Instruction::RETURN_WIDE}, kIGetWide},
761 {{Instruction::IPUT, Instruction::RETURN_VOID}, kIPut},
762 {{Instruction::IPUT_BOOLEAN, Instruction::RETURN_VOID}, kIPutBoolean},
763 {{Instruction::IPUT_OBJECT, Instruction::RETURN_VOID}, kIPutObject},
764 {{Instruction::IPUT_BYTE, Instruction::RETURN_VOID}, kIPutByte},
765 {{Instruction::IPUT_CHAR, Instruction::RETURN_VOID}, kIPutChar},
766 {{Instruction::IPUT_SHORT, Instruction::RETURN_VOID}, kIPutShort},
767 {{Instruction::IPUT_WIDE, Instruction::RETURN_VOID}, kIPutWide},
768 {{Instruction::RETURN}, kIdentity},
769 {{Instruction::RETURN_OBJECT}, kIdentity},
770 {{Instruction::RETURN_WIDE}, kIdentity},
buzbee16da88c2012-03-20 10:38:17 -0700771};
buzbee5de34942012-03-01 14:51:57 -0800772
buzbee5abfa3e2012-01-31 17:01:43 -0800773BasicBlock* oatNewBB(CompilationUnit* cUnit, BBType blockType, int blockId);
buzbee67bf8852011-08-17 17:51:35 -0700774
775void oatAppendMIR(BasicBlock* bb, MIR* mir);
776
777void oatPrependMIR(BasicBlock* bb, MIR* mir);
778
779void oatInsertMIRAfter(BasicBlock* bb, MIR* currentMIR, MIR* newMIR);
780
781void oatAppendLIR(CompilationUnit* cUnit, LIR* lir);
782
783void oatInsertLIRBefore(LIR* currentLIR, LIR* newLIR);
784
785void oatInsertLIRAfter(LIR* currentLIR, LIR* newLIR);
786
buzbee15bf9802012-06-12 17:49:27 -0700787MIR* oatFindMoveResult(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir);
buzbee67bf8852011-08-17 17:51:35 -0700788/* Debug Utilities */
789void oatDumpCompilationUnit(CompilationUnit* cUnit);
790
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800791} // namespace art
792
buzbee67bf8852011-08-17 17:51:35 -0700793#endif // ART_SRC_COMPILER_COMPILER_IR_H_