blob: 87dbd096c0435b9c3d00ada074921a003f88185f [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;
buzbee0967a252012-09-14 10:43:54 -0700283 bool explicitThrow;
284 bool conditionalBranch;
buzbee2cfc6392012-05-07 14:51:40 -0700285#if defined(ART_USE_QUICK_COMPILER)
286 bool hasReturn;
287#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700288 uint16_t startOffset;
289 uint16_t nestingDepth;
290 const Method* containingMethod; // For blocks from the callee
291 BBType blockType;
Bill Buzbeea114add2012-05-03 15:00:40 -0700292 bool isFallThroughFromInvoke; // True means the block needs alignment
293 MIR* firstMIRInsn;
294 MIR* lastMIRInsn;
295 BasicBlock* fallThrough;
296 BasicBlock* taken;
297 BasicBlock* iDom; // Immediate dominator
298 BasicBlockDataFlow* dataFlowInfo;
299 GrowableList* predecessors;
300 ArenaBitVector* dominators;
301 ArenaBitVector* iDominated; // Set nodes being immediately dominated
302 ArenaBitVector* domFrontier; // Dominance frontier
303 struct { // For one-to-many successors like
304 BlockListType blockListType; // switch and exception handling
305 GrowableList blocks;
306 } successorBlockList;
Elliott Hughes719ace42012-03-09 18:06:03 -0800307};
buzbee67bf8852011-08-17 17:51:35 -0700308
309/*
310 * The "blocks" field in "successorBlockList" points to an array of
311 * elements with the type "SuccessorBlockInfo".
312 * For catch blocks, key is type index for the exception.
313 * For swtich blocks, key is the case value.
314 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800315struct SuccessorBlockInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700316 BasicBlock* block;
317 int key;
Elliott Hughes719ace42012-03-09 18:06:03 -0800318};
buzbee67bf8852011-08-17 17:51:35 -0700319
320struct LoopAnalysis;
321struct RegisterPool;
buzbeeba938cb2012-02-03 14:47:55 -0800322struct ArenaMemBlock;
323struct Memstats;
buzbee67bf8852011-08-17 17:51:35 -0700324
Elliott Hughes719ace42012-03-09 18:06:03 -0800325enum AssemblerStatus {
Bill Buzbeea114add2012-05-03 15:00:40 -0700326 kSuccess,
327 kRetryAll,
328 kRetryHalve
Elliott Hughes719ace42012-03-09 18:06:03 -0800329};
buzbee67bf8852011-08-17 17:51:35 -0700330
buzbee5b537102012-01-17 17:33:47 -0800331#define NOTVISITED (-1)
332
Elliott Hughes719ace42012-03-09 18:06:03 -0800333struct CompilationUnit {
Elliott Hughese52e49b2012-04-02 16:05:44 -0700334 CompilationUnit()
Bill Buzbeea114add2012-05-03 15:00:40 -0700335 : numBlocks(0),
336 compiler(NULL),
337 class_linker(NULL),
338 dex_file(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700339 class_loader(NULL),
340 method_idx(0),
341 code_item(NULL),
342 access_flags(0),
Ian Rogers08f753d2012-08-24 14:35:25 -0700343 invoke_type(kDirect),
Bill Buzbeea114add2012-05-03 15:00:40 -0700344 shorty(NULL),
345 firstLIRInsn(NULL),
346 lastLIRInsn(NULL),
347 literalList(NULL),
348 methodLiteralList(NULL),
349 codeLiteralList(NULL),
350 classPointerList(NULL),
351 numClassPointers(0),
352 chainCellOffsetLIR(NULL),
353 disableOpt(0),
354 enableDebug(0),
355 headerSize(0),
356 dataOffset(0),
357 totalSize(0),
358 assemblerStatus(kSuccess),
359 assemblerRetries(0),
360 genDebugger(false),
361 printMe(false),
362 hasClassLiterals(false),
363 hasLoop(false),
364 hasInvoke(false),
365 heapMemOp(false),
366 qdMode(false),
367 usesLinkRegister(false),
368 methodTraceSupport(false),
369 regPool(NULL),
370 optRound(0),
371 instructionSet(kNone),
372 numSSARegs(0),
373 ssaBaseVRegs(NULL),
374 ssaSubscripts(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700375 ssaStrings(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700376 vRegToSSAMap(NULL),
377 SSALastDefs(NULL),
378 isConstantV(NULL),
379 constantValues(NULL),
380 phiAliasMap(NULL),
381 phiList(NULL),
382 regLocation(NULL),
383 sequenceNumber(0),
384 promotionMap(NULL),
385 methodSReg(0),
386 switchOverflowPad(NULL),
387 numReachableBlocks(0),
388 numDalvikRegisters(0),
389 entryBlock(NULL),
390 exitBlock(NULL),
391 curBlock(NULL),
392 nextCodegenBlock(NULL),
393 iDomList(NULL),
394 tryBlockAddr(NULL),
395 defBlockMatrix(NULL),
396 tempBlockV(NULL),
397 tempDalvikRegisterV(NULL),
398 tempSSARegisterV(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700399 tempSSABlockIdV(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700400 printSSANames(false),
401 blockLabelList(NULL),
402 quitLoopMode(false),
403 preservedRegsUsed(0),
404 numIns(0),
405 numOuts(0),
406 numRegs(0),
407 numCoreSpills(0),
408 numFPSpills(0),
409 numCompilerTemps(0),
410 frameSize(0),
411 coreSpillMask(0U),
412 fpSpillMask(0U),
413 attrs(0U),
414 currentDalvikOffset(0),
415 insns(NULL),
416 insnsSize(0U),
417 disableDataflow(false),
418 defCount(0),
419 compilerFlipMatch(false),
420 arenaHead(NULL),
421 currentArena(NULL),
422 numArenaBlocks(0),
423 mstats(NULL),
buzbeed1643e42012-09-05 14:06:51 -0700424 checkstats(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700425#if defined(ART_USE_QUICK_COMPILER)
426 genBitcode(false),
427 context(NULL),
428 module(NULL),
429 func(NULL),
430 intrinsic_helper(NULL),
431 irb(NULL),
432 placeholderBB(NULL),
433 entryBB(NULL),
buzbee4be777b2012-07-12 14:38:18 -0700434 entryTargetBB(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700435 tempName(0),
buzbeeb03f4872012-06-11 15:22:11 -0700436 requireShadowFrame(false),
437 numShadowFrameEntries(0),
438 shadowMap(NULL),
Elliott Hughese52e49b2012-04-02 16:05:44 -0700439#endif
buzbee2cfc6392012-05-07 14:51:40 -0700440#ifndef NDEBUG
441 liveSReg(0),
442#endif
443 opcodeCount(NULL) {}
Elliott Hughese52e49b2012-04-02 16:05:44 -0700444
Bill Buzbeea114add2012-05-03 15:00:40 -0700445 int numBlocks;
446 GrowableList blockList;
447 Compiler* compiler; // Compiler driving this compiler
448 ClassLinker* class_linker; // Linker to resolve fields and methods
449 const DexFile* dex_file; // DexFile containing the method being compiled
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700450 jobject class_loader; // compiling method's class loader
Bill Buzbeea114add2012-05-03 15:00:40 -0700451 uint32_t method_idx; // compiling method's index into method_ids of DexFile
452 const DexFile::CodeItem* code_item; // compiling method's DexFile code_item
453 uint32_t access_flags; // compiling method's access flags
Ian Rogers08f753d2012-08-24 14:35:25 -0700454 InvokeType invoke_type; // compiling method's invocation type
Bill Buzbeea114add2012-05-03 15:00:40 -0700455 const char* shorty; // compiling method's shorty
456 LIR* firstLIRInsn;
457 LIR* lastLIRInsn;
458 LIR* literalList; // Constants
459 LIR* methodLiteralList; // Method literals requiring patching
460 LIR* codeLiteralList; // Code literals requiring patching
461 LIR* classPointerList; // Relocatable
462 int numClassPointers;
463 LIR* chainCellOffsetLIR;
464 uint32_t disableOpt; // optControlVector flags
465 uint32_t enableDebug; // debugControlVector flags
466 int headerSize; // bytes before the first code ptr
467 int dataOffset; // starting offset of literal pool
468 int totalSize; // header + code size
469 AssemblerStatus assemblerStatus; // Success or fix and retry
470 int assemblerRetries;
471 std::vector<uint8_t> codeBuffer;
472 std::vector<uint32_t> mappingTable;
buzbeeca7a5e42012-08-20 11:12:18 -0700473 std::vector<uint32_t> coreVmapTable;
474 std::vector<uint32_t> fpVmapTable;
Bill Buzbeea114add2012-05-03 15:00:40 -0700475 bool genDebugger; // Generate code for debugger
476 bool printMe;
477 bool hasClassLiterals; // Contains class ptrs used as literals
478 bool hasLoop; // Contains a loop
479 bool hasInvoke; // Contains an invoke instruction
480 bool heapMemOp; // Mark mem ops for self verification
481 bool qdMode; // Compile for code size/compile time
482 bool usesLinkRegister; // For self-verification only
483 bool methodTraceSupport; // For TraceView profiling
484 RegisterPool* regPool;
485 int optRound; // round number to tell an LIR's age
486 InstructionSet instructionSet;
487 /* Number of total regs used in the whole cUnit after SSA transformation */
488 int numSSARegs;
489 /* Map SSA reg i to the base virtual register/subscript */
490 GrowableList* ssaBaseVRegs;
491 GrowableList* ssaSubscripts;
buzbee2cfc6392012-05-07 14:51:40 -0700492 GrowableList* ssaStrings;
buzbee67bf8852011-08-17 17:51:35 -0700493
Bill Buzbeea114add2012-05-03 15:00:40 -0700494 /* The following are new data structures to support SSA representations */
495 /* Map original Dalvik virtual reg i to the current SSA name */
496 int* vRegToSSAMap; // length == method->registersSize
497 int* SSALastDefs; // length == method->registersSize
498 ArenaBitVector* isConstantV; // length == numSSAReg
499 int* constantValues; // length == numSSAReg
500 int* phiAliasMap; // length == numSSAReg
501 MIR* phiList;
buzbee67bf8852011-08-17 17:51:35 -0700502
Bill Buzbeea114add2012-05-03 15:00:40 -0700503 /* Use counts of ssa names */
504 GrowableList useCounts; // Weighted by nesting depth
505 GrowableList rawUseCounts; // Not weighted
buzbee239c4e72012-03-16 08:42:29 -0700506
Bill Buzbeea114add2012-05-03 15:00:40 -0700507 /* Optimization support */
508 GrowableList loopHeaders;
buzbee239c4e72012-03-16 08:42:29 -0700509
Bill Buzbeea114add2012-05-03 15:00:40 -0700510 /* Map SSA names to location */
511 RegLocation* regLocation;
512 int sequenceNumber;
buzbee67bf8852011-08-17 17:51:35 -0700513
Bill Buzbeea114add2012-05-03 15:00:40 -0700514 /* Keep track of Dalvik vReg to physical register mappings */
515 PromotionMap* promotionMap;
buzbee67bc2362011-10-11 18:08:40 -0700516
Bill Buzbeea114add2012-05-03 15:00:40 -0700517 /* SSA name for Method* */
518 int methodSReg;
buzbeead8f15e2012-06-18 14:49:45 -0700519 RegLocation methodLoc; // Describes location of method*
buzbeee1965672012-03-11 18:39:19 -0700520
Bill Buzbeea114add2012-05-03 15:00:40 -0700521 /*
522 * Set to the Dalvik PC of the switch instruction if it has more than
523 * MAX_CHAINED_SWITCH_CASES cases.
524 */
525 const u2* switchOverflowPad;
buzbee67bf8852011-08-17 17:51:35 -0700526
Bill Buzbeea114add2012-05-03 15:00:40 -0700527 int numReachableBlocks;
528 int numDalvikRegisters; // method->registersSize
529 BasicBlock* entryBlock;
530 BasicBlock* exitBlock;
531 BasicBlock* curBlock;
532 BasicBlock* nextCodegenBlock; // for extended trace codegen
533 GrowableList dfsOrder;
534 GrowableList dfsPostOrder;
535 GrowableList domPostOrderTraversal;
536 GrowableList throwLaunchpads;
537 GrowableList suspendLaunchpads;
538 GrowableList intrinsicLaunchpads;
539 GrowableList compilerTemps;
540 int* iDomList;
541 ArenaBitVector* tryBlockAddr;
542 ArenaBitVector** defBlockMatrix; // numDalvikRegister x numBlocks
543 ArenaBitVector* tempBlockV;
544 ArenaBitVector* tempDalvikRegisterV;
545 ArenaBitVector* tempSSARegisterV; // numSSARegs
buzbee2cfc6392012-05-07 14:51:40 -0700546 int* tempSSABlockIdV; // working storage for Phi labels
Bill Buzbeea114add2012-05-03 15:00:40 -0700547 bool printSSANames;
buzbeea1da8a52012-07-09 14:00:21 -0700548 LIR* blockLabelList;
Bill Buzbeea114add2012-05-03 15:00:40 -0700549 bool quitLoopMode; // cold path/complex bytecode
550 int preservedRegsUsed; // How many callee save regs used
551 /*
552 * Frame layout details.
553 * NOTE: for debug support it will be necessary to add a structure
554 * to map the Dalvik virtual registers to the promoted registers.
555 * NOTE: "num" fields are in 4-byte words, "Size" and "Offset" in bytes.
556 */
557 int numIns;
558 int numOuts;
559 int numRegs; // Unlike numDalvikRegisters, does not include ins
560 int numCoreSpills;
561 int numFPSpills;
562 int numCompilerTemps;
563 int frameSize;
564 unsigned int coreSpillMask;
565 unsigned int fpSpillMask;
566 unsigned int attrs;
567 /*
568 * CLEANUP/RESTRUCTURE: The code generation utilities don't have a built-in
569 * mechanism to propagate the original Dalvik opcode address to the
570 * associated generated instructions. For the trace compiler, this wasn't
571 * necessary because the interpreter handled all throws and debugging
572 * requests. For now we'll handle this by placing the Dalvik offset
573 * in the CompilationUnit struct before codegen for each instruction.
574 * The low-level LIR creation utilites will pull it from here. Should
575 * be rewritten.
576 */
577 int currentDalvikOffset;
578 GrowableList switchTables;
579 GrowableList fillArrayData;
580 const u2* insns;
581 u4 insnsSize;
582 bool disableDataflow; // Skip dataflow analysis if possible
583 SafeMap<unsigned int, BasicBlock*> blockMap; // findBlock lookup cache
buzbeed1643e42012-09-05 14:06:51 -0700584 SafeMap<unsigned int, unsigned int> blockIdMap; // Block collapse lookup cache
Bill Buzbeea114add2012-05-03 15:00:40 -0700585 SafeMap<unsigned int, LIR*> boundaryMap; // boundary lookup cache
586 int defCount; // Used to estimate number of SSA names
Elliott Hughese52e49b2012-04-02 16:05:44 -0700587
Bill Buzbeea114add2012-05-03 15:00:40 -0700588 // If non-empty, apply optimizer/debug flags only to matching methods.
589 std::string compilerMethodMatch;
590 // Flips sense of compilerMethodMatch - apply flags if doesn't match.
591 bool compilerFlipMatch;
592 ArenaMemBlock* arenaHead;
593 ArenaMemBlock* currentArena;
594 int numArenaBlocks;
595 Memstats* mstats;
buzbeed1643e42012-09-05 14:06:51 -0700596 Checkstats* checkstats;
buzbee2cfc6392012-05-07 14:51:40 -0700597#if defined(ART_USE_QUICK_COMPILER)
598 bool genBitcode;
599 llvm::LLVMContext* context;
600 llvm::Module* module;
601 llvm::Function* func;
602 greenland::IntrinsicHelper* intrinsic_helper;
603 greenland::IRBuilder* irb;
604 llvm::BasicBlock* placeholderBB;
605 llvm::BasicBlock* entryBB;
buzbee4be777b2012-07-12 14:38:18 -0700606 llvm::BasicBlock* entryTargetBB;
buzbee2cfc6392012-05-07 14:51:40 -0700607 std::string bitcode_filename;
608 GrowableList llvmValues;
609 int32_t tempName;
610 SafeMap<llvm::BasicBlock*, LIR*> blockToLabelMap; // llvm bb -> LIR label
611 SafeMap<int32_t, llvm::BasicBlock*> idToBlockMap; // block id -> llvm bb
612 SafeMap<llvm::Value*, RegLocation> locMap; // llvm Value to loc rec
buzbeeb03f4872012-06-11 15:22:11 -0700613 bool requireShadowFrame;
614 int numShadowFrameEntries;
615 int* shadowMap;
buzbee0967a252012-09-14 10:43:54 -0700616 std::set<llvm::BasicBlock*> llvmBlocks;
buzbee2cfc6392012-05-07 14:51:40 -0700617#endif
buzbee3d661942012-03-14 17:37:27 -0700618#ifndef NDEBUG
Bill Buzbeea114add2012-05-03 15:00:40 -0700619 /*
620 * Sanity checking for the register temp tracking. The same ssa
621 * name should never be associated with one temp register per
622 * instruction compilation.
623 */
624 int liveSReg;
buzbee3d661942012-03-14 17:37:27 -0700625#endif
buzbee2cfc6392012-05-07 14:51:40 -0700626 int* opcodeCount; // Count Dalvik opcodes for tuning
Elliott Hughes719ace42012-03-09 18:06:03 -0800627};
buzbee67bf8852011-08-17 17:51:35 -0700628
Elliott Hughes719ace42012-03-09 18:06:03 -0800629enum OpSize {
Bill Buzbeea114add2012-05-03 15:00:40 -0700630 kWord,
631 kLong,
632 kSingle,
633 kDouble,
634 kUnsignedHalf,
635 kSignedHalf,
636 kUnsignedByte,
637 kSignedByte,
Elliott Hughes719ace42012-03-09 18:06:03 -0800638};
buzbeee3acd072012-02-25 17:03:10 -0800639
Elliott Hughes719ace42012-03-09 18:06:03 -0800640enum OpKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700641 kOpMov,
642 kOpMvn,
643 kOpCmp,
644 kOpLsl,
645 kOpLsr,
646 kOpAsr,
647 kOpRor,
648 kOpNot,
649 kOpAnd,
650 kOpOr,
651 kOpXor,
652 kOpNeg,
653 kOpAdd,
654 kOpAdc,
655 kOpSub,
656 kOpSbc,
657 kOpRsub,
658 kOpMul,
659 kOpDiv,
660 kOpRem,
661 kOpBic,
662 kOpCmn,
663 kOpTst,
664 kOpBkpt,
665 kOpBlx,
666 kOpPush,
667 kOpPop,
668 kOp2Char,
669 kOp2Short,
670 kOp2Byte,
671 kOpCondBr,
672 kOpUncondBr,
673 kOpBx,
674 kOpInvalid,
Elliott Hughes719ace42012-03-09 18:06:03 -0800675};
buzbee31a4a6f2012-02-28 15:36:15 -0800676
Ian Rogers680b1bd2012-03-07 20:18:49 -0800677std::ostream& operator<<(std::ostream& os, const OpKind& kind);
678
Elliott Hughes719ace42012-03-09 18:06:03 -0800679enum ConditionCode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700680 kCondEq, // equal
681 kCondNe, // not equal
682 kCondCs, // carry set (unsigned less than)
683 kCondUlt = kCondCs,
684 kCondCc, // carry clear (unsigned greater than or same)
685 kCondUge = kCondCc,
686 kCondMi, // minus
687 kCondPl, // plus, positive or zero
688 kCondVs, // overflow
689 kCondVc, // no overflow
690 kCondHi, // unsigned greater than
691 kCondLs, // unsigned lower or same
692 kCondGe, // signed greater than or equal
693 kCondLt, // signed less than
694 kCondGt, // signed greater than
695 kCondLe, // signed less than or equal
696 kCondAl, // always
697 kCondNv, // never
Elliott Hughes719ace42012-03-09 18:06:03 -0800698};
buzbee31a4a6f2012-02-28 15:36:15 -0800699
Elliott Hughes719ace42012-03-09 18:06:03 -0800700enum ThrowKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700701 kThrowNullPointer,
702 kThrowDivZero,
703 kThrowArrayBounds,
Bill Buzbeea114add2012-05-03 15:00:40 -0700704 kThrowNoSuchMethod,
705 kThrowStackOverflow,
Elliott Hughes719ace42012-03-09 18:06:03 -0800706};
buzbee31a4a6f2012-02-28 15:36:15 -0800707
Elliott Hughes719ace42012-03-09 18:06:03 -0800708struct SwitchTable {
Bill Buzbeea114add2012-05-03 15:00:40 -0700709 int offset;
710 const u2* table; // Original dex table
711 int vaddr; // Dalvik offset of switch opcode
712 LIR* anchor; // Reference instruction for relative offsets
713 LIR** targets; // Array of case targets
Elliott Hughes719ace42012-03-09 18:06:03 -0800714};
buzbee5de34942012-03-01 14:51:57 -0800715
Elliott Hughes719ace42012-03-09 18:06:03 -0800716struct FillArrayData {
Bill Buzbeea114add2012-05-03 15:00:40 -0700717 int offset;
718 const u2* table; // Original dex table
719 int size;
720 int vaddr; // Dalvik offset of FILL_ARRAY_DATA opcode
Elliott Hughes719ace42012-03-09 18:06:03 -0800721};
buzbee5de34942012-03-01 14:51:57 -0800722
buzbee16da88c2012-03-20 10:38:17 -0700723#define MAX_PATTERN_LEN 5
724
725enum SpecialCaseHandler {
Bill Buzbeea114add2012-05-03 15:00:40 -0700726 kNoHandler,
727 kNullMethod,
728 kConstFunction,
729 kIGet,
730 kIGetBoolean,
731 kIGetObject,
732 kIGetByte,
733 kIGetChar,
734 kIGetShort,
735 kIGetWide,
736 kIPut,
737 kIPutBoolean,
738 kIPutObject,
739 kIPutByte,
740 kIPutChar,
741 kIPutShort,
742 kIPutWide,
743 kIdentity,
buzbee16da88c2012-03-20 10:38:17 -0700744};
745
746struct CodePattern {
Bill Buzbeea114add2012-05-03 15:00:40 -0700747 const Instruction::Code opcodes[MAX_PATTERN_LEN];
748 const SpecialCaseHandler handlerCode;
buzbee16da88c2012-03-20 10:38:17 -0700749};
750
751static const CodePattern specialPatterns[] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700752 {{Instruction::RETURN_VOID}, kNullMethod},
753 {{Instruction::CONST, Instruction::RETURN}, kConstFunction},
754 {{Instruction::CONST_4, Instruction::RETURN}, kConstFunction},
755 {{Instruction::CONST_4, Instruction::RETURN_OBJECT}, kConstFunction},
756 {{Instruction::CONST_16, Instruction::RETURN}, kConstFunction},
757 {{Instruction::IGET, Instruction:: RETURN}, kIGet},
758 {{Instruction::IGET_BOOLEAN, Instruction::RETURN}, kIGetBoolean},
759 {{Instruction::IGET_OBJECT, Instruction::RETURN_OBJECT}, kIGetObject},
760 {{Instruction::IGET_BYTE, Instruction::RETURN}, kIGetByte},
761 {{Instruction::IGET_CHAR, Instruction::RETURN}, kIGetChar},
762 {{Instruction::IGET_SHORT, Instruction::RETURN}, kIGetShort},
763 {{Instruction::IGET_WIDE, Instruction::RETURN_WIDE}, kIGetWide},
764 {{Instruction::IPUT, Instruction::RETURN_VOID}, kIPut},
765 {{Instruction::IPUT_BOOLEAN, Instruction::RETURN_VOID}, kIPutBoolean},
766 {{Instruction::IPUT_OBJECT, Instruction::RETURN_VOID}, kIPutObject},
767 {{Instruction::IPUT_BYTE, Instruction::RETURN_VOID}, kIPutByte},
768 {{Instruction::IPUT_CHAR, Instruction::RETURN_VOID}, kIPutChar},
769 {{Instruction::IPUT_SHORT, Instruction::RETURN_VOID}, kIPutShort},
770 {{Instruction::IPUT_WIDE, Instruction::RETURN_VOID}, kIPutWide},
771 {{Instruction::RETURN}, kIdentity},
772 {{Instruction::RETURN_OBJECT}, kIdentity},
773 {{Instruction::RETURN_WIDE}, kIdentity},
buzbee16da88c2012-03-20 10:38:17 -0700774};
buzbee5de34942012-03-01 14:51:57 -0800775
buzbee5abfa3e2012-01-31 17:01:43 -0800776BasicBlock* oatNewBB(CompilationUnit* cUnit, BBType blockType, int blockId);
buzbee67bf8852011-08-17 17:51:35 -0700777
778void oatAppendMIR(BasicBlock* bb, MIR* mir);
779
780void oatPrependMIR(BasicBlock* bb, MIR* mir);
781
782void oatInsertMIRAfter(BasicBlock* bb, MIR* currentMIR, MIR* newMIR);
783
784void oatAppendLIR(CompilationUnit* cUnit, LIR* lir);
785
786void oatInsertLIRBefore(LIR* currentLIR, LIR* newLIR);
787
788void oatInsertLIRAfter(LIR* currentLIR, LIR* newLIR);
789
buzbee15bf9802012-06-12 17:49:27 -0700790MIR* oatFindMoveResult(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir);
buzbee67bf8852011-08-17 17:51:35 -0700791/* Debug Utilities */
792void oatDumpCompilationUnit(CompilationUnit* cUnit);
793
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800794} // namespace art
795
buzbee67bf8852011-08-17 17:51:35 -0700796#endif // ART_SRC_COMPILER_COMPILER_IR_H_