blob: c5bbae62835bdc179439630c80fa1f7eb786753f [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;
Ian Rogers0c7abda2012-09-19 13:33:42 -0700475 std::vector<uint8_t> nativeGcMap;
Bill Buzbeea114add2012-05-03 15:00:40 -0700476 bool genDebugger; // Generate code for debugger
477 bool printMe;
478 bool hasClassLiterals; // Contains class ptrs used as literals
479 bool hasLoop; // Contains a loop
480 bool hasInvoke; // Contains an invoke instruction
481 bool heapMemOp; // Mark mem ops for self verification
482 bool qdMode; // Compile for code size/compile time
483 bool usesLinkRegister; // For self-verification only
484 bool methodTraceSupport; // For TraceView profiling
485 RegisterPool* regPool;
486 int optRound; // round number to tell an LIR's age
487 InstructionSet instructionSet;
488 /* Number of total regs used in the whole cUnit after SSA transformation */
489 int numSSARegs;
490 /* Map SSA reg i to the base virtual register/subscript */
491 GrowableList* ssaBaseVRegs;
492 GrowableList* ssaSubscripts;
buzbee2cfc6392012-05-07 14:51:40 -0700493 GrowableList* ssaStrings;
buzbee67bf8852011-08-17 17:51:35 -0700494
Bill Buzbeea114add2012-05-03 15:00:40 -0700495 /* The following are new data structures to support SSA representations */
496 /* Map original Dalvik virtual reg i to the current SSA name */
497 int* vRegToSSAMap; // length == method->registersSize
498 int* SSALastDefs; // length == method->registersSize
499 ArenaBitVector* isConstantV; // length == numSSAReg
500 int* constantValues; // length == numSSAReg
501 int* phiAliasMap; // length == numSSAReg
502 MIR* phiList;
buzbee67bf8852011-08-17 17:51:35 -0700503
Bill Buzbeea114add2012-05-03 15:00:40 -0700504 /* Use counts of ssa names */
505 GrowableList useCounts; // Weighted by nesting depth
506 GrowableList rawUseCounts; // Not weighted
buzbee239c4e72012-03-16 08:42:29 -0700507
Bill Buzbeea114add2012-05-03 15:00:40 -0700508 /* Optimization support */
509 GrowableList loopHeaders;
buzbee239c4e72012-03-16 08:42:29 -0700510
Bill Buzbeea114add2012-05-03 15:00:40 -0700511 /* Map SSA names to location */
512 RegLocation* regLocation;
513 int sequenceNumber;
buzbee67bf8852011-08-17 17:51:35 -0700514
Bill Buzbeea114add2012-05-03 15:00:40 -0700515 /* Keep track of Dalvik vReg to physical register mappings */
516 PromotionMap* promotionMap;
buzbee67bc2362011-10-11 18:08:40 -0700517
Bill Buzbeea114add2012-05-03 15:00:40 -0700518 /* SSA name for Method* */
519 int methodSReg;
buzbeead8f15e2012-06-18 14:49:45 -0700520 RegLocation methodLoc; // Describes location of method*
buzbeee1965672012-03-11 18:39:19 -0700521
Bill Buzbeea114add2012-05-03 15:00:40 -0700522 /*
523 * Set to the Dalvik PC of the switch instruction if it has more than
524 * MAX_CHAINED_SWITCH_CASES cases.
525 */
526 const u2* switchOverflowPad;
buzbee67bf8852011-08-17 17:51:35 -0700527
Bill Buzbeea114add2012-05-03 15:00:40 -0700528 int numReachableBlocks;
529 int numDalvikRegisters; // method->registersSize
530 BasicBlock* entryBlock;
531 BasicBlock* exitBlock;
532 BasicBlock* curBlock;
533 BasicBlock* nextCodegenBlock; // for extended trace codegen
534 GrowableList dfsOrder;
535 GrowableList dfsPostOrder;
536 GrowableList domPostOrderTraversal;
537 GrowableList throwLaunchpads;
538 GrowableList suspendLaunchpads;
539 GrowableList intrinsicLaunchpads;
540 GrowableList compilerTemps;
541 int* iDomList;
542 ArenaBitVector* tryBlockAddr;
543 ArenaBitVector** defBlockMatrix; // numDalvikRegister x numBlocks
544 ArenaBitVector* tempBlockV;
545 ArenaBitVector* tempDalvikRegisterV;
546 ArenaBitVector* tempSSARegisterV; // numSSARegs
buzbee2cfc6392012-05-07 14:51:40 -0700547 int* tempSSABlockIdV; // working storage for Phi labels
Bill Buzbeea114add2012-05-03 15:00:40 -0700548 bool printSSANames;
buzbeea1da8a52012-07-09 14:00:21 -0700549 LIR* blockLabelList;
Bill Buzbeea114add2012-05-03 15:00:40 -0700550 bool quitLoopMode; // cold path/complex bytecode
551 int preservedRegsUsed; // How many callee save regs used
552 /*
553 * Frame layout details.
554 * NOTE: for debug support it will be necessary to add a structure
555 * to map the Dalvik virtual registers to the promoted registers.
556 * NOTE: "num" fields are in 4-byte words, "Size" and "Offset" in bytes.
557 */
558 int numIns;
559 int numOuts;
560 int numRegs; // Unlike numDalvikRegisters, does not include ins
561 int numCoreSpills;
562 int numFPSpills;
563 int numCompilerTemps;
564 int frameSize;
565 unsigned int coreSpillMask;
566 unsigned int fpSpillMask;
567 unsigned int attrs;
568 /*
569 * CLEANUP/RESTRUCTURE: The code generation utilities don't have a built-in
570 * mechanism to propagate the original Dalvik opcode address to the
571 * associated generated instructions. For the trace compiler, this wasn't
572 * necessary because the interpreter handled all throws and debugging
573 * requests. For now we'll handle this by placing the Dalvik offset
574 * in the CompilationUnit struct before codegen for each instruction.
575 * The low-level LIR creation utilites will pull it from here. Should
576 * be rewritten.
577 */
578 int currentDalvikOffset;
579 GrowableList switchTables;
580 GrowableList fillArrayData;
581 const u2* insns;
582 u4 insnsSize;
583 bool disableDataflow; // Skip dataflow analysis if possible
584 SafeMap<unsigned int, BasicBlock*> blockMap; // findBlock lookup cache
buzbeed1643e42012-09-05 14:06:51 -0700585 SafeMap<unsigned int, unsigned int> blockIdMap; // Block collapse lookup cache
Bill Buzbeea114add2012-05-03 15:00:40 -0700586 SafeMap<unsigned int, LIR*> boundaryMap; // boundary lookup cache
587 int defCount; // Used to estimate number of SSA names
Elliott Hughese52e49b2012-04-02 16:05:44 -0700588
Bill Buzbeea114add2012-05-03 15:00:40 -0700589 // If non-empty, apply optimizer/debug flags only to matching methods.
590 std::string compilerMethodMatch;
591 // Flips sense of compilerMethodMatch - apply flags if doesn't match.
592 bool compilerFlipMatch;
593 ArenaMemBlock* arenaHead;
594 ArenaMemBlock* currentArena;
595 int numArenaBlocks;
596 Memstats* mstats;
buzbeed1643e42012-09-05 14:06:51 -0700597 Checkstats* checkstats;
buzbee2cfc6392012-05-07 14:51:40 -0700598#if defined(ART_USE_QUICK_COMPILER)
599 bool genBitcode;
TDYa12755e5e6c2012-09-11 15:14:42 -0700600 QuickCompiler* quick_compiler;
buzbee2cfc6392012-05-07 14:51:40 -0700601 llvm::LLVMContext* context;
602 llvm::Module* module;
603 llvm::Function* func;
604 greenland::IntrinsicHelper* intrinsic_helper;
605 greenland::IRBuilder* irb;
606 llvm::BasicBlock* placeholderBB;
607 llvm::BasicBlock* entryBB;
buzbee4be777b2012-07-12 14:38:18 -0700608 llvm::BasicBlock* entryTargetBB;
buzbee2cfc6392012-05-07 14:51:40 -0700609 std::string bitcode_filename;
610 GrowableList llvmValues;
611 int32_t tempName;
612 SafeMap<llvm::BasicBlock*, LIR*> blockToLabelMap; // llvm bb -> LIR label
613 SafeMap<int32_t, llvm::BasicBlock*> idToBlockMap; // block id -> llvm bb
614 SafeMap<llvm::Value*, RegLocation> locMap; // llvm Value to loc rec
buzbeeb03f4872012-06-11 15:22:11 -0700615 bool requireShadowFrame;
616 int numShadowFrameEntries;
617 int* shadowMap;
buzbee0967a252012-09-14 10:43:54 -0700618 std::set<llvm::BasicBlock*> llvmBlocks;
buzbee2cfc6392012-05-07 14:51:40 -0700619#endif
buzbee3d661942012-03-14 17:37:27 -0700620#ifndef NDEBUG
Bill Buzbeea114add2012-05-03 15:00:40 -0700621 /*
622 * Sanity checking for the register temp tracking. The same ssa
623 * name should never be associated with one temp register per
624 * instruction compilation.
625 */
626 int liveSReg;
buzbee3d661942012-03-14 17:37:27 -0700627#endif
buzbee2cfc6392012-05-07 14:51:40 -0700628 int* opcodeCount; // Count Dalvik opcodes for tuning
Elliott Hughes719ace42012-03-09 18:06:03 -0800629};
buzbee67bf8852011-08-17 17:51:35 -0700630
Elliott Hughes719ace42012-03-09 18:06:03 -0800631enum OpSize {
Bill Buzbeea114add2012-05-03 15:00:40 -0700632 kWord,
633 kLong,
634 kSingle,
635 kDouble,
636 kUnsignedHalf,
637 kSignedHalf,
638 kUnsignedByte,
639 kSignedByte,
Elliott Hughes719ace42012-03-09 18:06:03 -0800640};
buzbeee3acd072012-02-25 17:03:10 -0800641
Elliott Hughes719ace42012-03-09 18:06:03 -0800642enum OpKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700643 kOpMov,
644 kOpMvn,
645 kOpCmp,
646 kOpLsl,
647 kOpLsr,
648 kOpAsr,
649 kOpRor,
650 kOpNot,
651 kOpAnd,
652 kOpOr,
653 kOpXor,
654 kOpNeg,
655 kOpAdd,
656 kOpAdc,
657 kOpSub,
658 kOpSbc,
659 kOpRsub,
660 kOpMul,
661 kOpDiv,
662 kOpRem,
663 kOpBic,
664 kOpCmn,
665 kOpTst,
666 kOpBkpt,
667 kOpBlx,
668 kOpPush,
669 kOpPop,
670 kOp2Char,
671 kOp2Short,
672 kOp2Byte,
673 kOpCondBr,
674 kOpUncondBr,
675 kOpBx,
676 kOpInvalid,
Elliott Hughes719ace42012-03-09 18:06:03 -0800677};
buzbee31a4a6f2012-02-28 15:36:15 -0800678
Ian Rogers680b1bd2012-03-07 20:18:49 -0800679std::ostream& operator<<(std::ostream& os, const OpKind& kind);
680
Elliott Hughes719ace42012-03-09 18:06:03 -0800681enum ConditionCode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700682 kCondEq, // equal
683 kCondNe, // not equal
684 kCondCs, // carry set (unsigned less than)
685 kCondUlt = kCondCs,
686 kCondCc, // carry clear (unsigned greater than or same)
687 kCondUge = kCondCc,
688 kCondMi, // minus
689 kCondPl, // plus, positive or zero
690 kCondVs, // overflow
691 kCondVc, // no overflow
692 kCondHi, // unsigned greater than
693 kCondLs, // unsigned lower or same
694 kCondGe, // signed greater than or equal
695 kCondLt, // signed less than
696 kCondGt, // signed greater than
697 kCondLe, // signed less than or equal
698 kCondAl, // always
699 kCondNv, // never
Elliott Hughes719ace42012-03-09 18:06:03 -0800700};
buzbee31a4a6f2012-02-28 15:36:15 -0800701
Elliott Hughes719ace42012-03-09 18:06:03 -0800702enum ThrowKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700703 kThrowNullPointer,
704 kThrowDivZero,
705 kThrowArrayBounds,
Bill Buzbeea114add2012-05-03 15:00:40 -0700706 kThrowNoSuchMethod,
707 kThrowStackOverflow,
Elliott Hughes719ace42012-03-09 18:06:03 -0800708};
buzbee31a4a6f2012-02-28 15:36:15 -0800709
Elliott Hughes719ace42012-03-09 18:06:03 -0800710struct SwitchTable {
Bill Buzbeea114add2012-05-03 15:00:40 -0700711 int offset;
712 const u2* table; // Original dex table
713 int vaddr; // Dalvik offset of switch opcode
714 LIR* anchor; // Reference instruction for relative offsets
715 LIR** targets; // Array of case targets
Elliott Hughes719ace42012-03-09 18:06:03 -0800716};
buzbee5de34942012-03-01 14:51:57 -0800717
Elliott Hughes719ace42012-03-09 18:06:03 -0800718struct FillArrayData {
Bill Buzbeea114add2012-05-03 15:00:40 -0700719 int offset;
720 const u2* table; // Original dex table
721 int size;
722 int vaddr; // Dalvik offset of FILL_ARRAY_DATA opcode
Elliott Hughes719ace42012-03-09 18:06:03 -0800723};
buzbee5de34942012-03-01 14:51:57 -0800724
buzbee16da88c2012-03-20 10:38:17 -0700725#define MAX_PATTERN_LEN 5
726
727enum SpecialCaseHandler {
Bill Buzbeea114add2012-05-03 15:00:40 -0700728 kNoHandler,
729 kNullMethod,
730 kConstFunction,
731 kIGet,
732 kIGetBoolean,
733 kIGetObject,
734 kIGetByte,
735 kIGetChar,
736 kIGetShort,
737 kIGetWide,
738 kIPut,
739 kIPutBoolean,
740 kIPutObject,
741 kIPutByte,
742 kIPutChar,
743 kIPutShort,
744 kIPutWide,
745 kIdentity,
buzbee16da88c2012-03-20 10:38:17 -0700746};
747
748struct CodePattern {
Bill Buzbeea114add2012-05-03 15:00:40 -0700749 const Instruction::Code opcodes[MAX_PATTERN_LEN];
750 const SpecialCaseHandler handlerCode;
buzbee16da88c2012-03-20 10:38:17 -0700751};
752
753static const CodePattern specialPatterns[] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700754 {{Instruction::RETURN_VOID}, kNullMethod},
755 {{Instruction::CONST, Instruction::RETURN}, kConstFunction},
756 {{Instruction::CONST_4, Instruction::RETURN}, kConstFunction},
757 {{Instruction::CONST_4, Instruction::RETURN_OBJECT}, kConstFunction},
758 {{Instruction::CONST_16, Instruction::RETURN}, kConstFunction},
759 {{Instruction::IGET, Instruction:: RETURN}, kIGet},
760 {{Instruction::IGET_BOOLEAN, Instruction::RETURN}, kIGetBoolean},
761 {{Instruction::IGET_OBJECT, Instruction::RETURN_OBJECT}, kIGetObject},
762 {{Instruction::IGET_BYTE, Instruction::RETURN}, kIGetByte},
763 {{Instruction::IGET_CHAR, Instruction::RETURN}, kIGetChar},
764 {{Instruction::IGET_SHORT, Instruction::RETURN}, kIGetShort},
765 {{Instruction::IGET_WIDE, Instruction::RETURN_WIDE}, kIGetWide},
766 {{Instruction::IPUT, Instruction::RETURN_VOID}, kIPut},
767 {{Instruction::IPUT_BOOLEAN, Instruction::RETURN_VOID}, kIPutBoolean},
768 {{Instruction::IPUT_OBJECT, Instruction::RETURN_VOID}, kIPutObject},
769 {{Instruction::IPUT_BYTE, Instruction::RETURN_VOID}, kIPutByte},
770 {{Instruction::IPUT_CHAR, Instruction::RETURN_VOID}, kIPutChar},
771 {{Instruction::IPUT_SHORT, Instruction::RETURN_VOID}, kIPutShort},
772 {{Instruction::IPUT_WIDE, Instruction::RETURN_VOID}, kIPutWide},
773 {{Instruction::RETURN}, kIdentity},
774 {{Instruction::RETURN_OBJECT}, kIdentity},
775 {{Instruction::RETURN_WIDE}, kIdentity},
buzbee16da88c2012-03-20 10:38:17 -0700776};
buzbee5de34942012-03-01 14:51:57 -0800777
buzbee5abfa3e2012-01-31 17:01:43 -0800778BasicBlock* oatNewBB(CompilationUnit* cUnit, BBType blockType, int blockId);
buzbee67bf8852011-08-17 17:51:35 -0700779
780void oatAppendMIR(BasicBlock* bb, MIR* mir);
781
782void oatPrependMIR(BasicBlock* bb, MIR* mir);
783
784void oatInsertMIRAfter(BasicBlock* bb, MIR* currentMIR, MIR* newMIR);
785
786void oatAppendLIR(CompilationUnit* cUnit, LIR* lir);
787
788void oatInsertLIRBefore(LIR* currentLIR, LIR* newLIR);
789
790void oatInsertLIRAfter(LIR* currentLIR, LIR* newLIR);
791
buzbee15bf9802012-06-12 17:49:27 -0700792MIR* oatFindMoveResult(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir);
buzbee67bf8852011-08-17 17:51:35 -0700793/* Debug Utilities */
794void oatDumpCompilationUnit(CompilationUnit* cUnit);
795
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800796} // namespace art
797
buzbee67bf8852011-08-17 17:51:35 -0700798#endif // ART_SRC_COMPILER_COMPILER_IR_H_