blob: 3f855bbf8beb28f75b99189e90cf49ba134f96c7 [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#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
Elliott Hughes719ace42012-03-09 18:06:03 -080047enum RegLocationType {
Bill Buzbeea114add2012-05-03 15:00:40 -070048 kLocDalvikFrame = 0, // Normal Dalvik register
49 kLocPhysReg,
50 kLocCompilerTemp,
51 kLocInvalid
Elliott Hughes719ace42012-03-09 18:06:03 -080052};
buzbee67bf8852011-08-17 17:51:35 -070053
Elliott Hughes719ace42012-03-09 18:06:03 -080054struct PromotionMap {
Bill Buzbeea114add2012-05-03 15:00:40 -070055 RegLocationType coreLocation:3;
56 u1 coreReg;
57 RegLocationType fpLocation:3;
58 u1 fpReg;
59 bool firstInPair;
Elliott Hughes719ace42012-03-09 18:06:03 -080060};
buzbee67bc2362011-10-11 18:08:40 -070061
Elliott Hughes719ace42012-03-09 18:06:03 -080062struct RegLocation {
Bill Buzbeea114add2012-05-03 15:00:40 -070063 RegLocationType location:3;
64 unsigned wide:1;
65 unsigned defined:1; // Do we know the type?
buzbee2cfc6392012-05-07 14:51:40 -070066 unsigned isConst:1; // Constant, value in cUnit->constantValues[]
Bill Buzbeea114add2012-05-03 15:00:40 -070067 unsigned fp:1; // Floating point?
68 unsigned core:1; // Non-floating point?
buzbeebff24652012-05-06 16:22:05 -070069 unsigned ref:1; // Something GC cares about
Bill Buzbeea114add2012-05-03 15:00:40 -070070 unsigned highWord:1; // High word of pair?
71 unsigned home:1; // Does this represent the home location?
72 u1 lowReg; // First physical register
73 u1 highReg; // 2nd physical register (if wide)
74 int32_t sRegLow; // SSA name for low Dalvik word
buzbee2cfc6392012-05-07 14:51:40 -070075 int32_t origSReg; // TODO: remove after Bitcode gen complete
76 // and consolodate usage w/ sRegLow
buzbeee1965672012-03-11 18:39:19 -070077};
78
79struct CompilerTemp {
Bill Buzbeea114add2012-05-03 15:00:40 -070080 int sReg;
81 ArenaBitVector* bv;
Elliott Hughes719ace42012-03-09 18:06:03 -080082};
buzbee67bf8852011-08-17 17:51:35 -070083
buzbee3b3dbdd2012-06-13 13:39:34 -070084struct CallInfo {
buzbee15bf9802012-06-12 17:49:27 -070085 int numArgWords; // Note: word count, not arg count
86 RegLocation* args; // One for each word of arguments
87 RegLocation result; // Eventual target of MOVE_RESULT
88 int optFlags;
89 InvokeType type;
90 uint32_t dexIdx;
buzbee3b3dbdd2012-06-13 13:39:34 -070091 uint32_t index; // Method idx for invokes, type idx for FilledNewArray
buzbee15bf9802012-06-12 17:49:27 -070092 uintptr_t directCode;
93 uintptr_t directMethod;
94 RegLocation target; // Target of following move_result
95 bool skipThis;
96 bool isRange;
97 int offset; // Dalvik offset
98};
99
buzbeee3acd072012-02-25 17:03:10 -0800100 /*
101 * Data structure tracking the mapping between a Dalvik register (pair) and a
102 * native register (pair). The idea is to reuse the previously loaded value
103 * if possible, otherwise to keep the value in a native register as long as
104 * possible.
105 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800106struct RegisterInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700107 int reg; // Reg number
108 bool inUse; // Has it been allocated?
109 bool isTemp; // Can allocate as temp?
110 bool pair; // Part of a register pair?
111 int partner; // If pair, other reg of pair
112 bool live; // Is there an associated SSA name?
113 bool dirty; // If live, is it dirty?
114 int sReg; // Name of live value
115 LIR *defStart; // Starting inst in last def sequence
116 LIR *defEnd; // Ending inst in last def sequence
Elliott Hughes719ace42012-03-09 18:06:03 -0800117};
buzbeee3acd072012-02-25 17:03:10 -0800118
Elliott Hughes719ace42012-03-09 18:06:03 -0800119struct RegisterPool {
Bill Buzbeea114add2012-05-03 15:00:40 -0700120 int numCoreRegs;
121 RegisterInfo *coreRegs;
122 int nextCoreReg;
123 int numFPRegs;
124 RegisterInfo *FPRegs;
125 int nextFPReg;
Elliott Hughes719ace42012-03-09 18:06:03 -0800126};
buzbeee3acd072012-02-25 17:03:10 -0800127
buzbee67bf8852011-08-17 17:51:35 -0700128#define INVALID_SREG (-1)
buzbee3ddc0d12011-10-05 10:36:21 -0700129#define INVALID_VREG (0xFFFFU)
buzbee67bc2362011-10-11 18:08:40 -0700130#define INVALID_REG (0xFF)
buzbeeb046e162012-10-30 15:48:42 -0700131#define INVALID_OFFSET (0xDEADF00FU)
buzbee67bf8852011-08-17 17:51:35 -0700132
buzbeee1965672012-03-11 18:39:19 -0700133/* SSA encodings for special registers */
buzbee9c044ce2012-03-18 13:24:07 -0700134#define SSA_METHOD_BASEREG (-2)
buzbeee1965672012-03-11 18:39:19 -0700135/* First compiler temp basereg, grows smaller */
buzbee9c044ce2012-03-18 13:24:07 -0700136#define SSA_CTEMP_BASEREG (SSA_METHOD_BASEREG - 1)
buzbeee1965672012-03-11 18:39:19 -0700137
buzbee99ba9642012-01-25 14:23:14 -0800138/*
139 * Some code patterns cause the generation of excessively large
140 * methods - in particular initialization sequences. There isn't much
141 * benefit in optimizing these methods, and the cost can be very high.
142 * We attempt to identify these cases, and avoid performing most dataflow
143 * analysis. Two thresholds are used - one for known initializers and one
buzbee5abfa3e2012-01-31 17:01:43 -0800144 * for everything else.
buzbee99ba9642012-01-25 14:23:14 -0800145 */
buzbee5abfa3e2012-01-31 17:01:43 -0800146#define MANY_BLOCKS_INITIALIZER 1000 /* Threshold for switching dataflow off */
147#define MANY_BLOCKS 4000 /* Non-initializer threshold */
buzbee99ba9642012-01-25 14:23:14 -0800148
Elliott Hughes719ace42012-03-09 18:06:03 -0800149enum BBType {
Bill Buzbeea114add2012-05-03 15:00:40 -0700150 kEntryBlock,
151 kDalvikByteCode,
152 kExitBlock,
153 kExceptionHandling,
buzbeed1643e42012-09-05 14:06:51 -0700154 kDead,
Elliott Hughes719ace42012-03-09 18:06:03 -0800155};
buzbee67bf8852011-08-17 17:51:35 -0700156
buzbee31a4a6f2012-02-28 15:36:15 -0800157/* Utility macros to traverse the LIR list */
158#define NEXT_LIR(lir) (lir->next)
159#define PREV_LIR(lir) (lir->prev)
160
buzbee07131ca2012-11-07 16:13:14 -0800161/* Defines for aliasInfo (tracks Dalvik register references) */
162#define DECODE_ALIAS_INFO_REG(X) (X & 0xffff)
163#define DECODE_ALIAS_INFO_WIDE_FLAG (0x80000000)
164#define DECODE_ALIAS_INFO_WIDE(X) ((X & DECODE_ALIAS_INFO_WIDE_FLAG) ? 1 : 0)
165#define ENCODE_ALIAS_INFO(REG, ISWIDE) (REG | (ISWIDE ? DECODE_ALIAS_INFO_WIDE_FLAG : 0))
166
167/*
168 * Def/Use encoding in 64-bit useMask/defMask. Low positions used for target-specific
169 * registers (and typically use the register number as the position). High positions
170 * reserved for common and abstract resources.
171 */
172
173enum ResourceEncodingPos {
174 kMustNotAlias = 63,
175 kHeapRef = 62, // Default memory reference type
176 kLiteral = 61, // Literal pool memory reference
177 kDalvikReg = 60, // Dalvik vReg memory reference
178 kFPStatus = 59,
179 kCCode = 58,
180 kLowestCommonResource = kCCode
181};
182
183/* Common resource macros */
184#define ENCODE_CCODE (1ULL << kCCode)
185#define ENCODE_FP_STATUS (1ULL << kFPStatus)
186
187/* Abstract memory locations */
188#define ENCODE_DALVIK_REG (1ULL << kDalvikReg)
189#define ENCODE_LITERAL (1ULL << kLiteral)
190#define ENCODE_HEAP_REF (1ULL << kHeapRef)
191#define ENCODE_MUST_NOT_ALIAS (1ULL << kMustNotAlias)
192
193#define ENCODE_ALL (~0ULL)
194#define ENCODE_MEM (ENCODE_DALVIK_REG | ENCODE_LITERAL | \
195 ENCODE_HEAP_REF | ENCODE_MUST_NOT_ALIAS)
196
Elliott Hughes719ace42012-03-09 18:06:03 -0800197struct LIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700198 int offset; // Offset of this instruction
199 int dalvikOffset; // Offset of Dalvik opcode
200 LIR* next;
201 LIR* prev;
202 LIR* target;
203 int opcode;
204 int operands[5]; // [0..4] = [dest, src1, src2, extra, extra2]
205 struct {
206 bool isNop:1; // LIR is optimized away
207 bool pcRelFixup:1; // May need pc-relative fixup
Bill Buzbeea114add2012-05-03 15:00:40 -0700208 unsigned int size:5; // in bytes
buzbeef5f5a122012-09-21 13:57:36 -0700209 unsigned int unused:25;
Bill Buzbeea114add2012-05-03 15:00:40 -0700210 } flags;
211 int aliasInfo; // For Dalvik register & litpool disambiguation
212 u8 useMask; // Resource mask for use
213 u8 defMask; // Resource mask for def
Elliott Hughes719ace42012-03-09 18:06:03 -0800214};
buzbee67bf8852011-08-17 17:51:35 -0700215
buzbeeb046e162012-10-30 15:48:42 -0700216/* Shared pseudo opcodes - must be < 0 */
217enum LIRPseudoOpcode {
218 kPseudoExportedPC = -18,
219 kPseudoSafepointPC = -17,
220 kPseudoIntrinsicRetry = -16,
221 kPseudoSuspendTarget = -15,
222 kPseudoThrowTarget = -14,
223 kPseudoCaseLabel = -13,
224 kPseudoMethodEntry = -12,
225 kPseudoMethodExit = -11,
226 kPseudoBarrier = -10,
227 kPseudoExtended = -9,
228 kPseudoSSARep = -8,
229 kPseudoEntryBlock = -7,
230 kPseudoExitBlock = -6,
231 kPseudoTargetLabel = -5,
232 kPseudoDalvikByteCodeBoundary = -4,
233 kPseudoPseudoAlign4 = -3,
234 kPseudoEHBlockLabel = -2,
235 kPseudoNormalBlockLabel = -1,
236};
237
buzbee67bf8852011-08-17 17:51:35 -0700238enum ExtendedMIROpcode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700239 kMirOpFirst = kNumPackedOpcodes,
240 kMirOpPhi = kMirOpFirst,
241 kMirOpCopy,
242 kMirOpFusedCmplFloat,
243 kMirOpFusedCmpgFloat,
244 kMirOpFusedCmplDouble,
245 kMirOpFusedCmpgDouble,
246 kMirOpFusedCmpLong,
247 kMirOpNop,
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700248 kMirOpNullCheck,
249 kMirOpRangeCheck,
250 kMirOpDivZeroCheck,
251 kMirOpCheck,
Bill Buzbeea114add2012-05-03 15:00:40 -0700252 kMirOpLast,
buzbee67bf8852011-08-17 17:51:35 -0700253};
254
255struct SSARepresentation;
256
Elliott Hughes719ace42012-03-09 18:06:03 -0800257enum MIROptimizationFlagPositons {
Bill Buzbeea114add2012-05-03 15:00:40 -0700258 kMIRIgnoreNullCheck = 0,
259 kMIRNullCheckOnly,
260 kMIRIgnoreRangeCheck,
261 kMIRRangeCheckOnly,
262 kMIRInlined, // Invoke is inlined (ie dead)
263 kMIRInlinedPred, // Invoke is inlined via prediction
264 kMIRCallee, // Instruction is inlined from callee
265 kMIRIgnoreSuspendCheck,
266 kMIRDup,
267 kMIRMark, // Temporary node mark
Elliott Hughes719ace42012-03-09 18:06:03 -0800268};
buzbee67bf8852011-08-17 17:51:35 -0700269
270#define MIR_IGNORE_NULL_CHECK (1 << kMIRIgnoreNullCheck)
271#define MIR_NULL_CHECK_ONLY (1 << kMIRNullCheckOnly)
272#define MIR_IGNORE_RANGE_CHECK (1 << kMIRIgnoreRangeCheck)
273#define MIR_RANGE_CHECK_ONLY (1 << kMIRRangeCheckOnly)
274#define MIR_INLINED (1 << kMIRInlined)
275#define MIR_INLINED_PRED (1 << kMIRInlinedPred)
276#define MIR_CALLEE (1 << kMIRCallee)
buzbeec1f45042011-09-21 16:03:19 -0700277#define MIR_IGNORE_SUSPEND_CHECK (1 << kMIRIgnoreSuspendCheck)
buzbeee1965672012-03-11 18:39:19 -0700278#define MIR_DUP (1 << kMIRDup)
buzbee239c4e72012-03-16 08:42:29 -0700279#define MIR_MARK (1 << kMIRMark)
buzbee67bf8852011-08-17 17:51:35 -0700280
buzbeed1643e42012-09-05 14:06:51 -0700281struct Checkstats {
282 int nullChecks;
283 int nullChecksEliminated;
284 int rangeChecks;
285 int rangeChecksEliminated;
286};
287
Elliott Hughes719ace42012-03-09 18:06:03 -0800288struct MIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700289 DecodedInstruction dalvikInsn;
290 unsigned int width;
291 unsigned int offset;
292 MIR* prev;
293 MIR* next;
294 SSARepresentation* ssaRep;
295 int optimizationFlags;
Bill Buzbeea114add2012-05-03 15:00:40 -0700296 union {
Bill Buzbeea114add2012-05-03 15:00:40 -0700297 // Used to quickly locate all Phi opcodes
298 MIR* phiNext;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700299 // Establish link between two halves of throwing instructions
300 MIR* throwInsn;
Bill Buzbeea114add2012-05-03 15:00:40 -0700301 } meta;
Elliott Hughes719ace42012-03-09 18:06:03 -0800302};
buzbee67bf8852011-08-17 17:51:35 -0700303
304struct BasicBlockDataFlow;
305
306/* For successorBlockList */
Elliott Hughes719ace42012-03-09 18:06:03 -0800307enum BlockListType {
Bill Buzbeea114add2012-05-03 15:00:40 -0700308 kNotUsed = 0,
309 kCatch,
310 kPackedSwitch,
311 kSparseSwitch,
Elliott Hughes719ace42012-03-09 18:06:03 -0800312};
buzbee67bf8852011-08-17 17:51:35 -0700313
Elliott Hughes719ace42012-03-09 18:06:03 -0800314struct BasicBlock {
Bill Buzbeea114add2012-05-03 15:00:40 -0700315 int id;
316 int dfsId;
317 bool visited;
318 bool hidden;
319 bool catchEntry;
buzbee0967a252012-09-14 10:43:54 -0700320 bool explicitThrow;
321 bool conditionalBranch;
buzbee2cfc6392012-05-07 14:51:40 -0700322 bool hasReturn;
Bill Buzbeea114add2012-05-03 15:00:40 -0700323 uint16_t startOffset;
324 uint16_t nestingDepth;
Bill Buzbeea114add2012-05-03 15:00:40 -0700325 BBType blockType;
Bill Buzbeea114add2012-05-03 15:00:40 -0700326 MIR* firstMIRInsn;
327 MIR* lastMIRInsn;
328 BasicBlock* fallThrough;
329 BasicBlock* taken;
330 BasicBlock* iDom; // Immediate dominator
331 BasicBlockDataFlow* dataFlowInfo;
332 GrowableList* predecessors;
333 ArenaBitVector* dominators;
334 ArenaBitVector* iDominated; // Set nodes being immediately dominated
335 ArenaBitVector* domFrontier; // Dominance frontier
336 struct { // For one-to-many successors like
337 BlockListType blockListType; // switch and exception handling
338 GrowableList blocks;
339 } successorBlockList;
Elliott Hughes719ace42012-03-09 18:06:03 -0800340};
buzbee67bf8852011-08-17 17:51:35 -0700341
342/*
343 * The "blocks" field in "successorBlockList" points to an array of
344 * elements with the type "SuccessorBlockInfo".
345 * For catch blocks, key is type index for the exception.
346 * For swtich blocks, key is the case value.
347 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800348struct SuccessorBlockInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700349 BasicBlock* block;
350 int key;
Elliott Hughes719ace42012-03-09 18:06:03 -0800351};
buzbee67bf8852011-08-17 17:51:35 -0700352
353struct LoopAnalysis;
354struct RegisterPool;
buzbeeba938cb2012-02-03 14:47:55 -0800355struct ArenaMemBlock;
356struct Memstats;
buzbee67bf8852011-08-17 17:51:35 -0700357
Elliott Hughes719ace42012-03-09 18:06:03 -0800358enum AssemblerStatus {
Bill Buzbeea114add2012-05-03 15:00:40 -0700359 kSuccess,
360 kRetryAll,
Elliott Hughes719ace42012-03-09 18:06:03 -0800361};
buzbee67bf8852011-08-17 17:51:35 -0700362
buzbee5b537102012-01-17 17:33:47 -0800363#define NOTVISITED (-1)
364
Elliott Hughes719ace42012-03-09 18:06:03 -0800365struct CompilationUnit {
Elliott Hughese52e49b2012-04-02 16:05:44 -0700366 CompilationUnit()
Bill Buzbeea114add2012-05-03 15:00:40 -0700367 : numBlocks(0),
368 compiler(NULL),
369 class_linker(NULL),
370 dex_file(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700371 class_loader(NULL),
372 method_idx(0),
373 code_item(NULL),
374 access_flags(0),
Ian Rogers08f753d2012-08-24 14:35:25 -0700375 invoke_type(kDirect),
Bill Buzbeea114add2012-05-03 15:00:40 -0700376 shorty(NULL),
377 firstLIRInsn(NULL),
378 lastLIRInsn(NULL),
379 literalList(NULL),
380 methodLiteralList(NULL),
381 codeLiteralList(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700382 disableOpt(0),
383 enableDebug(0),
Bill Buzbeea114add2012-05-03 15:00:40 -0700384 dataOffset(0),
385 totalSize(0),
386 assemblerStatus(kSuccess),
387 assemblerRetries(0),
Bill Buzbeea114add2012-05-03 15:00:40 -0700388 printMe(false),
Bill Buzbeea114add2012-05-03 15:00:40 -0700389 hasLoop(false),
390 hasInvoke(false),
Bill Buzbeea114add2012-05-03 15:00:40 -0700391 qdMode(false),
Bill Buzbeea114add2012-05-03 15:00:40 -0700392 regPool(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700393 instructionSet(kNone),
394 numSSARegs(0),
395 ssaBaseVRegs(NULL),
396 ssaSubscripts(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700397 ssaStrings(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700398 vRegToSSAMap(NULL),
399 SSALastDefs(NULL),
400 isConstantV(NULL),
401 constantValues(NULL),
402 phiAliasMap(NULL),
403 phiList(NULL),
404 regLocation(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700405 promotionMap(NULL),
406 methodSReg(0),
Bill Buzbeea114add2012-05-03 15:00:40 -0700407 numReachableBlocks(0),
408 numDalvikRegisters(0),
409 entryBlock(NULL),
410 exitBlock(NULL),
411 curBlock(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700412 iDomList(NULL),
413 tryBlockAddr(NULL),
414 defBlockMatrix(NULL),
415 tempBlockV(NULL),
416 tempDalvikRegisterV(NULL),
417 tempSSARegisterV(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700418 tempSSABlockIdV(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700419 blockLabelList(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700420 numIns(0),
421 numOuts(0),
422 numRegs(0),
423 numCoreSpills(0),
424 numFPSpills(0),
425 numCompilerTemps(0),
426 frameSize(0),
427 coreSpillMask(0U),
428 fpSpillMask(0U),
429 attrs(0U),
430 currentDalvikOffset(0),
431 insns(NULL),
432 insnsSize(0U),
433 disableDataflow(false),
434 defCount(0),
435 compilerFlipMatch(false),
436 arenaHead(NULL),
437 currentArena(NULL),
438 numArenaBlocks(0),
439 mstats(NULL),
buzbeed1643e42012-09-05 14:06:51 -0700440 checkstats(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700441 genBitcode(false),
442 context(NULL),
443 module(NULL),
444 func(NULL),
445 intrinsic_helper(NULL),
446 irb(NULL),
447 placeholderBB(NULL),
448 entryBB(NULL),
buzbee4be777b2012-07-12 14:38:18 -0700449 entryTargetBB(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700450 tempName(0),
buzbeeb03f4872012-06-11 15:22:11 -0700451 numShadowFrameEntries(0),
452 shadowMap(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700453#ifndef NDEBUG
454 liveSReg(0),
455#endif
456 opcodeCount(NULL) {}
Elliott Hughese52e49b2012-04-02 16:05:44 -0700457
Bill Buzbeea114add2012-05-03 15:00:40 -0700458 int numBlocks;
459 GrowableList blockList;
460 Compiler* compiler; // Compiler driving this compiler
461 ClassLinker* class_linker; // Linker to resolve fields and methods
462 const DexFile* dex_file; // DexFile containing the method being compiled
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700463 jobject class_loader; // compiling method's class loader
Bill Buzbeea114add2012-05-03 15:00:40 -0700464 uint32_t method_idx; // compiling method's index into method_ids of DexFile
465 const DexFile::CodeItem* code_item; // compiling method's DexFile code_item
466 uint32_t access_flags; // compiling method's access flags
Ian Rogers08f753d2012-08-24 14:35:25 -0700467 InvokeType invoke_type; // compiling method's invocation type
Bill Buzbeea114add2012-05-03 15:00:40 -0700468 const char* shorty; // compiling method's shorty
469 LIR* firstLIRInsn;
470 LIR* lastLIRInsn;
471 LIR* literalList; // Constants
472 LIR* methodLiteralList; // Method literals requiring patching
473 LIR* codeLiteralList; // Code literals requiring patching
Bill Buzbeea114add2012-05-03 15:00:40 -0700474 uint32_t disableOpt; // optControlVector flags
475 uint32_t enableDebug; // debugControlVector flags
Bill Buzbeea114add2012-05-03 15:00:40 -0700476 int dataOffset; // starting offset of literal pool
477 int totalSize; // header + code size
478 AssemblerStatus assemblerStatus; // Success or fix and retry
479 int assemblerRetries;
480 std::vector<uint8_t> codeBuffer;
Bill Buzbeea5b30242012-09-28 07:19:44 -0700481 /*
482 * Holds mapping from native PC to dex PC for safepoints where we may deoptimize.
483 * Native PC is on the return address of the safepointed operation. Dex PC is for
484 * the instruction being executed at the safepoint.
485 */
486 std::vector<uint32_t> pc2dexMappingTable;
487 /*
488 * Holds mapping from Dex PC to native PC for catch entry points. Native PC and Dex PC
489 * immediately preceed the instruction.
490 */
491 std::vector<uint32_t> dex2pcMappingTable;
492 std::vector<uint32_t> combinedMappingTable;
buzbeeca7a5e42012-08-20 11:12:18 -0700493 std::vector<uint32_t> coreVmapTable;
494 std::vector<uint32_t> fpVmapTable;
Ian Rogers0c7abda2012-09-19 13:33:42 -0700495 std::vector<uint8_t> nativeGcMap;
Bill Buzbeea114add2012-05-03 15:00:40 -0700496 bool printMe;
Bill Buzbeea114add2012-05-03 15:00:40 -0700497 bool hasLoop; // Contains a loop
498 bool hasInvoke; // Contains an invoke instruction
Bill Buzbeea114add2012-05-03 15:00:40 -0700499 bool qdMode; // Compile for code size/compile time
Bill Buzbeea114add2012-05-03 15:00:40 -0700500 RegisterPool* regPool;
Bill Buzbeea114add2012-05-03 15:00:40 -0700501 InstructionSet instructionSet;
502 /* Number of total regs used in the whole cUnit after SSA transformation */
503 int numSSARegs;
504 /* Map SSA reg i to the base virtual register/subscript */
505 GrowableList* ssaBaseVRegs;
506 GrowableList* ssaSubscripts;
buzbee2cfc6392012-05-07 14:51:40 -0700507 GrowableList* ssaStrings;
buzbee67bf8852011-08-17 17:51:35 -0700508
Bill Buzbeea114add2012-05-03 15:00:40 -0700509 /* The following are new data structures to support SSA representations */
510 /* Map original Dalvik virtual reg i to the current SSA name */
511 int* vRegToSSAMap; // length == method->registersSize
512 int* SSALastDefs; // length == method->registersSize
513 ArenaBitVector* isConstantV; // length == numSSAReg
514 int* constantValues; // length == numSSAReg
515 int* phiAliasMap; // length == numSSAReg
516 MIR* phiList;
buzbee67bf8852011-08-17 17:51:35 -0700517
Bill Buzbeea114add2012-05-03 15:00:40 -0700518 /* Use counts of ssa names */
519 GrowableList useCounts; // Weighted by nesting depth
520 GrowableList rawUseCounts; // Not weighted
buzbee239c4e72012-03-16 08:42:29 -0700521
Bill Buzbeea114add2012-05-03 15:00:40 -0700522 /* Optimization support */
523 GrowableList loopHeaders;
buzbee239c4e72012-03-16 08:42:29 -0700524
Bill Buzbeea114add2012-05-03 15:00:40 -0700525 /* Map SSA names to location */
526 RegLocation* regLocation;
buzbee67bf8852011-08-17 17:51:35 -0700527
Bill Buzbeea114add2012-05-03 15:00:40 -0700528 /* Keep track of Dalvik vReg to physical register mappings */
529 PromotionMap* promotionMap;
buzbee67bc2362011-10-11 18:08:40 -0700530
Bill Buzbeea114add2012-05-03 15:00:40 -0700531 /* SSA name for Method* */
532 int methodSReg;
buzbeead8f15e2012-06-18 14:49:45 -0700533 RegLocation methodLoc; // Describes location of method*
buzbeee1965672012-03-11 18:39:19 -0700534
Bill Buzbeea114add2012-05-03 15:00:40 -0700535 int numReachableBlocks;
536 int numDalvikRegisters; // method->registersSize
537 BasicBlock* entryBlock;
538 BasicBlock* exitBlock;
539 BasicBlock* curBlock;
Bill Buzbeea114add2012-05-03 15:00:40 -0700540 GrowableList dfsOrder;
541 GrowableList dfsPostOrder;
542 GrowableList domPostOrderTraversal;
543 GrowableList throwLaunchpads;
544 GrowableList suspendLaunchpads;
545 GrowableList intrinsicLaunchpads;
546 GrowableList compilerTemps;
547 int* iDomList;
548 ArenaBitVector* tryBlockAddr;
549 ArenaBitVector** defBlockMatrix; // numDalvikRegister x numBlocks
550 ArenaBitVector* tempBlockV;
551 ArenaBitVector* tempDalvikRegisterV;
552 ArenaBitVector* tempSSARegisterV; // numSSARegs
buzbee2cfc6392012-05-07 14:51:40 -0700553 int* tempSSABlockIdV; // working storage for Phi labels
buzbeea1da8a52012-07-09 14:00:21 -0700554 LIR* blockLabelList;
Bill Buzbeea114add2012-05-03 15:00:40 -0700555 /*
556 * Frame layout details.
557 * NOTE: for debug support it will be necessary to add a structure
558 * to map the Dalvik virtual registers to the promoted registers.
559 * NOTE: "num" fields are in 4-byte words, "Size" and "Offset" in bytes.
560 */
561 int numIns;
562 int numOuts;
563 int numRegs; // Unlike numDalvikRegisters, does not include ins
564 int numCoreSpills;
565 int numFPSpills;
566 int numCompilerTemps;
567 int frameSize;
568 unsigned int coreSpillMask;
569 unsigned int fpSpillMask;
570 unsigned int attrs;
571 /*
572 * CLEANUP/RESTRUCTURE: The code generation utilities don't have a built-in
573 * mechanism to propagate the original Dalvik opcode address to the
574 * associated generated instructions. For the trace compiler, this wasn't
575 * necessary because the interpreter handled all throws and debugging
576 * requests. For now we'll handle this by placing the Dalvik offset
577 * in the CompilationUnit struct before codegen for each instruction.
578 * The low-level LIR creation utilites will pull it from here. Should
579 * be rewritten.
580 */
581 int currentDalvikOffset;
582 GrowableList switchTables;
583 GrowableList fillArrayData;
584 const u2* insns;
585 u4 insnsSize;
586 bool disableDataflow; // Skip dataflow analysis if possible
587 SafeMap<unsigned int, BasicBlock*> blockMap; // findBlock lookup cache
buzbeed1643e42012-09-05 14:06:51 -0700588 SafeMap<unsigned int, unsigned int> blockIdMap; // Block collapse lookup cache
Bill Buzbeea114add2012-05-03 15:00:40 -0700589 SafeMap<unsigned int, LIR*> boundaryMap; // boundary lookup cache
590 int defCount; // Used to estimate number of SSA names
Elliott Hughese52e49b2012-04-02 16:05:44 -0700591
Bill Buzbeea114add2012-05-03 15:00:40 -0700592 // If non-empty, apply optimizer/debug flags only to matching methods.
593 std::string compilerMethodMatch;
594 // Flips sense of compilerMethodMatch - apply flags if doesn't match.
595 bool compilerFlipMatch;
596 ArenaMemBlock* arenaHead;
597 ArenaMemBlock* currentArena;
598 int numArenaBlocks;
599 Memstats* mstats;
buzbeed1643e42012-09-05 14:06:51 -0700600 Checkstats* checkstats;
buzbee2cfc6392012-05-07 14:51:40 -0700601 bool genBitcode;
buzbee4df2bbd2012-10-11 14:46:06 -0700602 LLVMInfo* llvm_info;
buzbee2cfc6392012-05-07 14:51:40 -0700603 llvm::LLVMContext* context;
604 llvm::Module* module;
605 llvm::Function* func;
606 greenland::IntrinsicHelper* intrinsic_helper;
607 greenland::IRBuilder* irb;
608 llvm::BasicBlock* placeholderBB;
609 llvm::BasicBlock* entryBB;
buzbee4be777b2012-07-12 14:38:18 -0700610 llvm::BasicBlock* entryTargetBB;
buzbee2cfc6392012-05-07 14:51:40 -0700611 std::string bitcode_filename;
612 GrowableList llvmValues;
613 int32_t tempName;
614 SafeMap<llvm::BasicBlock*, LIR*> blockToLabelMap; // llvm bb -> LIR label
615 SafeMap<int32_t, llvm::BasicBlock*> idToBlockMap; // block id -> llvm bb
616 SafeMap<llvm::Value*, RegLocation> locMap; // llvm Value to loc rec
buzbeeb03f4872012-06-11 15:22:11 -0700617 int numShadowFrameEntries;
618 int* shadowMap;
buzbee0967a252012-09-14 10:43:54 -0700619 std::set<llvm::BasicBlock*> llvmBlocks;
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
buzbee6459e7c2012-10-02 14:42:41 -0700628 std::set<uint32_t> catches;
buzbee2cfc6392012-05-07 14:51:40 -0700629 int* opcodeCount; // Count Dalvik opcodes for tuning
Elliott Hughes719ace42012-03-09 18:06:03 -0800630};
buzbee67bf8852011-08-17 17:51:35 -0700631
Elliott Hughes719ace42012-03-09 18:06:03 -0800632enum OpSize {
Bill Buzbeea114add2012-05-03 15:00:40 -0700633 kWord,
634 kLong,
635 kSingle,
636 kDouble,
637 kUnsignedHalf,
638 kSignedHalf,
639 kUnsignedByte,
640 kSignedByte,
Elliott Hughes719ace42012-03-09 18:06:03 -0800641};
buzbeee3acd072012-02-25 17:03:10 -0800642
Elliott Hughes719ace42012-03-09 18:06:03 -0800643enum OpKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700644 kOpMov,
645 kOpMvn,
646 kOpCmp,
647 kOpLsl,
648 kOpLsr,
649 kOpAsr,
650 kOpRor,
651 kOpNot,
652 kOpAnd,
653 kOpOr,
654 kOpXor,
655 kOpNeg,
656 kOpAdd,
657 kOpAdc,
658 kOpSub,
659 kOpSbc,
660 kOpRsub,
661 kOpMul,
662 kOpDiv,
663 kOpRem,
664 kOpBic,
665 kOpCmn,
666 kOpTst,
667 kOpBkpt,
668 kOpBlx,
669 kOpPush,
670 kOpPop,
671 kOp2Char,
672 kOp2Short,
673 kOp2Byte,
674 kOpCondBr,
675 kOpUncondBr,
676 kOpBx,
677 kOpInvalid,
Elliott Hughes719ace42012-03-09 18:06:03 -0800678};
buzbee31a4a6f2012-02-28 15:36:15 -0800679
Ian Rogers680b1bd2012-03-07 20:18:49 -0800680std::ostream& operator<<(std::ostream& os, const OpKind& kind);
681
Elliott Hughes719ace42012-03-09 18:06:03 -0800682enum ConditionCode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700683 kCondEq, // equal
684 kCondNe, // not equal
685 kCondCs, // carry set (unsigned less than)
686 kCondUlt = kCondCs,
687 kCondCc, // carry clear (unsigned greater than or same)
688 kCondUge = kCondCc,
689 kCondMi, // minus
690 kCondPl, // plus, positive or zero
691 kCondVs, // overflow
692 kCondVc, // no overflow
693 kCondHi, // unsigned greater than
694 kCondLs, // unsigned lower or same
695 kCondGe, // signed greater than or equal
696 kCondLt, // signed less than
697 kCondGt, // signed greater than
698 kCondLe, // signed less than or equal
699 kCondAl, // always
700 kCondNv, // never
Elliott Hughes719ace42012-03-09 18:06:03 -0800701};
buzbee31a4a6f2012-02-28 15:36:15 -0800702
buzbeeb046e162012-10-30 15:48:42 -0700703// Target specific condition encodings
704enum ArmConditionCode {
705 kArmCondEq = 0x0, /* 0000 */
706 kArmCondNe = 0x1, /* 0001 */
707 kArmCondCs = 0x2, /* 0010 */
708 kArmCondCc = 0x3, /* 0011 */
709 kArmCondMi = 0x4, /* 0100 */
710 kArmCondPl = 0x5, /* 0101 */
711 kArmCondVs = 0x6, /* 0110 */
712 kArmCondVc = 0x7, /* 0111 */
713 kArmCondHi = 0x8, /* 1000 */
714 kArmCondLs = 0x9, /* 1001 */
715 kArmCondGe = 0xa, /* 1010 */
716 kArmCondLt = 0xb, /* 1011 */
717 kArmCondGt = 0xc, /* 1100 */
718 kArmCondLe = 0xd, /* 1101 */
719 kArmCondAl = 0xe, /* 1110 */
720 kArmCondNv = 0xf, /* 1111 */
721};
722
723enum X86ConditionCode {
724 kX86CondO = 0x0, // overflow
725 kX86CondNo = 0x1, // not overflow
726
727 kX86CondB = 0x2, // below
728 kX86CondNae = kX86CondB, // not-above-equal
729 kX86CondC = kX86CondB, // carry
730
731 kX86CondNb = 0x3, // not-below
732 kX86CondAe = kX86CondNb, // above-equal
733 kX86CondNc = kX86CondNb, // not-carry
734
735 kX86CondZ = 0x4, // zero
736 kX86CondEq = kX86CondZ, // equal
737
738 kX86CondNz = 0x5, // not-zero
739 kX86CondNe = kX86CondNz, // not-equal
740
741 kX86CondBe = 0x6, // below-equal
742 kX86CondNa = kX86CondBe, // not-above
743
744 kX86CondNbe = 0x7, // not-below-equal
745 kX86CondA = kX86CondNbe,// above
746
747 kX86CondS = 0x8, // sign
748 kX86CondNs = 0x9, // not-sign
749
750 kX86CondP = 0xA, // 8-bit parity even
751 kX86CondPE = kX86CondP,
752
753 kX86CondNp = 0xB, // 8-bit parity odd
754 kX86CondPo = kX86CondNp,
755
756 kX86CondL = 0xC, // less-than
757 kX86CondNge = kX86CondL, // not-greater-equal
758
759 kX86CondNl = 0xD, // not-less-than
760 kX86CondGe = kX86CondNl, // not-greater-equal
761
762 kX86CondLe = 0xE, // less-than-equal
763 kX86CondNg = kX86CondLe, // not-greater
764
765 kX86CondNle = 0xF, // not-less-than
766 kX86CondG = kX86CondNle,// greater
767};
768
769
Elliott Hughes719ace42012-03-09 18:06:03 -0800770enum ThrowKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700771 kThrowNullPointer,
772 kThrowDivZero,
773 kThrowArrayBounds,
Bill Buzbeea114add2012-05-03 15:00:40 -0700774 kThrowNoSuchMethod,
775 kThrowStackOverflow,
Elliott Hughes719ace42012-03-09 18:06:03 -0800776};
buzbee31a4a6f2012-02-28 15:36:15 -0800777
Elliott Hughes719ace42012-03-09 18:06:03 -0800778struct SwitchTable {
Bill Buzbeea114add2012-05-03 15:00:40 -0700779 int offset;
780 const u2* table; // Original dex table
781 int vaddr; // Dalvik offset of switch opcode
782 LIR* anchor; // Reference instruction for relative offsets
783 LIR** targets; // Array of case targets
Elliott Hughes719ace42012-03-09 18:06:03 -0800784};
buzbee5de34942012-03-01 14:51:57 -0800785
Elliott Hughes719ace42012-03-09 18:06:03 -0800786struct FillArrayData {
Bill Buzbeea114add2012-05-03 15:00:40 -0700787 int offset;
788 const u2* table; // Original dex table
789 int size;
790 int vaddr; // Dalvik offset of FILL_ARRAY_DATA opcode
Elliott Hughes719ace42012-03-09 18:06:03 -0800791};
buzbee5de34942012-03-01 14:51:57 -0800792
buzbee16da88c2012-03-20 10:38:17 -0700793#define MAX_PATTERN_LEN 5
794
795enum SpecialCaseHandler {
Bill Buzbeea114add2012-05-03 15:00:40 -0700796 kNoHandler,
797 kNullMethod,
798 kConstFunction,
799 kIGet,
800 kIGetBoolean,
801 kIGetObject,
802 kIGetByte,
803 kIGetChar,
804 kIGetShort,
805 kIGetWide,
806 kIPut,
807 kIPutBoolean,
808 kIPutObject,
809 kIPutByte,
810 kIPutChar,
811 kIPutShort,
812 kIPutWide,
813 kIdentity,
buzbee16da88c2012-03-20 10:38:17 -0700814};
815
816struct CodePattern {
Bill Buzbeea114add2012-05-03 15:00:40 -0700817 const Instruction::Code opcodes[MAX_PATTERN_LEN];
818 const SpecialCaseHandler handlerCode;
buzbee16da88c2012-03-20 10:38:17 -0700819};
820
821static const CodePattern specialPatterns[] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700822 {{Instruction::RETURN_VOID}, kNullMethod},
823 {{Instruction::CONST, Instruction::RETURN}, kConstFunction},
824 {{Instruction::CONST_4, Instruction::RETURN}, kConstFunction},
825 {{Instruction::CONST_4, Instruction::RETURN_OBJECT}, kConstFunction},
826 {{Instruction::CONST_16, Instruction::RETURN}, kConstFunction},
827 {{Instruction::IGET, Instruction:: RETURN}, kIGet},
828 {{Instruction::IGET_BOOLEAN, Instruction::RETURN}, kIGetBoolean},
829 {{Instruction::IGET_OBJECT, Instruction::RETURN_OBJECT}, kIGetObject},
830 {{Instruction::IGET_BYTE, Instruction::RETURN}, kIGetByte},
831 {{Instruction::IGET_CHAR, Instruction::RETURN}, kIGetChar},
832 {{Instruction::IGET_SHORT, Instruction::RETURN}, kIGetShort},
833 {{Instruction::IGET_WIDE, Instruction::RETURN_WIDE}, kIGetWide},
834 {{Instruction::IPUT, Instruction::RETURN_VOID}, kIPut},
835 {{Instruction::IPUT_BOOLEAN, Instruction::RETURN_VOID}, kIPutBoolean},
836 {{Instruction::IPUT_OBJECT, Instruction::RETURN_VOID}, kIPutObject},
837 {{Instruction::IPUT_BYTE, Instruction::RETURN_VOID}, kIPutByte},
838 {{Instruction::IPUT_CHAR, Instruction::RETURN_VOID}, kIPutChar},
839 {{Instruction::IPUT_SHORT, Instruction::RETURN_VOID}, kIPutShort},
840 {{Instruction::IPUT_WIDE, Instruction::RETURN_VOID}, kIPutWide},
841 {{Instruction::RETURN}, kIdentity},
842 {{Instruction::RETURN_OBJECT}, kIdentity},
843 {{Instruction::RETURN_WIDE}, kIdentity},
buzbee16da88c2012-03-20 10:38:17 -0700844};
buzbee5de34942012-03-01 14:51:57 -0800845
buzbee5abfa3e2012-01-31 17:01:43 -0800846BasicBlock* oatNewBB(CompilationUnit* cUnit, BBType blockType, int blockId);
buzbee67bf8852011-08-17 17:51:35 -0700847
848void oatAppendMIR(BasicBlock* bb, MIR* mir);
849
850void oatPrependMIR(BasicBlock* bb, MIR* mir);
851
852void oatInsertMIRAfter(BasicBlock* bb, MIR* currentMIR, MIR* newMIR);
853
854void oatAppendLIR(CompilationUnit* cUnit, LIR* lir);
855
856void oatInsertLIRBefore(LIR* currentLIR, LIR* newLIR);
857
858void oatInsertLIRAfter(LIR* currentLIR, LIR* newLIR);
859
buzbee15bf9802012-06-12 17:49:27 -0700860MIR* oatFindMoveResult(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir);
buzbee67bf8852011-08-17 17:51:35 -0700861/* Debug Utilities */
862void oatDumpCompilationUnit(CompilationUnit* cUnit);
863
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800864} // namespace art
865
buzbee67bf8852011-08-17 17:51:35 -0700866#endif // ART_SRC_COMPILER_COMPILER_IR_H_