blob: 69689f94ace7920580b2a31c9b6b973e84bd143e [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
Elliott Hughes719ace42012-03-09 18:06:03 -080044enum RegisterClass {
Bill Buzbeea114add2012-05-03 15:00:40 -070045 kCoreReg,
46 kFPReg,
47 kAnyReg,
Elliott Hughes719ace42012-03-09 18:06:03 -080048};
buzbee67bf8852011-08-17 17:51:35 -070049
Elliott Hughes719ace42012-03-09 18:06:03 -080050enum RegLocationType {
Bill Buzbeea114add2012-05-03 15:00:40 -070051 kLocDalvikFrame = 0, // Normal Dalvik register
52 kLocPhysReg,
53 kLocCompilerTemp,
54 kLocInvalid
Elliott Hughes719ace42012-03-09 18:06:03 -080055};
buzbee67bf8852011-08-17 17:51:35 -070056
Elliott Hughes719ace42012-03-09 18:06:03 -080057struct PromotionMap {
Bill Buzbeea114add2012-05-03 15:00:40 -070058 RegLocationType coreLocation:3;
59 u1 coreReg;
60 RegLocationType fpLocation:3;
61 u1 fpReg;
62 bool firstInPair;
Elliott Hughes719ace42012-03-09 18:06:03 -080063};
buzbee67bc2362011-10-11 18:08:40 -070064
Elliott Hughes719ace42012-03-09 18:06:03 -080065struct RegLocation {
Bill Buzbeea114add2012-05-03 15:00:40 -070066 RegLocationType location:3;
67 unsigned wide:1;
68 unsigned defined:1; // Do we know the type?
buzbee2cfc6392012-05-07 14:51:40 -070069 unsigned isConst:1; // Constant, value in cUnit->constantValues[]
Bill Buzbeea114add2012-05-03 15:00:40 -070070 unsigned fp:1; // Floating point?
71 unsigned core:1; // Non-floating point?
buzbeebff24652012-05-06 16:22:05 -070072 unsigned ref:1; // Something GC cares about
Bill Buzbeea114add2012-05-03 15:00:40 -070073 unsigned highWord:1; // High word of pair?
74 unsigned home:1; // Does this represent the home location?
75 u1 lowReg; // First physical register
76 u1 highReg; // 2nd physical register (if wide)
77 int32_t sRegLow; // SSA name for low Dalvik word
buzbee2cfc6392012-05-07 14:51:40 -070078 int32_t origSReg; // TODO: remove after Bitcode gen complete
79 // and consolodate usage w/ sRegLow
buzbeee1965672012-03-11 18:39:19 -070080};
81
82struct CompilerTemp {
Bill Buzbeea114add2012-05-03 15:00:40 -070083 int sReg;
84 ArenaBitVector* bv;
Elliott Hughes719ace42012-03-09 18:06:03 -080085};
buzbee67bf8852011-08-17 17:51:35 -070086
buzbee3b3dbdd2012-06-13 13:39:34 -070087struct CallInfo {
buzbee15bf9802012-06-12 17:49:27 -070088 int numArgWords; // Note: word count, not arg count
89 RegLocation* args; // One for each word of arguments
90 RegLocation result; // Eventual target of MOVE_RESULT
91 int optFlags;
92 InvokeType type;
93 uint32_t dexIdx;
buzbee3b3dbdd2012-06-13 13:39:34 -070094 uint32_t index; // Method idx for invokes, type idx for FilledNewArray
buzbee15bf9802012-06-12 17:49:27 -070095 uintptr_t directCode;
96 uintptr_t directMethod;
97 RegLocation target; // Target of following move_result
98 bool skipThis;
99 bool isRange;
100 int offset; // Dalvik offset
101};
102
buzbeee3acd072012-02-25 17:03:10 -0800103 /*
104 * Data structure tracking the mapping between a Dalvik register (pair) and a
105 * native register (pair). The idea is to reuse the previously loaded value
106 * if possible, otherwise to keep the value in a native register as long as
107 * possible.
108 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800109struct RegisterInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700110 int reg; // Reg number
111 bool inUse; // Has it been allocated?
112 bool isTemp; // Can allocate as temp?
113 bool pair; // Part of a register pair?
114 int partner; // If pair, other reg of pair
115 bool live; // Is there an associated SSA name?
116 bool dirty; // If live, is it dirty?
117 int sReg; // Name of live value
118 LIR *defStart; // Starting inst in last def sequence
119 LIR *defEnd; // Ending inst in last def sequence
Elliott Hughes719ace42012-03-09 18:06:03 -0800120};
buzbeee3acd072012-02-25 17:03:10 -0800121
Elliott Hughes719ace42012-03-09 18:06:03 -0800122struct RegisterPool {
Bill Buzbeea114add2012-05-03 15:00:40 -0700123 int numCoreRegs;
124 RegisterInfo *coreRegs;
125 int nextCoreReg;
126 int numFPRegs;
127 RegisterInfo *FPRegs;
128 int nextFPReg;
Elliott Hughes719ace42012-03-09 18:06:03 -0800129};
buzbeee3acd072012-02-25 17:03:10 -0800130
buzbee67bf8852011-08-17 17:51:35 -0700131#define INVALID_SREG (-1)
buzbee3ddc0d12011-10-05 10:36:21 -0700132#define INVALID_VREG (0xFFFFU)
buzbee67bc2362011-10-11 18:08:40 -0700133#define INVALID_REG (0xFF)
buzbee67bf8852011-08-17 17:51:35 -0700134#define INVALID_OFFSET (-1)
135
buzbeee1965672012-03-11 18:39:19 -0700136/* SSA encodings for special registers */
buzbee9c044ce2012-03-18 13:24:07 -0700137#define SSA_METHOD_BASEREG (-2)
buzbeee1965672012-03-11 18:39:19 -0700138/* First compiler temp basereg, grows smaller */
buzbee9c044ce2012-03-18 13:24:07 -0700139#define SSA_CTEMP_BASEREG (SSA_METHOD_BASEREG - 1)
buzbee2cfc6392012-05-07 14:51:40 -0700140/* Max SSA name length */
141#define SSA_NAME_MAX 16
buzbeee1965672012-03-11 18:39:19 -0700142
buzbee99ba9642012-01-25 14:23:14 -0800143/*
144 * Some code patterns cause the generation of excessively large
145 * methods - in particular initialization sequences. There isn't much
146 * benefit in optimizing these methods, and the cost can be very high.
147 * We attempt to identify these cases, and avoid performing most dataflow
148 * analysis. Two thresholds are used - one for known initializers and one
buzbee5abfa3e2012-01-31 17:01:43 -0800149 * for everything else.
buzbee99ba9642012-01-25 14:23:14 -0800150 */
buzbee5abfa3e2012-01-31 17:01:43 -0800151#define MANY_BLOCKS_INITIALIZER 1000 /* Threshold for switching dataflow off */
152#define MANY_BLOCKS 4000 /* Non-initializer threshold */
buzbee99ba9642012-01-25 14:23:14 -0800153
Elliott Hughes719ace42012-03-09 18:06:03 -0800154enum BBType {
Bill Buzbeea114add2012-05-03 15:00:40 -0700155 kEntryBlock,
156 kDalvikByteCode,
157 kExitBlock,
158 kExceptionHandling,
159 kCatchEntry,
Elliott Hughes719ace42012-03-09 18:06:03 -0800160};
buzbee67bf8852011-08-17 17:51:35 -0700161
buzbee31a4a6f2012-02-28 15:36:15 -0800162/* Utility macros to traverse the LIR list */
163#define NEXT_LIR(lir) (lir->next)
164#define PREV_LIR(lir) (lir->prev)
165
166#define NEXT_LIR_LVALUE(lir) (lir)->next
167#define PREV_LIR_LVALUE(lir) (lir)->prev
168
Elliott Hughes719ace42012-03-09 18:06:03 -0800169struct LIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700170 int offset; // Offset of this instruction
171 int dalvikOffset; // Offset of Dalvik opcode
172 LIR* next;
173 LIR* prev;
174 LIR* target;
175 int opcode;
176 int operands[5]; // [0..4] = [dest, src1, src2, extra, extra2]
177 struct {
178 bool isNop:1; // LIR is optimized away
179 bool pcRelFixup:1; // May need pc-relative fixup
180 unsigned int age:4; // default is 0, set lazily by the optimizer
181 unsigned int size:5; // in bytes
182 unsigned int unused:21;
183 } flags;
184 int aliasInfo; // For Dalvik register & litpool disambiguation
185 u8 useMask; // Resource mask for use
186 u8 defMask; // Resource mask for def
Elliott Hughes719ace42012-03-09 18:06:03 -0800187};
buzbee67bf8852011-08-17 17:51:35 -0700188
189enum ExtendedMIROpcode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700190 kMirOpFirst = kNumPackedOpcodes,
191 kMirOpPhi = kMirOpFirst,
192 kMirOpCopy,
193 kMirOpFusedCmplFloat,
194 kMirOpFusedCmpgFloat,
195 kMirOpFusedCmplDouble,
196 kMirOpFusedCmpgDouble,
197 kMirOpFusedCmpLong,
198 kMirOpNop,
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700199 kMirOpNullCheck,
200 kMirOpRangeCheck,
201 kMirOpDivZeroCheck,
202 kMirOpCheck,
Bill Buzbeea114add2012-05-03 15:00:40 -0700203 kMirOpLast,
buzbee67bf8852011-08-17 17:51:35 -0700204};
205
206struct SSARepresentation;
207
Elliott Hughes719ace42012-03-09 18:06:03 -0800208enum MIROptimizationFlagPositons {
Bill Buzbeea114add2012-05-03 15:00:40 -0700209 kMIRIgnoreNullCheck = 0,
210 kMIRNullCheckOnly,
211 kMIRIgnoreRangeCheck,
212 kMIRRangeCheckOnly,
213 kMIRInlined, // Invoke is inlined (ie dead)
214 kMIRInlinedPred, // Invoke is inlined via prediction
215 kMIRCallee, // Instruction is inlined from callee
216 kMIRIgnoreSuspendCheck,
217 kMIRDup,
218 kMIRMark, // Temporary node mark
Elliott Hughes719ace42012-03-09 18:06:03 -0800219};
buzbee67bf8852011-08-17 17:51:35 -0700220
221#define MIR_IGNORE_NULL_CHECK (1 << kMIRIgnoreNullCheck)
222#define MIR_NULL_CHECK_ONLY (1 << kMIRNullCheckOnly)
223#define MIR_IGNORE_RANGE_CHECK (1 << kMIRIgnoreRangeCheck)
224#define MIR_RANGE_CHECK_ONLY (1 << kMIRRangeCheckOnly)
225#define MIR_INLINED (1 << kMIRInlined)
226#define MIR_INLINED_PRED (1 << kMIRInlinedPred)
227#define MIR_CALLEE (1 << kMIRCallee)
buzbeec1f45042011-09-21 16:03:19 -0700228#define MIR_IGNORE_SUSPEND_CHECK (1 << kMIRIgnoreSuspendCheck)
buzbeee1965672012-03-11 18:39:19 -0700229#define MIR_DUP (1 << kMIRDup)
buzbee239c4e72012-03-16 08:42:29 -0700230#define MIR_MARK (1 << kMIRMark)
buzbee67bf8852011-08-17 17:51:35 -0700231
Elliott Hughes719ace42012-03-09 18:06:03 -0800232struct CallsiteInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700233 const char* classDescriptor;
234 Object* classLoader;
235 const Method* method;
236 LIR* misPredBranchOver;
Elliott Hughes719ace42012-03-09 18:06:03 -0800237};
buzbee67bf8852011-08-17 17:51:35 -0700238
Elliott Hughes719ace42012-03-09 18:06:03 -0800239struct MIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700240 DecodedInstruction dalvikInsn;
241 unsigned int width;
242 unsigned int offset;
243 MIR* prev;
244 MIR* next;
245 SSARepresentation* ssaRep;
246 int optimizationFlags;
247 int seqNum;
248 union {
Bill Buzbeea114add2012-05-03 15:00:40 -0700249 // Used to quickly locate all Phi opcodes
250 MIR* phiNext;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700251 // Establish link between two halves of throwing instructions
252 MIR* throwInsn;
Bill Buzbeea114add2012-05-03 15:00:40 -0700253 } meta;
Elliott Hughes719ace42012-03-09 18:06:03 -0800254};
buzbee67bf8852011-08-17 17:51:35 -0700255
256struct BasicBlockDataFlow;
257
258/* For successorBlockList */
Elliott Hughes719ace42012-03-09 18:06:03 -0800259enum BlockListType {
Bill Buzbeea114add2012-05-03 15:00:40 -0700260 kNotUsed = 0,
261 kCatch,
262 kPackedSwitch,
263 kSparseSwitch,
Elliott Hughes719ace42012-03-09 18:06:03 -0800264};
buzbee67bf8852011-08-17 17:51:35 -0700265
Elliott Hughes719ace42012-03-09 18:06:03 -0800266struct BasicBlock {
Bill Buzbeea114add2012-05-03 15:00:40 -0700267 int id;
268 int dfsId;
269 bool visited;
270 bool hidden;
271 bool catchEntry;
272 bool fallThroughTarget; // Reached via fallthrough
buzbee2cfc6392012-05-07 14:51:40 -0700273#if defined(ART_USE_QUICK_COMPILER)
274 bool hasReturn;
275#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700276 uint16_t startOffset;
277 uint16_t nestingDepth;
278 const Method* containingMethod; // For blocks from the callee
279 BBType blockType;
Bill Buzbeea114add2012-05-03 15:00:40 -0700280 bool isFallThroughFromInvoke; // True means the block needs alignment
281 MIR* firstMIRInsn;
282 MIR* lastMIRInsn;
283 BasicBlock* fallThrough;
284 BasicBlock* taken;
285 BasicBlock* iDom; // Immediate dominator
286 BasicBlockDataFlow* dataFlowInfo;
287 GrowableList* predecessors;
288 ArenaBitVector* dominators;
289 ArenaBitVector* iDominated; // Set nodes being immediately dominated
290 ArenaBitVector* domFrontier; // Dominance frontier
291 struct { // For one-to-many successors like
292 BlockListType blockListType; // switch and exception handling
293 GrowableList blocks;
294 } successorBlockList;
Elliott Hughes719ace42012-03-09 18:06:03 -0800295};
buzbee67bf8852011-08-17 17:51:35 -0700296
297/*
298 * The "blocks" field in "successorBlockList" points to an array of
299 * elements with the type "SuccessorBlockInfo".
300 * For catch blocks, key is type index for the exception.
301 * For swtich blocks, key is the case value.
302 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800303struct SuccessorBlockInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700304 BasicBlock* block;
305 int key;
Elliott Hughes719ace42012-03-09 18:06:03 -0800306};
buzbee67bf8852011-08-17 17:51:35 -0700307
308struct LoopAnalysis;
309struct RegisterPool;
buzbeeba938cb2012-02-03 14:47:55 -0800310struct ArenaMemBlock;
311struct Memstats;
buzbee67bf8852011-08-17 17:51:35 -0700312
Elliott Hughes719ace42012-03-09 18:06:03 -0800313enum AssemblerStatus {
Bill Buzbeea114add2012-05-03 15:00:40 -0700314 kSuccess,
315 kRetryAll,
316 kRetryHalve
Elliott Hughes719ace42012-03-09 18:06:03 -0800317};
buzbee67bf8852011-08-17 17:51:35 -0700318
buzbee5b537102012-01-17 17:33:47 -0800319#define NOTVISITED (-1)
320
Elliott Hughes719ace42012-03-09 18:06:03 -0800321struct CompilationUnit {
Elliott Hughese52e49b2012-04-02 16:05:44 -0700322 CompilationUnit()
Bill Buzbeea114add2012-05-03 15:00:40 -0700323 : numBlocks(0),
324 compiler(NULL),
325 class_linker(NULL),
326 dex_file(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700327 class_loader(NULL),
328 method_idx(0),
329 code_item(NULL),
330 access_flags(0),
331 shorty(NULL),
332 firstLIRInsn(NULL),
333 lastLIRInsn(NULL),
334 literalList(NULL),
335 methodLiteralList(NULL),
336 codeLiteralList(NULL),
337 classPointerList(NULL),
338 numClassPointers(0),
339 chainCellOffsetLIR(NULL),
340 disableOpt(0),
341 enableDebug(0),
342 headerSize(0),
343 dataOffset(0),
344 totalSize(0),
345 assemblerStatus(kSuccess),
346 assemblerRetries(0),
347 genDebugger(false),
348 printMe(false),
349 hasClassLiterals(false),
350 hasLoop(false),
351 hasInvoke(false),
352 heapMemOp(false),
353 qdMode(false),
354 usesLinkRegister(false),
355 methodTraceSupport(false),
356 regPool(NULL),
357 optRound(0),
358 instructionSet(kNone),
359 numSSARegs(0),
360 ssaBaseVRegs(NULL),
361 ssaSubscripts(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700362 ssaStrings(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700363 vRegToSSAMap(NULL),
364 SSALastDefs(NULL),
365 isConstantV(NULL),
366 constantValues(NULL),
367 phiAliasMap(NULL),
368 phiList(NULL),
369 regLocation(NULL),
370 sequenceNumber(0),
371 promotionMap(NULL),
372 methodSReg(0),
373 switchOverflowPad(NULL),
374 numReachableBlocks(0),
375 numDalvikRegisters(0),
376 entryBlock(NULL),
377 exitBlock(NULL),
378 curBlock(NULL),
379 nextCodegenBlock(NULL),
380 iDomList(NULL),
381 tryBlockAddr(NULL),
382 defBlockMatrix(NULL),
383 tempBlockV(NULL),
384 tempDalvikRegisterV(NULL),
385 tempSSARegisterV(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700386 tempSSABlockIdV(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700387 printSSANames(false),
388 blockLabelList(NULL),
389 quitLoopMode(false),
390 preservedRegsUsed(0),
391 numIns(0),
392 numOuts(0),
393 numRegs(0),
394 numCoreSpills(0),
395 numFPSpills(0),
396 numCompilerTemps(0),
397 frameSize(0),
398 coreSpillMask(0U),
399 fpSpillMask(0U),
400 attrs(0U),
401 currentDalvikOffset(0),
402 insns(NULL),
403 insnsSize(0U),
404 disableDataflow(false),
405 defCount(0),
406 compilerFlipMatch(false),
407 arenaHead(NULL),
408 currentArena(NULL),
409 numArenaBlocks(0),
410 mstats(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700411#if defined(ART_USE_QUICK_COMPILER)
412 genBitcode(false),
413 context(NULL),
414 module(NULL),
415 func(NULL),
416 intrinsic_helper(NULL),
417 irb(NULL),
418 placeholderBB(NULL),
419 entryBB(NULL),
buzbee4be777b2012-07-12 14:38:18 -0700420 entryTargetBB(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700421 tempName(0),
buzbeeb03f4872012-06-11 15:22:11 -0700422 requireShadowFrame(false),
423 numShadowFrameEntries(0),
424 shadowMap(NULL),
Elliott Hughese52e49b2012-04-02 16:05:44 -0700425#endif
buzbee2cfc6392012-05-07 14:51:40 -0700426#ifndef NDEBUG
427 liveSReg(0),
428#endif
429 opcodeCount(NULL) {}
Elliott Hughese52e49b2012-04-02 16:05:44 -0700430
Bill Buzbeea114add2012-05-03 15:00:40 -0700431 int numBlocks;
432 GrowableList blockList;
433 Compiler* compiler; // Compiler driving this compiler
434 ClassLinker* class_linker; // Linker to resolve fields and methods
435 const DexFile* dex_file; // DexFile containing the method being compiled
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700436 jobject class_loader; // compiling method's class loader
Bill Buzbeea114add2012-05-03 15:00:40 -0700437 uint32_t method_idx; // compiling method's index into method_ids of DexFile
438 const DexFile::CodeItem* code_item; // compiling method's DexFile code_item
439 uint32_t access_flags; // compiling method's access flags
440 const char* shorty; // compiling method's shorty
441 LIR* firstLIRInsn;
442 LIR* lastLIRInsn;
443 LIR* literalList; // Constants
444 LIR* methodLiteralList; // Method literals requiring patching
445 LIR* codeLiteralList; // Code literals requiring patching
446 LIR* classPointerList; // Relocatable
447 int numClassPointers;
448 LIR* chainCellOffsetLIR;
449 uint32_t disableOpt; // optControlVector flags
450 uint32_t enableDebug; // debugControlVector flags
451 int headerSize; // bytes before the first code ptr
452 int dataOffset; // starting offset of literal pool
453 int totalSize; // header + code size
454 AssemblerStatus assemblerStatus; // Success or fix and retry
455 int assemblerRetries;
456 std::vector<uint8_t> codeBuffer;
457 std::vector<uint32_t> mappingTable;
458 std::vector<uint16_t> coreVmapTable;
459 std::vector<uint16_t> fpVmapTable;
460 bool genDebugger; // Generate code for debugger
461 bool printMe;
462 bool hasClassLiterals; // Contains class ptrs used as literals
463 bool hasLoop; // Contains a loop
464 bool hasInvoke; // Contains an invoke instruction
465 bool heapMemOp; // Mark mem ops for self verification
466 bool qdMode; // Compile for code size/compile time
467 bool usesLinkRegister; // For self-verification only
468 bool methodTraceSupport; // For TraceView profiling
469 RegisterPool* regPool;
470 int optRound; // round number to tell an LIR's age
471 InstructionSet instructionSet;
472 /* Number of total regs used in the whole cUnit after SSA transformation */
473 int numSSARegs;
474 /* Map SSA reg i to the base virtual register/subscript */
475 GrowableList* ssaBaseVRegs;
476 GrowableList* ssaSubscripts;
buzbee2cfc6392012-05-07 14:51:40 -0700477 GrowableList* ssaStrings;
buzbee67bf8852011-08-17 17:51:35 -0700478
Bill Buzbeea114add2012-05-03 15:00:40 -0700479 /* The following are new data structures to support SSA representations */
480 /* Map original Dalvik virtual reg i to the current SSA name */
481 int* vRegToSSAMap; // length == method->registersSize
482 int* SSALastDefs; // length == method->registersSize
483 ArenaBitVector* isConstantV; // length == numSSAReg
484 int* constantValues; // length == numSSAReg
485 int* phiAliasMap; // length == numSSAReg
486 MIR* phiList;
buzbee67bf8852011-08-17 17:51:35 -0700487
Bill Buzbeea114add2012-05-03 15:00:40 -0700488 /* Use counts of ssa names */
489 GrowableList useCounts; // Weighted by nesting depth
490 GrowableList rawUseCounts; // Not weighted
buzbee239c4e72012-03-16 08:42:29 -0700491
Bill Buzbeea114add2012-05-03 15:00:40 -0700492 /* Optimization support */
493 GrowableList loopHeaders;
buzbee239c4e72012-03-16 08:42:29 -0700494
Bill Buzbeea114add2012-05-03 15:00:40 -0700495 /* Map SSA names to location */
496 RegLocation* regLocation;
497 int sequenceNumber;
buzbee67bf8852011-08-17 17:51:35 -0700498
Bill Buzbeea114add2012-05-03 15:00:40 -0700499 /* Keep track of Dalvik vReg to physical register mappings */
500 PromotionMap* promotionMap;
buzbee67bc2362011-10-11 18:08:40 -0700501
Bill Buzbeea114add2012-05-03 15:00:40 -0700502 /* SSA name for Method* */
503 int methodSReg;
buzbeead8f15e2012-06-18 14:49:45 -0700504 RegLocation methodLoc; // Describes location of method*
buzbeee1965672012-03-11 18:39:19 -0700505
Bill Buzbeea114add2012-05-03 15:00:40 -0700506 /*
507 * Set to the Dalvik PC of the switch instruction if it has more than
508 * MAX_CHAINED_SWITCH_CASES cases.
509 */
510 const u2* switchOverflowPad;
buzbee67bf8852011-08-17 17:51:35 -0700511
Bill Buzbeea114add2012-05-03 15:00:40 -0700512 int numReachableBlocks;
513 int numDalvikRegisters; // method->registersSize
514 BasicBlock* entryBlock;
515 BasicBlock* exitBlock;
516 BasicBlock* curBlock;
517 BasicBlock* nextCodegenBlock; // for extended trace codegen
518 GrowableList dfsOrder;
519 GrowableList dfsPostOrder;
520 GrowableList domPostOrderTraversal;
521 GrowableList throwLaunchpads;
522 GrowableList suspendLaunchpads;
523 GrowableList intrinsicLaunchpads;
524 GrowableList compilerTemps;
525 int* iDomList;
526 ArenaBitVector* tryBlockAddr;
527 ArenaBitVector** defBlockMatrix; // numDalvikRegister x numBlocks
528 ArenaBitVector* tempBlockV;
529 ArenaBitVector* tempDalvikRegisterV;
530 ArenaBitVector* tempSSARegisterV; // numSSARegs
buzbee2cfc6392012-05-07 14:51:40 -0700531 int* tempSSABlockIdV; // working storage for Phi labels
Bill Buzbeea114add2012-05-03 15:00:40 -0700532 bool printSSANames;
buzbeea1da8a52012-07-09 14:00:21 -0700533 LIR* blockLabelList;
Bill Buzbeea114add2012-05-03 15:00:40 -0700534 bool quitLoopMode; // cold path/complex bytecode
535 int preservedRegsUsed; // How many callee save regs used
536 /*
537 * Frame layout details.
538 * NOTE: for debug support it will be necessary to add a structure
539 * to map the Dalvik virtual registers to the promoted registers.
540 * NOTE: "num" fields are in 4-byte words, "Size" and "Offset" in bytes.
541 */
542 int numIns;
543 int numOuts;
544 int numRegs; // Unlike numDalvikRegisters, does not include ins
545 int numCoreSpills;
546 int numFPSpills;
547 int numCompilerTemps;
548 int frameSize;
549 unsigned int coreSpillMask;
550 unsigned int fpSpillMask;
551 unsigned int attrs;
552 /*
553 * CLEANUP/RESTRUCTURE: The code generation utilities don't have a built-in
554 * mechanism to propagate the original Dalvik opcode address to the
555 * associated generated instructions. For the trace compiler, this wasn't
556 * necessary because the interpreter handled all throws and debugging
557 * requests. For now we'll handle this by placing the Dalvik offset
558 * in the CompilationUnit struct before codegen for each instruction.
559 * The low-level LIR creation utilites will pull it from here. Should
560 * be rewritten.
561 */
562 int currentDalvikOffset;
563 GrowableList switchTables;
564 GrowableList fillArrayData;
565 const u2* insns;
566 u4 insnsSize;
567 bool disableDataflow; // Skip dataflow analysis if possible
568 SafeMap<unsigned int, BasicBlock*> blockMap; // findBlock lookup cache
569 SafeMap<unsigned int, LIR*> boundaryMap; // boundary lookup cache
570 int defCount; // Used to estimate number of SSA names
Elliott Hughese52e49b2012-04-02 16:05:44 -0700571
Bill Buzbeea114add2012-05-03 15:00:40 -0700572 // If non-empty, apply optimizer/debug flags only to matching methods.
573 std::string compilerMethodMatch;
574 // Flips sense of compilerMethodMatch - apply flags if doesn't match.
575 bool compilerFlipMatch;
576 ArenaMemBlock* arenaHead;
577 ArenaMemBlock* currentArena;
578 int numArenaBlocks;
579 Memstats* mstats;
buzbee2cfc6392012-05-07 14:51:40 -0700580#if defined(ART_USE_QUICK_COMPILER)
581 bool genBitcode;
582 llvm::LLVMContext* context;
583 llvm::Module* module;
584 llvm::Function* func;
585 greenland::IntrinsicHelper* intrinsic_helper;
586 greenland::IRBuilder* irb;
587 llvm::BasicBlock* placeholderBB;
588 llvm::BasicBlock* entryBB;
buzbee4be777b2012-07-12 14:38:18 -0700589 llvm::BasicBlock* entryTargetBB;
buzbee2cfc6392012-05-07 14:51:40 -0700590 std::string bitcode_filename;
591 GrowableList llvmValues;
592 int32_t tempName;
593 SafeMap<llvm::BasicBlock*, LIR*> blockToLabelMap; // llvm bb -> LIR label
594 SafeMap<int32_t, llvm::BasicBlock*> idToBlockMap; // block id -> llvm bb
595 SafeMap<llvm::Value*, RegLocation> locMap; // llvm Value to loc rec
buzbeeb03f4872012-06-11 15:22:11 -0700596 bool requireShadowFrame;
597 int numShadowFrameEntries;
598 int* shadowMap;
buzbee2cfc6392012-05-07 14:51:40 -0700599#endif
buzbee3d661942012-03-14 17:37:27 -0700600#ifndef NDEBUG
Bill Buzbeea114add2012-05-03 15:00:40 -0700601 /*
602 * Sanity checking for the register temp tracking. The same ssa
603 * name should never be associated with one temp register per
604 * instruction compilation.
605 */
606 int liveSReg;
buzbee3d661942012-03-14 17:37:27 -0700607#endif
buzbee2cfc6392012-05-07 14:51:40 -0700608 int* opcodeCount; // Count Dalvik opcodes for tuning
Elliott Hughes719ace42012-03-09 18:06:03 -0800609};
buzbee67bf8852011-08-17 17:51:35 -0700610
Elliott Hughes719ace42012-03-09 18:06:03 -0800611enum OpSize {
Bill Buzbeea114add2012-05-03 15:00:40 -0700612 kWord,
613 kLong,
614 kSingle,
615 kDouble,
616 kUnsignedHalf,
617 kSignedHalf,
618 kUnsignedByte,
619 kSignedByte,
Elliott Hughes719ace42012-03-09 18:06:03 -0800620};
buzbeee3acd072012-02-25 17:03:10 -0800621
Elliott Hughes719ace42012-03-09 18:06:03 -0800622enum OpKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700623 kOpMov,
624 kOpMvn,
625 kOpCmp,
626 kOpLsl,
627 kOpLsr,
628 kOpAsr,
629 kOpRor,
630 kOpNot,
631 kOpAnd,
632 kOpOr,
633 kOpXor,
634 kOpNeg,
635 kOpAdd,
636 kOpAdc,
637 kOpSub,
638 kOpSbc,
639 kOpRsub,
640 kOpMul,
641 kOpDiv,
642 kOpRem,
643 kOpBic,
644 kOpCmn,
645 kOpTst,
646 kOpBkpt,
647 kOpBlx,
648 kOpPush,
649 kOpPop,
650 kOp2Char,
651 kOp2Short,
652 kOp2Byte,
653 kOpCondBr,
654 kOpUncondBr,
655 kOpBx,
656 kOpInvalid,
Elliott Hughes719ace42012-03-09 18:06:03 -0800657};
buzbee31a4a6f2012-02-28 15:36:15 -0800658
Ian Rogers680b1bd2012-03-07 20:18:49 -0800659std::ostream& operator<<(std::ostream& os, const OpKind& kind);
660
Elliott Hughes719ace42012-03-09 18:06:03 -0800661enum ConditionCode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700662 kCondEq, // equal
663 kCondNe, // not equal
664 kCondCs, // carry set (unsigned less than)
665 kCondUlt = kCondCs,
666 kCondCc, // carry clear (unsigned greater than or same)
667 kCondUge = kCondCc,
668 kCondMi, // minus
669 kCondPl, // plus, positive or zero
670 kCondVs, // overflow
671 kCondVc, // no overflow
672 kCondHi, // unsigned greater than
673 kCondLs, // unsigned lower or same
674 kCondGe, // signed greater than or equal
675 kCondLt, // signed less than
676 kCondGt, // signed greater than
677 kCondLe, // signed less than or equal
678 kCondAl, // always
679 kCondNv, // never
Elliott Hughes719ace42012-03-09 18:06:03 -0800680};
buzbee31a4a6f2012-02-28 15:36:15 -0800681
Elliott Hughes719ace42012-03-09 18:06:03 -0800682enum ThrowKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700683 kThrowNullPointer,
684 kThrowDivZero,
685 kThrowArrayBounds,
686 kThrowVerificationError,
687 kThrowNoSuchMethod,
688 kThrowStackOverflow,
Elliott Hughes719ace42012-03-09 18:06:03 -0800689};
buzbee31a4a6f2012-02-28 15:36:15 -0800690
Elliott Hughes719ace42012-03-09 18:06:03 -0800691struct SwitchTable {
Bill Buzbeea114add2012-05-03 15:00:40 -0700692 int offset;
693 const u2* table; // Original dex table
694 int vaddr; // Dalvik offset of switch opcode
695 LIR* anchor; // Reference instruction for relative offsets
696 LIR** targets; // Array of case targets
Elliott Hughes719ace42012-03-09 18:06:03 -0800697};
buzbee5de34942012-03-01 14:51:57 -0800698
Elliott Hughes719ace42012-03-09 18:06:03 -0800699struct FillArrayData {
Bill Buzbeea114add2012-05-03 15:00:40 -0700700 int offset;
701 const u2* table; // Original dex table
702 int size;
703 int vaddr; // Dalvik offset of FILL_ARRAY_DATA opcode
Elliott Hughes719ace42012-03-09 18:06:03 -0800704};
buzbee5de34942012-03-01 14:51:57 -0800705
buzbee16da88c2012-03-20 10:38:17 -0700706#define MAX_PATTERN_LEN 5
707
708enum SpecialCaseHandler {
Bill Buzbeea114add2012-05-03 15:00:40 -0700709 kNoHandler,
710 kNullMethod,
711 kConstFunction,
712 kIGet,
713 kIGetBoolean,
714 kIGetObject,
715 kIGetByte,
716 kIGetChar,
717 kIGetShort,
718 kIGetWide,
719 kIPut,
720 kIPutBoolean,
721 kIPutObject,
722 kIPutByte,
723 kIPutChar,
724 kIPutShort,
725 kIPutWide,
726 kIdentity,
buzbee16da88c2012-03-20 10:38:17 -0700727};
728
729struct CodePattern {
Bill Buzbeea114add2012-05-03 15:00:40 -0700730 const Instruction::Code opcodes[MAX_PATTERN_LEN];
731 const SpecialCaseHandler handlerCode;
buzbee16da88c2012-03-20 10:38:17 -0700732};
733
734static const CodePattern specialPatterns[] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700735 {{Instruction::RETURN_VOID}, kNullMethod},
736 {{Instruction::CONST, Instruction::RETURN}, kConstFunction},
737 {{Instruction::CONST_4, Instruction::RETURN}, kConstFunction},
738 {{Instruction::CONST_4, Instruction::RETURN_OBJECT}, kConstFunction},
739 {{Instruction::CONST_16, Instruction::RETURN}, kConstFunction},
740 {{Instruction::IGET, Instruction:: RETURN}, kIGet},
741 {{Instruction::IGET_BOOLEAN, Instruction::RETURN}, kIGetBoolean},
742 {{Instruction::IGET_OBJECT, Instruction::RETURN_OBJECT}, kIGetObject},
743 {{Instruction::IGET_BYTE, Instruction::RETURN}, kIGetByte},
744 {{Instruction::IGET_CHAR, Instruction::RETURN}, kIGetChar},
745 {{Instruction::IGET_SHORT, Instruction::RETURN}, kIGetShort},
746 {{Instruction::IGET_WIDE, Instruction::RETURN_WIDE}, kIGetWide},
747 {{Instruction::IPUT, Instruction::RETURN_VOID}, kIPut},
748 {{Instruction::IPUT_BOOLEAN, Instruction::RETURN_VOID}, kIPutBoolean},
749 {{Instruction::IPUT_OBJECT, Instruction::RETURN_VOID}, kIPutObject},
750 {{Instruction::IPUT_BYTE, Instruction::RETURN_VOID}, kIPutByte},
751 {{Instruction::IPUT_CHAR, Instruction::RETURN_VOID}, kIPutChar},
752 {{Instruction::IPUT_SHORT, Instruction::RETURN_VOID}, kIPutShort},
753 {{Instruction::IPUT_WIDE, Instruction::RETURN_VOID}, kIPutWide},
754 {{Instruction::RETURN}, kIdentity},
755 {{Instruction::RETURN_OBJECT}, kIdentity},
756 {{Instruction::RETURN_WIDE}, kIdentity},
buzbee16da88c2012-03-20 10:38:17 -0700757};
buzbee5de34942012-03-01 14:51:57 -0800758
buzbee5abfa3e2012-01-31 17:01:43 -0800759BasicBlock* oatNewBB(CompilationUnit* cUnit, BBType blockType, int blockId);
buzbee67bf8852011-08-17 17:51:35 -0700760
761void oatAppendMIR(BasicBlock* bb, MIR* mir);
762
763void oatPrependMIR(BasicBlock* bb, MIR* mir);
764
765void oatInsertMIRAfter(BasicBlock* bb, MIR* currentMIR, MIR* newMIR);
766
767void oatAppendLIR(CompilationUnit* cUnit, LIR* lir);
768
769void oatInsertLIRBefore(LIR* currentLIR, LIR* newLIR);
770
771void oatInsertLIRAfter(LIR* currentLIR, LIR* newLIR);
772
buzbee15bf9802012-06-12 17:49:27 -0700773MIR* oatFindMoveResult(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir);
buzbee67bf8852011-08-17 17:51:35 -0700774/* Debug Utilities */
775void oatDumpCompilationUnit(CompilationUnit* cUnit);
776
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800777} // namespace art
778
buzbee67bf8852011-08-17 17:51:35 -0700779#endif // ART_SRC_COMPILER_COMPILER_IR_H_