blob: 6c6442d94312dac4404a65f38843b59183b58e0b [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
buzbeeefc63692012-11-14 16:31:52 -080022#include "codegen/optimizer.h"
23#include "compiler_utility.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#include "greenland/ir_builder.h"
27#include "llvm/Module.h"
buzbee67bf8852011-08-17 17:51:35 -070028
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080029namespace art {
30
buzbee31a4a6f2012-02-28 15:36:15 -080031#define SLOW_FIELD_PATH (cUnit->enableDebug & (1 << kDebugSlowFieldPath))
32#define SLOW_INVOKE_PATH (cUnit->enableDebug & (1 << kDebugSlowInvokePath))
33#define SLOW_STRING_PATH (cUnit->enableDebug & (1 << kDebugSlowStringPath))
34#define SLOW_TYPE_PATH (cUnit->enableDebug & (1 << kDebugSlowTypePath))
buzbee31a4a6f2012-02-28 15:36:15 -080035#define EXERCISE_SLOWEST_STRING_PATH (cUnit->enableDebug & \
Bill Buzbeea114add2012-05-03 15:00:40 -070036 (1 << kDebugSlowestStringPath))
buzbee31a4a6f2012-02-28 15:36:15 -080037
buzbeeca7a5e42012-08-20 11:12:18 -070038// Minimum field size to contain Dalvik vReg number
39#define VREG_NUM_WIDTH 16
40
Elliott Hughes719ace42012-03-09 18:06:03 -080041enum RegisterClass {
Bill Buzbeea114add2012-05-03 15:00:40 -070042 kCoreReg,
43 kFPReg,
44 kAnyReg,
Elliott Hughes719ace42012-03-09 18:06:03 -080045};
buzbee67bf8852011-08-17 17:51:35 -070046
buzbeef0504cd2012-11-13 16:31:10 -080047enum SpecialTargetRegister {
48 kSelf, // Thread
49 kSuspend, // Used to reduce suspend checks
50 kLr,
51 kPc,
52 kSp,
53 kArg0,
54 kArg1,
55 kArg2,
56 kArg3,
57 kFArg0,
58 kFArg1,
59 kFArg2,
60 kFArg3,
61 kRet0,
62 kRet1,
63 kInvokeTgt,
64 kCount
65};
66
Elliott Hughes719ace42012-03-09 18:06:03 -080067enum RegLocationType {
Bill Buzbeea114add2012-05-03 15:00:40 -070068 kLocDalvikFrame = 0, // Normal Dalvik register
69 kLocPhysReg,
70 kLocCompilerTemp,
71 kLocInvalid
Elliott Hughes719ace42012-03-09 18:06:03 -080072};
buzbee67bf8852011-08-17 17:51:35 -070073
Elliott Hughes719ace42012-03-09 18:06:03 -080074struct PromotionMap {
Bill Buzbeea114add2012-05-03 15:00:40 -070075 RegLocationType coreLocation:3;
76 u1 coreReg;
77 RegLocationType fpLocation:3;
78 u1 fpReg;
79 bool firstInPair;
Elliott Hughes719ace42012-03-09 18:06:03 -080080};
buzbee67bc2362011-10-11 18:08:40 -070081
Elliott Hughes719ace42012-03-09 18:06:03 -080082struct RegLocation {
Bill Buzbeea114add2012-05-03 15:00:40 -070083 RegLocationType location:3;
84 unsigned wide:1;
85 unsigned defined:1; // Do we know the type?
buzbee2cfc6392012-05-07 14:51:40 -070086 unsigned isConst:1; // Constant, value in cUnit->constantValues[]
Bill Buzbeea114add2012-05-03 15:00:40 -070087 unsigned fp:1; // Floating point?
88 unsigned core:1; // Non-floating point?
buzbeebff24652012-05-06 16:22:05 -070089 unsigned ref:1; // Something GC cares about
Bill Buzbeea114add2012-05-03 15:00:40 -070090 unsigned highWord:1; // High word of pair?
91 unsigned home:1; // Does this represent the home location?
92 u1 lowReg; // First physical register
93 u1 highReg; // 2nd physical register (if wide)
94 int32_t sRegLow; // SSA name for low Dalvik word
buzbee2cfc6392012-05-07 14:51:40 -070095 int32_t origSReg; // TODO: remove after Bitcode gen complete
96 // and consolodate usage w/ sRegLow
buzbeee1965672012-03-11 18:39:19 -070097};
98
99struct CompilerTemp {
Bill Buzbeea114add2012-05-03 15:00:40 -0700100 int sReg;
101 ArenaBitVector* bv;
Elliott Hughes719ace42012-03-09 18:06:03 -0800102};
buzbee67bf8852011-08-17 17:51:35 -0700103
buzbee3b3dbdd2012-06-13 13:39:34 -0700104struct CallInfo {
buzbee15bf9802012-06-12 17:49:27 -0700105 int numArgWords; // Note: word count, not arg count
106 RegLocation* args; // One for each word of arguments
107 RegLocation result; // Eventual target of MOVE_RESULT
108 int optFlags;
109 InvokeType type;
110 uint32_t dexIdx;
buzbee3b3dbdd2012-06-13 13:39:34 -0700111 uint32_t index; // Method idx for invokes, type idx for FilledNewArray
buzbee15bf9802012-06-12 17:49:27 -0700112 uintptr_t directCode;
113 uintptr_t directMethod;
114 RegLocation target; // Target of following move_result
115 bool skipThis;
116 bool isRange;
117 int offset; // Dalvik offset
118};
119
buzbeee3acd072012-02-25 17:03:10 -0800120 /*
121 * Data structure tracking the mapping between a Dalvik register (pair) and a
122 * native register (pair). The idea is to reuse the previously loaded value
123 * if possible, otherwise to keep the value in a native register as long as
124 * possible.
125 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800126struct RegisterInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700127 int reg; // Reg number
128 bool inUse; // Has it been allocated?
129 bool isTemp; // Can allocate as temp?
130 bool pair; // Part of a register pair?
131 int partner; // If pair, other reg of pair
132 bool live; // Is there an associated SSA name?
133 bool dirty; // If live, is it dirty?
134 int sReg; // Name of live value
135 LIR *defStart; // Starting inst in last def sequence
136 LIR *defEnd; // Ending inst in last def sequence
Elliott Hughes719ace42012-03-09 18:06:03 -0800137};
buzbeee3acd072012-02-25 17:03:10 -0800138
Elliott Hughes719ace42012-03-09 18:06:03 -0800139struct RegisterPool {
Bill Buzbeea114add2012-05-03 15:00:40 -0700140 int numCoreRegs;
141 RegisterInfo *coreRegs;
142 int nextCoreReg;
143 int numFPRegs;
144 RegisterInfo *FPRegs;
145 int nextFPReg;
Elliott Hughes719ace42012-03-09 18:06:03 -0800146};
buzbeee3acd072012-02-25 17:03:10 -0800147
buzbee67bf8852011-08-17 17:51:35 -0700148#define INVALID_SREG (-1)
buzbee3ddc0d12011-10-05 10:36:21 -0700149#define INVALID_VREG (0xFFFFU)
buzbee67bc2362011-10-11 18:08:40 -0700150#define INVALID_REG (0xFF)
buzbeeb046e162012-10-30 15:48:42 -0700151#define INVALID_OFFSET (0xDEADF00FU)
buzbee67bf8852011-08-17 17:51:35 -0700152
buzbeee1965672012-03-11 18:39:19 -0700153/* SSA encodings for special registers */
buzbee9c044ce2012-03-18 13:24:07 -0700154#define SSA_METHOD_BASEREG (-2)
buzbeee1965672012-03-11 18:39:19 -0700155/* First compiler temp basereg, grows smaller */
buzbee9c044ce2012-03-18 13:24:07 -0700156#define SSA_CTEMP_BASEREG (SSA_METHOD_BASEREG - 1)
buzbeee1965672012-03-11 18:39:19 -0700157
buzbee99ba9642012-01-25 14:23:14 -0800158/*
159 * Some code patterns cause the generation of excessively large
160 * methods - in particular initialization sequences. There isn't much
161 * benefit in optimizing these methods, and the cost can be very high.
162 * We attempt to identify these cases, and avoid performing most dataflow
163 * analysis. Two thresholds are used - one for known initializers and one
buzbee5abfa3e2012-01-31 17:01:43 -0800164 * for everything else.
buzbee99ba9642012-01-25 14:23:14 -0800165 */
buzbee5abfa3e2012-01-31 17:01:43 -0800166#define MANY_BLOCKS_INITIALIZER 1000 /* Threshold for switching dataflow off */
167#define MANY_BLOCKS 4000 /* Non-initializer threshold */
buzbee99ba9642012-01-25 14:23:14 -0800168
Elliott Hughes719ace42012-03-09 18:06:03 -0800169enum BBType {
Bill Buzbeea114add2012-05-03 15:00:40 -0700170 kEntryBlock,
171 kDalvikByteCode,
172 kExitBlock,
173 kExceptionHandling,
buzbeed1643e42012-09-05 14:06:51 -0700174 kDead,
Elliott Hughes719ace42012-03-09 18:06:03 -0800175};
buzbee67bf8852011-08-17 17:51:35 -0700176
buzbee31a4a6f2012-02-28 15:36:15 -0800177/* Utility macros to traverse the LIR list */
178#define NEXT_LIR(lir) (lir->next)
179#define PREV_LIR(lir) (lir->prev)
180
buzbeeec137432012-11-13 12:13:16 -0800181/* Defines for aliasInfo (tracks Dalvik register references) */
182#define DECODE_ALIAS_INFO_REG(X) (X & 0xffff)
183#define DECODE_ALIAS_INFO_WIDE_FLAG (0x80000000)
184#define DECODE_ALIAS_INFO_WIDE(X) ((X & DECODE_ALIAS_INFO_WIDE_FLAG) ? 1 : 0)
185#define ENCODE_ALIAS_INFO(REG, ISWIDE) (REG | (ISWIDE ? DECODE_ALIAS_INFO_WIDE_FLAG : 0))
186
187/*
188 * Def/Use encoding in 64-bit useMask/defMask. Low positions used for target-specific
189 * registers (and typically use the register number as the position). High positions
190 * reserved for common and abstract resources.
191 */
192
193enum ResourceEncodingPos {
194 kMustNotAlias = 63,
195 kHeapRef = 62, // Default memory reference type
196 kLiteral = 61, // Literal pool memory reference
197 kDalvikReg = 60, // Dalvik vReg memory reference
198 kFPStatus = 59,
199 kCCode = 58,
200 kLowestCommonResource = kCCode
201};
202
203/* Common resource macros */
204#define ENCODE_CCODE (1ULL << kCCode)
205#define ENCODE_FP_STATUS (1ULL << kFPStatus)
206
207/* Abstract memory locations */
208#define ENCODE_DALVIK_REG (1ULL << kDalvikReg)
209#define ENCODE_LITERAL (1ULL << kLiteral)
210#define ENCODE_HEAP_REF (1ULL << kHeapRef)
211#define ENCODE_MUST_NOT_ALIAS (1ULL << kMustNotAlias)
212
213#define ENCODE_ALL (~0ULL)
214#define ENCODE_MEM (ENCODE_DALVIK_REG | ENCODE_LITERAL | \
215 ENCODE_HEAP_REF | ENCODE_MUST_NOT_ALIAS)
216
Elliott Hughes719ace42012-03-09 18:06:03 -0800217struct LIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700218 int offset; // Offset of this instruction
219 int dalvikOffset; // Offset of Dalvik opcode
220 LIR* next;
221 LIR* prev;
222 LIR* target;
223 int opcode;
224 int operands[5]; // [0..4] = [dest, src1, src2, extra, extra2]
225 struct {
226 bool isNop:1; // LIR is optimized away
227 bool pcRelFixup:1; // May need pc-relative fixup
Bill Buzbeea114add2012-05-03 15:00:40 -0700228 unsigned int size:5; // in bytes
buzbeef5f5a122012-09-21 13:57:36 -0700229 unsigned int unused:25;
Bill Buzbeea114add2012-05-03 15:00:40 -0700230 } flags;
231 int aliasInfo; // For Dalvik register & litpool disambiguation
232 u8 useMask; // Resource mask for use
233 u8 defMask; // Resource mask for def
Elliott Hughes719ace42012-03-09 18:06:03 -0800234};
buzbee67bf8852011-08-17 17:51:35 -0700235
buzbeeb046e162012-10-30 15:48:42 -0700236/* Shared pseudo opcodes - must be < 0 */
237enum LIRPseudoOpcode {
238 kPseudoExportedPC = -18,
239 kPseudoSafepointPC = -17,
240 kPseudoIntrinsicRetry = -16,
241 kPseudoSuspendTarget = -15,
242 kPseudoThrowTarget = -14,
243 kPseudoCaseLabel = -13,
244 kPseudoMethodEntry = -12,
245 kPseudoMethodExit = -11,
246 kPseudoBarrier = -10,
247 kPseudoExtended = -9,
248 kPseudoSSARep = -8,
249 kPseudoEntryBlock = -7,
250 kPseudoExitBlock = -6,
251 kPseudoTargetLabel = -5,
252 kPseudoDalvikByteCodeBoundary = -4,
253 kPseudoPseudoAlign4 = -3,
254 kPseudoEHBlockLabel = -2,
255 kPseudoNormalBlockLabel = -1,
256};
257
buzbee67bf8852011-08-17 17:51:35 -0700258enum ExtendedMIROpcode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700259 kMirOpFirst = kNumPackedOpcodes,
260 kMirOpPhi = kMirOpFirst,
261 kMirOpCopy,
262 kMirOpFusedCmplFloat,
263 kMirOpFusedCmpgFloat,
264 kMirOpFusedCmplDouble,
265 kMirOpFusedCmpgDouble,
266 kMirOpFusedCmpLong,
267 kMirOpNop,
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700268 kMirOpNullCheck,
269 kMirOpRangeCheck,
270 kMirOpDivZeroCheck,
271 kMirOpCheck,
Bill Buzbeea114add2012-05-03 15:00:40 -0700272 kMirOpLast,
buzbee67bf8852011-08-17 17:51:35 -0700273};
274
275struct SSARepresentation;
276
Elliott Hughes719ace42012-03-09 18:06:03 -0800277enum MIROptimizationFlagPositons {
Bill Buzbeea114add2012-05-03 15:00:40 -0700278 kMIRIgnoreNullCheck = 0,
279 kMIRNullCheckOnly,
280 kMIRIgnoreRangeCheck,
281 kMIRRangeCheckOnly,
282 kMIRInlined, // Invoke is inlined (ie dead)
283 kMIRInlinedPred, // Invoke is inlined via prediction
284 kMIRCallee, // Instruction is inlined from callee
285 kMIRIgnoreSuspendCheck,
286 kMIRDup,
287 kMIRMark, // Temporary node mark
Elliott Hughes719ace42012-03-09 18:06:03 -0800288};
buzbee67bf8852011-08-17 17:51:35 -0700289
290#define MIR_IGNORE_NULL_CHECK (1 << kMIRIgnoreNullCheck)
291#define MIR_NULL_CHECK_ONLY (1 << kMIRNullCheckOnly)
292#define MIR_IGNORE_RANGE_CHECK (1 << kMIRIgnoreRangeCheck)
293#define MIR_RANGE_CHECK_ONLY (1 << kMIRRangeCheckOnly)
294#define MIR_INLINED (1 << kMIRInlined)
295#define MIR_INLINED_PRED (1 << kMIRInlinedPred)
296#define MIR_CALLEE (1 << kMIRCallee)
buzbeec1f45042011-09-21 16:03:19 -0700297#define MIR_IGNORE_SUSPEND_CHECK (1 << kMIRIgnoreSuspendCheck)
buzbeee1965672012-03-11 18:39:19 -0700298#define MIR_DUP (1 << kMIRDup)
buzbee239c4e72012-03-16 08:42:29 -0700299#define MIR_MARK (1 << kMIRMark)
buzbee67bf8852011-08-17 17:51:35 -0700300
buzbeed1643e42012-09-05 14:06:51 -0700301struct Checkstats {
302 int nullChecks;
303 int nullChecksEliminated;
304 int rangeChecks;
305 int rangeChecksEliminated;
306};
307
Elliott Hughes719ace42012-03-09 18:06:03 -0800308struct MIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700309 DecodedInstruction dalvikInsn;
310 unsigned int width;
311 unsigned int offset;
312 MIR* prev;
313 MIR* next;
314 SSARepresentation* ssaRep;
315 int optimizationFlags;
Bill Buzbeea114add2012-05-03 15:00:40 -0700316 union {
Bill Buzbeea114add2012-05-03 15:00:40 -0700317 // Used to quickly locate all Phi opcodes
318 MIR* phiNext;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700319 // Establish link between two halves of throwing instructions
320 MIR* throwInsn;
Bill Buzbeea114add2012-05-03 15:00:40 -0700321 } meta;
Elliott Hughes719ace42012-03-09 18:06:03 -0800322};
buzbee67bf8852011-08-17 17:51:35 -0700323
324struct BasicBlockDataFlow;
325
326/* For successorBlockList */
Elliott Hughes719ace42012-03-09 18:06:03 -0800327enum BlockListType {
Bill Buzbeea114add2012-05-03 15:00:40 -0700328 kNotUsed = 0,
329 kCatch,
330 kPackedSwitch,
331 kSparseSwitch,
Elliott Hughes719ace42012-03-09 18:06:03 -0800332};
buzbee67bf8852011-08-17 17:51:35 -0700333
Elliott Hughes719ace42012-03-09 18:06:03 -0800334struct BasicBlock {
Bill Buzbeea114add2012-05-03 15:00:40 -0700335 int id;
336 int dfsId;
337 bool visited;
338 bool hidden;
339 bool catchEntry;
buzbee0967a252012-09-14 10:43:54 -0700340 bool explicitThrow;
341 bool conditionalBranch;
buzbee2cfc6392012-05-07 14:51:40 -0700342 bool hasReturn;
Bill Buzbeea114add2012-05-03 15:00:40 -0700343 uint16_t startOffset;
344 uint16_t nestingDepth;
Bill Buzbeea114add2012-05-03 15:00:40 -0700345 BBType blockType;
Bill Buzbeea114add2012-05-03 15:00:40 -0700346 MIR* firstMIRInsn;
347 MIR* lastMIRInsn;
348 BasicBlock* fallThrough;
349 BasicBlock* taken;
350 BasicBlock* iDom; // Immediate dominator
351 BasicBlockDataFlow* dataFlowInfo;
352 GrowableList* predecessors;
353 ArenaBitVector* dominators;
354 ArenaBitVector* iDominated; // Set nodes being immediately dominated
355 ArenaBitVector* domFrontier; // Dominance frontier
356 struct { // For one-to-many successors like
357 BlockListType blockListType; // switch and exception handling
358 GrowableList blocks;
359 } successorBlockList;
Elliott Hughes719ace42012-03-09 18:06:03 -0800360};
buzbee67bf8852011-08-17 17:51:35 -0700361
362/*
363 * The "blocks" field in "successorBlockList" points to an array of
364 * elements with the type "SuccessorBlockInfo".
365 * For catch blocks, key is type index for the exception.
366 * For swtich blocks, key is the case value.
367 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800368struct SuccessorBlockInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700369 BasicBlock* block;
370 int key;
Elliott Hughes719ace42012-03-09 18:06:03 -0800371};
buzbee67bf8852011-08-17 17:51:35 -0700372
373struct LoopAnalysis;
374struct RegisterPool;
buzbeeba938cb2012-02-03 14:47:55 -0800375struct ArenaMemBlock;
376struct Memstats;
buzbee67bf8852011-08-17 17:51:35 -0700377
Elliott Hughes719ace42012-03-09 18:06:03 -0800378enum AssemblerStatus {
Bill Buzbeea114add2012-05-03 15:00:40 -0700379 kSuccess,
380 kRetryAll,
Elliott Hughes719ace42012-03-09 18:06:03 -0800381};
buzbee67bf8852011-08-17 17:51:35 -0700382
buzbee5b537102012-01-17 17:33:47 -0800383#define NOTVISITED (-1)
384
Elliott Hughes719ace42012-03-09 18:06:03 -0800385struct CompilationUnit {
Elliott Hughese52e49b2012-04-02 16:05:44 -0700386 CompilationUnit()
Bill Buzbeea114add2012-05-03 15:00:40 -0700387 : numBlocks(0),
388 compiler(NULL),
389 class_linker(NULL),
390 dex_file(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700391 class_loader(NULL),
392 method_idx(0),
393 code_item(NULL),
394 access_flags(0),
Ian Rogers08f753d2012-08-24 14:35:25 -0700395 invoke_type(kDirect),
Bill Buzbeea114add2012-05-03 15:00:40 -0700396 shorty(NULL),
397 firstLIRInsn(NULL),
398 lastLIRInsn(NULL),
399 literalList(NULL),
400 methodLiteralList(NULL),
401 codeLiteralList(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700402 disableOpt(0),
403 enableDebug(0),
Bill Buzbeea114add2012-05-03 15:00:40 -0700404 dataOffset(0),
405 totalSize(0),
406 assemblerStatus(kSuccess),
407 assemblerRetries(0),
Bill Buzbeea114add2012-05-03 15:00:40 -0700408 printMe(false),
Bill Buzbeea114add2012-05-03 15:00:40 -0700409 hasLoop(false),
410 hasInvoke(false),
Bill Buzbeea114add2012-05-03 15:00:40 -0700411 qdMode(false),
Bill Buzbeea114add2012-05-03 15:00:40 -0700412 regPool(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700413 instructionSet(kNone),
414 numSSARegs(0),
415 ssaBaseVRegs(NULL),
416 ssaSubscripts(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700417 ssaStrings(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700418 vRegToSSAMap(NULL),
419 SSALastDefs(NULL),
420 isConstantV(NULL),
421 constantValues(NULL),
422 phiAliasMap(NULL),
423 phiList(NULL),
424 regLocation(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700425 promotionMap(NULL),
426 methodSReg(0),
Bill Buzbeea114add2012-05-03 15:00:40 -0700427 numReachableBlocks(0),
428 numDalvikRegisters(0),
429 entryBlock(NULL),
430 exitBlock(NULL),
431 curBlock(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700432 iDomList(NULL),
433 tryBlockAddr(NULL),
434 defBlockMatrix(NULL),
435 tempBlockV(NULL),
436 tempDalvikRegisterV(NULL),
437 tempSSARegisterV(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700438 tempSSABlockIdV(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700439 blockLabelList(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700440 numIns(0),
441 numOuts(0),
442 numRegs(0),
443 numCoreSpills(0),
444 numFPSpills(0),
445 numCompilerTemps(0),
446 frameSize(0),
447 coreSpillMask(0U),
448 fpSpillMask(0U),
449 attrs(0U),
450 currentDalvikOffset(0),
451 insns(NULL),
452 insnsSize(0U),
453 disableDataflow(false),
454 defCount(0),
455 compilerFlipMatch(false),
456 arenaHead(NULL),
457 currentArena(NULL),
458 numArenaBlocks(0),
459 mstats(NULL),
buzbeed1643e42012-09-05 14:06:51 -0700460 checkstats(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700461 genBitcode(false),
462 context(NULL),
463 module(NULL),
464 func(NULL),
465 intrinsic_helper(NULL),
466 irb(NULL),
467 placeholderBB(NULL),
468 entryBB(NULL),
buzbee4be777b2012-07-12 14:38:18 -0700469 entryTargetBB(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700470 tempName(0),
buzbeeb03f4872012-06-11 15:22:11 -0700471 numShadowFrameEntries(0),
472 shadowMap(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700473#ifndef NDEBUG
474 liveSReg(0),
475#endif
476 opcodeCount(NULL) {}
Elliott Hughese52e49b2012-04-02 16:05:44 -0700477
Bill Buzbeea114add2012-05-03 15:00:40 -0700478 int numBlocks;
479 GrowableList blockList;
480 Compiler* compiler; // Compiler driving this compiler
481 ClassLinker* class_linker; // Linker to resolve fields and methods
482 const DexFile* dex_file; // DexFile containing the method being compiled
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700483 jobject class_loader; // compiling method's class loader
Bill Buzbeea114add2012-05-03 15:00:40 -0700484 uint32_t method_idx; // compiling method's index into method_ids of DexFile
485 const DexFile::CodeItem* code_item; // compiling method's DexFile code_item
486 uint32_t access_flags; // compiling method's access flags
Ian Rogers08f753d2012-08-24 14:35:25 -0700487 InvokeType invoke_type; // compiling method's invocation type
Bill Buzbeea114add2012-05-03 15:00:40 -0700488 const char* shorty; // compiling method's shorty
489 LIR* firstLIRInsn;
490 LIR* lastLIRInsn;
491 LIR* literalList; // Constants
492 LIR* methodLiteralList; // Method literals requiring patching
493 LIR* codeLiteralList; // Code literals requiring patching
Bill Buzbeea114add2012-05-03 15:00:40 -0700494 uint32_t disableOpt; // optControlVector flags
495 uint32_t enableDebug; // debugControlVector flags
Bill Buzbeea114add2012-05-03 15:00:40 -0700496 int dataOffset; // starting offset of literal pool
497 int totalSize; // header + code size
498 AssemblerStatus assemblerStatus; // Success or fix and retry
499 int assemblerRetries;
500 std::vector<uint8_t> codeBuffer;
Bill Buzbeea5b30242012-09-28 07:19:44 -0700501 /*
502 * Holds mapping from native PC to dex PC for safepoints where we may deoptimize.
503 * Native PC is on the return address of the safepointed operation. Dex PC is for
504 * the instruction being executed at the safepoint.
505 */
506 std::vector<uint32_t> pc2dexMappingTable;
507 /*
508 * Holds mapping from Dex PC to native PC for catch entry points. Native PC and Dex PC
509 * immediately preceed the instruction.
510 */
511 std::vector<uint32_t> dex2pcMappingTable;
512 std::vector<uint32_t> combinedMappingTable;
buzbeeca7a5e42012-08-20 11:12:18 -0700513 std::vector<uint32_t> coreVmapTable;
514 std::vector<uint32_t> fpVmapTable;
Ian Rogers0c7abda2012-09-19 13:33:42 -0700515 std::vector<uint8_t> nativeGcMap;
Bill Buzbeea114add2012-05-03 15:00:40 -0700516 bool printMe;
Bill Buzbeea114add2012-05-03 15:00:40 -0700517 bool hasLoop; // Contains a loop
518 bool hasInvoke; // Contains an invoke instruction
Bill Buzbeea114add2012-05-03 15:00:40 -0700519 bool qdMode; // Compile for code size/compile time
Bill Buzbeea114add2012-05-03 15:00:40 -0700520 RegisterPool* regPool;
Bill Buzbeea114add2012-05-03 15:00:40 -0700521 InstructionSet instructionSet;
522 /* Number of total regs used in the whole cUnit after SSA transformation */
523 int numSSARegs;
524 /* Map SSA reg i to the base virtual register/subscript */
525 GrowableList* ssaBaseVRegs;
526 GrowableList* ssaSubscripts;
buzbee2cfc6392012-05-07 14:51:40 -0700527 GrowableList* ssaStrings;
buzbee67bf8852011-08-17 17:51:35 -0700528
Bill Buzbeea114add2012-05-03 15:00:40 -0700529 /* The following are new data structures to support SSA representations */
530 /* Map original Dalvik virtual reg i to the current SSA name */
531 int* vRegToSSAMap; // length == method->registersSize
532 int* SSALastDefs; // length == method->registersSize
533 ArenaBitVector* isConstantV; // length == numSSAReg
534 int* constantValues; // length == numSSAReg
535 int* phiAliasMap; // length == numSSAReg
536 MIR* phiList;
buzbee67bf8852011-08-17 17:51:35 -0700537
Bill Buzbeea114add2012-05-03 15:00:40 -0700538 /* Use counts of ssa names */
539 GrowableList useCounts; // Weighted by nesting depth
540 GrowableList rawUseCounts; // Not weighted
buzbee239c4e72012-03-16 08:42:29 -0700541
Bill Buzbeea114add2012-05-03 15:00:40 -0700542 /* Optimization support */
543 GrowableList loopHeaders;
buzbee239c4e72012-03-16 08:42:29 -0700544
Bill Buzbeea114add2012-05-03 15:00:40 -0700545 /* Map SSA names to location */
546 RegLocation* regLocation;
buzbee67bf8852011-08-17 17:51:35 -0700547
Bill Buzbeea114add2012-05-03 15:00:40 -0700548 /* Keep track of Dalvik vReg to physical register mappings */
549 PromotionMap* promotionMap;
buzbee67bc2362011-10-11 18:08:40 -0700550
Bill Buzbeea114add2012-05-03 15:00:40 -0700551 /* SSA name for Method* */
552 int methodSReg;
buzbeead8f15e2012-06-18 14:49:45 -0700553 RegLocation methodLoc; // Describes location of method*
buzbeee1965672012-03-11 18:39:19 -0700554
Bill Buzbeea114add2012-05-03 15:00:40 -0700555 int numReachableBlocks;
556 int numDalvikRegisters; // method->registersSize
557 BasicBlock* entryBlock;
558 BasicBlock* exitBlock;
559 BasicBlock* curBlock;
Bill Buzbeea114add2012-05-03 15:00:40 -0700560 GrowableList dfsOrder;
561 GrowableList dfsPostOrder;
562 GrowableList domPostOrderTraversal;
563 GrowableList throwLaunchpads;
564 GrowableList suspendLaunchpads;
565 GrowableList intrinsicLaunchpads;
566 GrowableList compilerTemps;
567 int* iDomList;
568 ArenaBitVector* tryBlockAddr;
569 ArenaBitVector** defBlockMatrix; // numDalvikRegister x numBlocks
570 ArenaBitVector* tempBlockV;
571 ArenaBitVector* tempDalvikRegisterV;
572 ArenaBitVector* tempSSARegisterV; // numSSARegs
buzbee2cfc6392012-05-07 14:51:40 -0700573 int* tempSSABlockIdV; // working storage for Phi labels
buzbeea1da8a52012-07-09 14:00:21 -0700574 LIR* blockLabelList;
Bill Buzbeea114add2012-05-03 15:00:40 -0700575 /*
576 * Frame layout details.
577 * NOTE: for debug support it will be necessary to add a structure
578 * to map the Dalvik virtual registers to the promoted registers.
579 * NOTE: "num" fields are in 4-byte words, "Size" and "Offset" in bytes.
580 */
581 int numIns;
582 int numOuts;
583 int numRegs; // Unlike numDalvikRegisters, does not include ins
584 int numCoreSpills;
585 int numFPSpills;
586 int numCompilerTemps;
587 int frameSize;
588 unsigned int coreSpillMask;
589 unsigned int fpSpillMask;
590 unsigned int attrs;
591 /*
592 * CLEANUP/RESTRUCTURE: The code generation utilities don't have a built-in
593 * mechanism to propagate the original Dalvik opcode address to the
594 * associated generated instructions. For the trace compiler, this wasn't
595 * necessary because the interpreter handled all throws and debugging
596 * requests. For now we'll handle this by placing the Dalvik offset
597 * in the CompilationUnit struct before codegen for each instruction.
598 * The low-level LIR creation utilites will pull it from here. Should
599 * be rewritten.
600 */
601 int currentDalvikOffset;
602 GrowableList switchTables;
603 GrowableList fillArrayData;
604 const u2* insns;
605 u4 insnsSize;
606 bool disableDataflow; // Skip dataflow analysis if possible
607 SafeMap<unsigned int, BasicBlock*> blockMap; // findBlock lookup cache
buzbeed1643e42012-09-05 14:06:51 -0700608 SafeMap<unsigned int, unsigned int> blockIdMap; // Block collapse lookup cache
Bill Buzbeea114add2012-05-03 15:00:40 -0700609 SafeMap<unsigned int, LIR*> boundaryMap; // boundary lookup cache
610 int defCount; // Used to estimate number of SSA names
Elliott Hughese52e49b2012-04-02 16:05:44 -0700611
Bill Buzbeea114add2012-05-03 15:00:40 -0700612 // If non-empty, apply optimizer/debug flags only to matching methods.
613 std::string compilerMethodMatch;
614 // Flips sense of compilerMethodMatch - apply flags if doesn't match.
615 bool compilerFlipMatch;
616 ArenaMemBlock* arenaHead;
617 ArenaMemBlock* currentArena;
618 int numArenaBlocks;
619 Memstats* mstats;
buzbeed1643e42012-09-05 14:06:51 -0700620 Checkstats* checkstats;
buzbee2cfc6392012-05-07 14:51:40 -0700621 bool genBitcode;
buzbee4df2bbd2012-10-11 14:46:06 -0700622 LLVMInfo* llvm_info;
buzbee2cfc6392012-05-07 14:51:40 -0700623 llvm::LLVMContext* context;
624 llvm::Module* module;
625 llvm::Function* func;
626 greenland::IntrinsicHelper* intrinsic_helper;
627 greenland::IRBuilder* irb;
628 llvm::BasicBlock* placeholderBB;
629 llvm::BasicBlock* entryBB;
buzbee4be777b2012-07-12 14:38:18 -0700630 llvm::BasicBlock* entryTargetBB;
buzbee2cfc6392012-05-07 14:51:40 -0700631 std::string bitcode_filename;
632 GrowableList llvmValues;
633 int32_t tempName;
634 SafeMap<llvm::BasicBlock*, LIR*> blockToLabelMap; // llvm bb -> LIR label
635 SafeMap<int32_t, llvm::BasicBlock*> idToBlockMap; // block id -> llvm bb
636 SafeMap<llvm::Value*, RegLocation> locMap; // llvm Value to loc rec
buzbeeb03f4872012-06-11 15:22:11 -0700637 int numShadowFrameEntries;
638 int* shadowMap;
buzbee0967a252012-09-14 10:43:54 -0700639 std::set<llvm::BasicBlock*> llvmBlocks;
buzbee3d661942012-03-14 17:37:27 -0700640#ifndef NDEBUG
Bill Buzbeea114add2012-05-03 15:00:40 -0700641 /*
642 * Sanity checking for the register temp tracking. The same ssa
643 * name should never be associated with one temp register per
644 * instruction compilation.
645 */
646 int liveSReg;
buzbee3d661942012-03-14 17:37:27 -0700647#endif
buzbee6459e7c2012-10-02 14:42:41 -0700648 std::set<uint32_t> catches;
buzbee2cfc6392012-05-07 14:51:40 -0700649 int* opcodeCount; // Count Dalvik opcodes for tuning
Elliott Hughes719ace42012-03-09 18:06:03 -0800650};
buzbee67bf8852011-08-17 17:51:35 -0700651
Elliott Hughes719ace42012-03-09 18:06:03 -0800652enum OpSize {
Bill Buzbeea114add2012-05-03 15:00:40 -0700653 kWord,
654 kLong,
655 kSingle,
656 kDouble,
657 kUnsignedHalf,
658 kSignedHalf,
659 kUnsignedByte,
660 kSignedByte,
Elliott Hughes719ace42012-03-09 18:06:03 -0800661};
buzbeee3acd072012-02-25 17:03:10 -0800662
Elliott Hughes719ace42012-03-09 18:06:03 -0800663enum OpKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700664 kOpMov,
665 kOpMvn,
666 kOpCmp,
667 kOpLsl,
668 kOpLsr,
669 kOpAsr,
670 kOpRor,
671 kOpNot,
672 kOpAnd,
673 kOpOr,
674 kOpXor,
675 kOpNeg,
676 kOpAdd,
677 kOpAdc,
678 kOpSub,
679 kOpSbc,
680 kOpRsub,
681 kOpMul,
682 kOpDiv,
683 kOpRem,
684 kOpBic,
685 kOpCmn,
686 kOpTst,
687 kOpBkpt,
688 kOpBlx,
689 kOpPush,
690 kOpPop,
691 kOp2Char,
692 kOp2Short,
693 kOp2Byte,
694 kOpCondBr,
695 kOpUncondBr,
696 kOpBx,
697 kOpInvalid,
Elliott Hughes719ace42012-03-09 18:06:03 -0800698};
buzbee31a4a6f2012-02-28 15:36:15 -0800699
Ian Rogers680b1bd2012-03-07 20:18:49 -0800700std::ostream& operator<<(std::ostream& os, const OpKind& kind);
701
Elliott Hughes719ace42012-03-09 18:06:03 -0800702enum ConditionCode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700703 kCondEq, // equal
704 kCondNe, // not equal
705 kCondCs, // carry set (unsigned less than)
706 kCondUlt = kCondCs,
707 kCondCc, // carry clear (unsigned greater than or same)
708 kCondUge = kCondCc,
709 kCondMi, // minus
710 kCondPl, // plus, positive or zero
711 kCondVs, // overflow
712 kCondVc, // no overflow
713 kCondHi, // unsigned greater than
714 kCondLs, // unsigned lower or same
715 kCondGe, // signed greater than or equal
716 kCondLt, // signed less than
717 kCondGt, // signed greater than
718 kCondLe, // signed less than or equal
719 kCondAl, // always
720 kCondNv, // never
Elliott Hughes719ace42012-03-09 18:06:03 -0800721};
buzbee31a4a6f2012-02-28 15:36:15 -0800722
buzbeeb046e162012-10-30 15:48:42 -0700723// Target specific condition encodings
724enum ArmConditionCode {
725 kArmCondEq = 0x0, /* 0000 */
726 kArmCondNe = 0x1, /* 0001 */
727 kArmCondCs = 0x2, /* 0010 */
728 kArmCondCc = 0x3, /* 0011 */
729 kArmCondMi = 0x4, /* 0100 */
730 kArmCondPl = 0x5, /* 0101 */
731 kArmCondVs = 0x6, /* 0110 */
732 kArmCondVc = 0x7, /* 0111 */
733 kArmCondHi = 0x8, /* 1000 */
734 kArmCondLs = 0x9, /* 1001 */
735 kArmCondGe = 0xa, /* 1010 */
736 kArmCondLt = 0xb, /* 1011 */
737 kArmCondGt = 0xc, /* 1100 */
738 kArmCondLe = 0xd, /* 1101 */
739 kArmCondAl = 0xe, /* 1110 */
740 kArmCondNv = 0xf, /* 1111 */
741};
742
743enum X86ConditionCode {
744 kX86CondO = 0x0, // overflow
745 kX86CondNo = 0x1, // not overflow
746
747 kX86CondB = 0x2, // below
748 kX86CondNae = kX86CondB, // not-above-equal
749 kX86CondC = kX86CondB, // carry
750
751 kX86CondNb = 0x3, // not-below
752 kX86CondAe = kX86CondNb, // above-equal
753 kX86CondNc = kX86CondNb, // not-carry
754
755 kX86CondZ = 0x4, // zero
756 kX86CondEq = kX86CondZ, // equal
757
758 kX86CondNz = 0x5, // not-zero
759 kX86CondNe = kX86CondNz, // not-equal
760
761 kX86CondBe = 0x6, // below-equal
762 kX86CondNa = kX86CondBe, // not-above
763
764 kX86CondNbe = 0x7, // not-below-equal
765 kX86CondA = kX86CondNbe,// above
766
767 kX86CondS = 0x8, // sign
768 kX86CondNs = 0x9, // not-sign
769
770 kX86CondP = 0xA, // 8-bit parity even
771 kX86CondPE = kX86CondP,
772
773 kX86CondNp = 0xB, // 8-bit parity odd
774 kX86CondPo = kX86CondNp,
775
776 kX86CondL = 0xC, // less-than
777 kX86CondNge = kX86CondL, // not-greater-equal
778
779 kX86CondNl = 0xD, // not-less-than
780 kX86CondGe = kX86CondNl, // not-greater-equal
781
782 kX86CondLe = 0xE, // less-than-equal
783 kX86CondNg = kX86CondLe, // not-greater
784
785 kX86CondNle = 0xF, // not-less-than
786 kX86CondG = kX86CondNle,// greater
787};
788
789
Elliott Hughes719ace42012-03-09 18:06:03 -0800790enum ThrowKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700791 kThrowNullPointer,
792 kThrowDivZero,
793 kThrowArrayBounds,
Bill Buzbeea114add2012-05-03 15:00:40 -0700794 kThrowNoSuchMethod,
795 kThrowStackOverflow,
Elliott Hughes719ace42012-03-09 18:06:03 -0800796};
buzbee31a4a6f2012-02-28 15:36:15 -0800797
Elliott Hughes719ace42012-03-09 18:06:03 -0800798struct SwitchTable {
Bill Buzbeea114add2012-05-03 15:00:40 -0700799 int offset;
800 const u2* table; // Original dex table
801 int vaddr; // Dalvik offset of switch opcode
802 LIR* anchor; // Reference instruction for relative offsets
803 LIR** targets; // Array of case targets
Elliott Hughes719ace42012-03-09 18:06:03 -0800804};
buzbee5de34942012-03-01 14:51:57 -0800805
Elliott Hughes719ace42012-03-09 18:06:03 -0800806struct FillArrayData {
Bill Buzbeea114add2012-05-03 15:00:40 -0700807 int offset;
808 const u2* table; // Original dex table
809 int size;
810 int vaddr; // Dalvik offset of FILL_ARRAY_DATA opcode
Elliott Hughes719ace42012-03-09 18:06:03 -0800811};
buzbee5de34942012-03-01 14:51:57 -0800812
buzbee16da88c2012-03-20 10:38:17 -0700813#define MAX_PATTERN_LEN 5
814
815enum SpecialCaseHandler {
Bill Buzbeea114add2012-05-03 15:00:40 -0700816 kNoHandler,
817 kNullMethod,
818 kConstFunction,
819 kIGet,
820 kIGetBoolean,
821 kIGetObject,
822 kIGetByte,
823 kIGetChar,
824 kIGetShort,
825 kIGetWide,
826 kIPut,
827 kIPutBoolean,
828 kIPutObject,
829 kIPutByte,
830 kIPutChar,
831 kIPutShort,
832 kIPutWide,
833 kIdentity,
buzbee16da88c2012-03-20 10:38:17 -0700834};
835
836struct CodePattern {
Bill Buzbeea114add2012-05-03 15:00:40 -0700837 const Instruction::Code opcodes[MAX_PATTERN_LEN];
838 const SpecialCaseHandler handlerCode;
buzbee16da88c2012-03-20 10:38:17 -0700839};
840
841static const CodePattern specialPatterns[] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700842 {{Instruction::RETURN_VOID}, kNullMethod},
843 {{Instruction::CONST, Instruction::RETURN}, kConstFunction},
844 {{Instruction::CONST_4, Instruction::RETURN}, kConstFunction},
845 {{Instruction::CONST_4, Instruction::RETURN_OBJECT}, kConstFunction},
846 {{Instruction::CONST_16, Instruction::RETURN}, kConstFunction},
847 {{Instruction::IGET, Instruction:: RETURN}, kIGet},
848 {{Instruction::IGET_BOOLEAN, Instruction::RETURN}, kIGetBoolean},
849 {{Instruction::IGET_OBJECT, Instruction::RETURN_OBJECT}, kIGetObject},
850 {{Instruction::IGET_BYTE, Instruction::RETURN}, kIGetByte},
851 {{Instruction::IGET_CHAR, Instruction::RETURN}, kIGetChar},
852 {{Instruction::IGET_SHORT, Instruction::RETURN}, kIGetShort},
853 {{Instruction::IGET_WIDE, Instruction::RETURN_WIDE}, kIGetWide},
854 {{Instruction::IPUT, Instruction::RETURN_VOID}, kIPut},
855 {{Instruction::IPUT_BOOLEAN, Instruction::RETURN_VOID}, kIPutBoolean},
856 {{Instruction::IPUT_OBJECT, Instruction::RETURN_VOID}, kIPutObject},
857 {{Instruction::IPUT_BYTE, Instruction::RETURN_VOID}, kIPutByte},
858 {{Instruction::IPUT_CHAR, Instruction::RETURN_VOID}, kIPutChar},
859 {{Instruction::IPUT_SHORT, Instruction::RETURN_VOID}, kIPutShort},
860 {{Instruction::IPUT_WIDE, Instruction::RETURN_VOID}, kIPutWide},
861 {{Instruction::RETURN}, kIdentity},
862 {{Instruction::RETURN_OBJECT}, kIdentity},
863 {{Instruction::RETURN_WIDE}, kIdentity},
buzbee16da88c2012-03-20 10:38:17 -0700864};
buzbee5de34942012-03-01 14:51:57 -0800865
buzbee5abfa3e2012-01-31 17:01:43 -0800866BasicBlock* oatNewBB(CompilationUnit* cUnit, BBType blockType, int blockId);
buzbee67bf8852011-08-17 17:51:35 -0700867
868void oatAppendMIR(BasicBlock* bb, MIR* mir);
869
870void oatPrependMIR(BasicBlock* bb, MIR* mir);
871
872void oatInsertMIRAfter(BasicBlock* bb, MIR* currentMIR, MIR* newMIR);
873
874void oatAppendLIR(CompilationUnit* cUnit, LIR* lir);
875
876void oatInsertLIRBefore(LIR* currentLIR, LIR* newLIR);
877
878void oatInsertLIRAfter(LIR* currentLIR, LIR* newLIR);
879
buzbee15bf9802012-06-12 17:49:27 -0700880MIR* oatFindMoveResult(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir);
buzbee67bf8852011-08-17 17:51:35 -0700881/* Debug Utilities */
882void oatDumpCompilationUnit(CompilationUnit* cUnit);
883
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800884} // namespace art
885
buzbee67bf8852011-08-17 17:51:35 -0700886#endif // ART_SRC_COMPILER_COMPILER_IR_H_