blob: 1ecf61aef514c4e1d01562ec080db55e59a60fba [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,
199 kMirOpNullNRangeUpCheck,
200 kMirOpNullNRangeDownCheck,
201 kMirOpLowerBound,
202 kMirOpLast,
buzbee67bf8852011-08-17 17:51:35 -0700203};
204
205struct SSARepresentation;
206
Elliott Hughes719ace42012-03-09 18:06:03 -0800207enum MIROptimizationFlagPositons {
Bill Buzbeea114add2012-05-03 15:00:40 -0700208 kMIRIgnoreNullCheck = 0,
209 kMIRNullCheckOnly,
210 kMIRIgnoreRangeCheck,
211 kMIRRangeCheckOnly,
212 kMIRInlined, // Invoke is inlined (ie dead)
213 kMIRInlinedPred, // Invoke is inlined via prediction
214 kMIRCallee, // Instruction is inlined from callee
215 kMIRIgnoreSuspendCheck,
216 kMIRDup,
217 kMIRMark, // Temporary node mark
Elliott Hughes719ace42012-03-09 18:06:03 -0800218};
buzbee67bf8852011-08-17 17:51:35 -0700219
220#define MIR_IGNORE_NULL_CHECK (1 << kMIRIgnoreNullCheck)
221#define MIR_NULL_CHECK_ONLY (1 << kMIRNullCheckOnly)
222#define MIR_IGNORE_RANGE_CHECK (1 << kMIRIgnoreRangeCheck)
223#define MIR_RANGE_CHECK_ONLY (1 << kMIRRangeCheckOnly)
224#define MIR_INLINED (1 << kMIRInlined)
225#define MIR_INLINED_PRED (1 << kMIRInlinedPred)
226#define MIR_CALLEE (1 << kMIRCallee)
buzbeec1f45042011-09-21 16:03:19 -0700227#define MIR_IGNORE_SUSPEND_CHECK (1 << kMIRIgnoreSuspendCheck)
buzbeee1965672012-03-11 18:39:19 -0700228#define MIR_DUP (1 << kMIRDup)
buzbee239c4e72012-03-16 08:42:29 -0700229#define MIR_MARK (1 << kMIRMark)
buzbee67bf8852011-08-17 17:51:35 -0700230
Elliott Hughes719ace42012-03-09 18:06:03 -0800231struct CallsiteInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700232 const char* classDescriptor;
233 Object* classLoader;
234 const Method* method;
235 LIR* misPredBranchOver;
Elliott Hughes719ace42012-03-09 18:06:03 -0800236};
buzbee67bf8852011-08-17 17:51:35 -0700237
Elliott Hughes719ace42012-03-09 18:06:03 -0800238struct MIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700239 DecodedInstruction dalvikInsn;
240 unsigned int width;
241 unsigned int offset;
242 MIR* prev;
243 MIR* next;
244 SSARepresentation* ssaRep;
245 int optimizationFlags;
246 int seqNum;
247 union {
248 // Used by the inlined insn from the callee to find the mother method
249 const Method* calleeMethod;
250 // Used by the inlined invoke to find the class and method pointers
251 CallsiteInfo* callsiteInfo;
252 // Used to quickly locate all Phi opcodes
253 MIR* phiNext;
254 } meta;
Elliott Hughes719ace42012-03-09 18:06:03 -0800255};
buzbee67bf8852011-08-17 17:51:35 -0700256
257struct BasicBlockDataFlow;
258
259/* For successorBlockList */
Elliott Hughes719ace42012-03-09 18:06:03 -0800260enum BlockListType {
Bill Buzbeea114add2012-05-03 15:00:40 -0700261 kNotUsed = 0,
262 kCatch,
263 kPackedSwitch,
264 kSparseSwitch,
Elliott Hughes719ace42012-03-09 18:06:03 -0800265};
buzbee67bf8852011-08-17 17:51:35 -0700266
Elliott Hughes719ace42012-03-09 18:06:03 -0800267struct BasicBlock {
Bill Buzbeea114add2012-05-03 15:00:40 -0700268 int id;
269 int dfsId;
270 bool visited;
271 bool hidden;
272 bool catchEntry;
273 bool fallThroughTarget; // Reached via fallthrough
buzbee2cfc6392012-05-07 14:51:40 -0700274#if defined(ART_USE_QUICK_COMPILER)
275 bool hasReturn;
276#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700277 uint16_t startOffset;
278 uint16_t nestingDepth;
279 const Method* containingMethod; // For blocks from the callee
280 BBType blockType;
281 bool needFallThroughBranch; // For blocks ended due to length limit
282 bool isFallThroughFromInvoke; // True means the block needs alignment
283 MIR* firstMIRInsn;
284 MIR* lastMIRInsn;
285 BasicBlock* fallThrough;
286 BasicBlock* taken;
287 BasicBlock* iDom; // Immediate dominator
288 BasicBlockDataFlow* dataFlowInfo;
289 GrowableList* predecessors;
290 ArenaBitVector* dominators;
291 ArenaBitVector* iDominated; // Set nodes being immediately dominated
292 ArenaBitVector* domFrontier; // Dominance frontier
293 struct { // For one-to-many successors like
294 BlockListType blockListType; // switch and exception handling
295 GrowableList blocks;
296 } successorBlockList;
Elliott Hughes719ace42012-03-09 18:06:03 -0800297};
buzbee67bf8852011-08-17 17:51:35 -0700298
299/*
300 * The "blocks" field in "successorBlockList" points to an array of
301 * elements with the type "SuccessorBlockInfo".
302 * For catch blocks, key is type index for the exception.
303 * For swtich blocks, key is the case value.
304 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800305struct SuccessorBlockInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700306 BasicBlock* block;
307 int key;
Elliott Hughes719ace42012-03-09 18:06:03 -0800308};
buzbee67bf8852011-08-17 17:51:35 -0700309
310struct LoopAnalysis;
311struct RegisterPool;
buzbeeba938cb2012-02-03 14:47:55 -0800312struct ArenaMemBlock;
313struct Memstats;
buzbee67bf8852011-08-17 17:51:35 -0700314
Elliott Hughes719ace42012-03-09 18:06:03 -0800315enum AssemblerStatus {
Bill Buzbeea114add2012-05-03 15:00:40 -0700316 kSuccess,
317 kRetryAll,
318 kRetryHalve
Elliott Hughes719ace42012-03-09 18:06:03 -0800319};
buzbee67bf8852011-08-17 17:51:35 -0700320
buzbee5b537102012-01-17 17:33:47 -0800321#define NOTVISITED (-1)
322
Elliott Hughes719ace42012-03-09 18:06:03 -0800323struct CompilationUnit {
Elliott Hughese52e49b2012-04-02 16:05:44 -0700324 CompilationUnit()
Bill Buzbeea114add2012-05-03 15:00:40 -0700325 : numBlocks(0),
326 compiler(NULL),
327 class_linker(NULL),
328 dex_file(NULL),
329 dex_cache(NULL),
330 class_loader(NULL),
331 method_idx(0),
332 code_item(NULL),
333 access_flags(0),
334 shorty(NULL),
335 firstLIRInsn(NULL),
336 lastLIRInsn(NULL),
337 literalList(NULL),
338 methodLiteralList(NULL),
339 codeLiteralList(NULL),
340 classPointerList(NULL),
341 numClassPointers(0),
342 chainCellOffsetLIR(NULL),
343 disableOpt(0),
344 enableDebug(0),
345 headerSize(0),
346 dataOffset(0),
347 totalSize(0),
348 assemblerStatus(kSuccess),
349 assemblerRetries(0),
350 genDebugger(false),
351 printMe(false),
352 hasClassLiterals(false),
353 hasLoop(false),
354 hasInvoke(false),
355 heapMemOp(false),
356 qdMode(false),
357 usesLinkRegister(false),
358 methodTraceSupport(false),
359 regPool(NULL),
360 optRound(0),
361 instructionSet(kNone),
362 numSSARegs(0),
363 ssaBaseVRegs(NULL),
364 ssaSubscripts(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700365 ssaStrings(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700366 vRegToSSAMap(NULL),
367 SSALastDefs(NULL),
368 isConstantV(NULL),
369 constantValues(NULL),
370 phiAliasMap(NULL),
371 phiList(NULL),
372 regLocation(NULL),
373 sequenceNumber(0),
374 promotionMap(NULL),
375 methodSReg(0),
376 switchOverflowPad(NULL),
377 numReachableBlocks(0),
378 numDalvikRegisters(0),
379 entryBlock(NULL),
380 exitBlock(NULL),
381 curBlock(NULL),
382 nextCodegenBlock(NULL),
383 iDomList(NULL),
384 tryBlockAddr(NULL),
385 defBlockMatrix(NULL),
386 tempBlockV(NULL),
387 tempDalvikRegisterV(NULL),
388 tempSSARegisterV(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700389 tempSSABlockIdV(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700390 printSSANames(false),
391 blockLabelList(NULL),
392 quitLoopMode(false),
393 preservedRegsUsed(0),
394 numIns(0),
395 numOuts(0),
396 numRegs(0),
397 numCoreSpills(0),
398 numFPSpills(0),
399 numCompilerTemps(0),
400 frameSize(0),
401 coreSpillMask(0U),
402 fpSpillMask(0U),
403 attrs(0U),
404 currentDalvikOffset(0),
405 insns(NULL),
406 insnsSize(0U),
407 disableDataflow(false),
408 defCount(0),
409 compilerFlipMatch(false),
410 arenaHead(NULL),
411 currentArena(NULL),
412 numArenaBlocks(0),
413 mstats(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700414#if defined(ART_USE_QUICK_COMPILER)
415 genBitcode(false),
416 context(NULL),
417 module(NULL),
418 func(NULL),
419 intrinsic_helper(NULL),
420 irb(NULL),
421 placeholderBB(NULL),
422 entryBB(NULL),
buzbee4be777b2012-07-12 14:38:18 -0700423 entryTargetBB(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700424 tempName(0),
buzbeeb03f4872012-06-11 15:22:11 -0700425 requireShadowFrame(false),
426 numShadowFrameEntries(0),
427 shadowMap(NULL),
Elliott Hughese52e49b2012-04-02 16:05:44 -0700428#endif
buzbee2cfc6392012-05-07 14:51:40 -0700429#ifndef NDEBUG
430 liveSReg(0),
431#endif
432 opcodeCount(NULL) {}
Elliott Hughese52e49b2012-04-02 16:05:44 -0700433
Bill Buzbeea114add2012-05-03 15:00:40 -0700434 int numBlocks;
435 GrowableList blockList;
436 Compiler* compiler; // Compiler driving this compiler
437 ClassLinker* class_linker; // Linker to resolve fields and methods
438 const DexFile* dex_file; // DexFile containing the method being compiled
439 DexCache* dex_cache; // DexFile's corresponding cache
Ian Rogers365c1022012-06-22 15:05:28 -0700440 ClassLoader* class_loader; // compiling method's class loader
Bill Buzbeea114add2012-05-03 15:00:40 -0700441 uint32_t method_idx; // compiling method's index into method_ids of DexFile
442 const DexFile::CodeItem* code_item; // compiling method's DexFile code_item
443 uint32_t access_flags; // compiling method's access flags
444 const char* shorty; // compiling method's shorty
445 LIR* firstLIRInsn;
446 LIR* lastLIRInsn;
447 LIR* literalList; // Constants
448 LIR* methodLiteralList; // Method literals requiring patching
449 LIR* codeLiteralList; // Code literals requiring patching
450 LIR* classPointerList; // Relocatable
451 int numClassPointers;
452 LIR* chainCellOffsetLIR;
453 uint32_t disableOpt; // optControlVector flags
454 uint32_t enableDebug; // debugControlVector flags
455 int headerSize; // bytes before the first code ptr
456 int dataOffset; // starting offset of literal pool
457 int totalSize; // header + code size
458 AssemblerStatus assemblerStatus; // Success or fix and retry
459 int assemblerRetries;
460 std::vector<uint8_t> codeBuffer;
461 std::vector<uint32_t> mappingTable;
462 std::vector<uint16_t> coreVmapTable;
463 std::vector<uint16_t> fpVmapTable;
464 bool genDebugger; // Generate code for debugger
465 bool printMe;
466 bool hasClassLiterals; // Contains class ptrs used as literals
467 bool hasLoop; // Contains a loop
468 bool hasInvoke; // Contains an invoke instruction
469 bool heapMemOp; // Mark mem ops for self verification
470 bool qdMode; // Compile for code size/compile time
471 bool usesLinkRegister; // For self-verification only
472 bool methodTraceSupport; // For TraceView profiling
473 RegisterPool* regPool;
474 int optRound; // round number to tell an LIR's age
475 InstructionSet instructionSet;
476 /* Number of total regs used in the whole cUnit after SSA transformation */
477 int numSSARegs;
478 /* Map SSA reg i to the base virtual register/subscript */
479 GrowableList* ssaBaseVRegs;
480 GrowableList* ssaSubscripts;
buzbee2cfc6392012-05-07 14:51:40 -0700481 GrowableList* ssaStrings;
buzbee67bf8852011-08-17 17:51:35 -0700482
Bill Buzbeea114add2012-05-03 15:00:40 -0700483 /* The following are new data structures to support SSA representations */
484 /* Map original Dalvik virtual reg i to the current SSA name */
485 int* vRegToSSAMap; // length == method->registersSize
486 int* SSALastDefs; // length == method->registersSize
487 ArenaBitVector* isConstantV; // length == numSSAReg
488 int* constantValues; // length == numSSAReg
489 int* phiAliasMap; // length == numSSAReg
490 MIR* phiList;
buzbee67bf8852011-08-17 17:51:35 -0700491
Bill Buzbeea114add2012-05-03 15:00:40 -0700492 /* Use counts of ssa names */
493 GrowableList useCounts; // Weighted by nesting depth
494 GrowableList rawUseCounts; // Not weighted
buzbee239c4e72012-03-16 08:42:29 -0700495
Bill Buzbeea114add2012-05-03 15:00:40 -0700496 /* Optimization support */
497 GrowableList loopHeaders;
buzbee239c4e72012-03-16 08:42:29 -0700498
Bill Buzbeea114add2012-05-03 15:00:40 -0700499 /* Map SSA names to location */
500 RegLocation* regLocation;
501 int sequenceNumber;
buzbee67bf8852011-08-17 17:51:35 -0700502
Bill Buzbeea114add2012-05-03 15:00:40 -0700503 /* Keep track of Dalvik vReg to physical register mappings */
504 PromotionMap* promotionMap;
buzbee67bc2362011-10-11 18:08:40 -0700505
Bill Buzbeea114add2012-05-03 15:00:40 -0700506 /* SSA name for Method* */
507 int methodSReg;
buzbeead8f15e2012-06-18 14:49:45 -0700508 RegLocation methodLoc; // Describes location of method*
buzbeee1965672012-03-11 18:39:19 -0700509
Bill Buzbeea114add2012-05-03 15:00:40 -0700510 /*
511 * Set to the Dalvik PC of the switch instruction if it has more than
512 * MAX_CHAINED_SWITCH_CASES cases.
513 */
514 const u2* switchOverflowPad;
buzbee67bf8852011-08-17 17:51:35 -0700515
Bill Buzbeea114add2012-05-03 15:00:40 -0700516 int numReachableBlocks;
517 int numDalvikRegisters; // method->registersSize
518 BasicBlock* entryBlock;
519 BasicBlock* exitBlock;
520 BasicBlock* curBlock;
521 BasicBlock* nextCodegenBlock; // for extended trace codegen
522 GrowableList dfsOrder;
523 GrowableList dfsPostOrder;
524 GrowableList domPostOrderTraversal;
525 GrowableList throwLaunchpads;
526 GrowableList suspendLaunchpads;
527 GrowableList intrinsicLaunchpads;
528 GrowableList compilerTemps;
529 int* iDomList;
530 ArenaBitVector* tryBlockAddr;
531 ArenaBitVector** defBlockMatrix; // numDalvikRegister x numBlocks
532 ArenaBitVector* tempBlockV;
533 ArenaBitVector* tempDalvikRegisterV;
534 ArenaBitVector* tempSSARegisterV; // numSSARegs
buzbee2cfc6392012-05-07 14:51:40 -0700535 int* tempSSABlockIdV; // working storage for Phi labels
Bill Buzbeea114add2012-05-03 15:00:40 -0700536 bool printSSANames;
buzbeea1da8a52012-07-09 14:00:21 -0700537 LIR* blockLabelList;
Bill Buzbeea114add2012-05-03 15:00:40 -0700538 bool quitLoopMode; // cold path/complex bytecode
539 int preservedRegsUsed; // How many callee save regs used
540 /*
541 * Frame layout details.
542 * NOTE: for debug support it will be necessary to add a structure
543 * to map the Dalvik virtual registers to the promoted registers.
544 * NOTE: "num" fields are in 4-byte words, "Size" and "Offset" in bytes.
545 */
546 int numIns;
547 int numOuts;
548 int numRegs; // Unlike numDalvikRegisters, does not include ins
549 int numCoreSpills;
550 int numFPSpills;
551 int numCompilerTemps;
552 int frameSize;
553 unsigned int coreSpillMask;
554 unsigned int fpSpillMask;
555 unsigned int attrs;
556 /*
557 * CLEANUP/RESTRUCTURE: The code generation utilities don't have a built-in
558 * mechanism to propagate the original Dalvik opcode address to the
559 * associated generated instructions. For the trace compiler, this wasn't
560 * necessary because the interpreter handled all throws and debugging
561 * requests. For now we'll handle this by placing the Dalvik offset
562 * in the CompilationUnit struct before codegen for each instruction.
563 * The low-level LIR creation utilites will pull it from here. Should
564 * be rewritten.
565 */
566 int currentDalvikOffset;
567 GrowableList switchTables;
568 GrowableList fillArrayData;
569 const u2* insns;
570 u4 insnsSize;
571 bool disableDataflow; // Skip dataflow analysis if possible
572 SafeMap<unsigned int, BasicBlock*> blockMap; // findBlock lookup cache
573 SafeMap<unsigned int, LIR*> boundaryMap; // boundary lookup cache
574 int defCount; // Used to estimate number of SSA names
Elliott Hughese52e49b2012-04-02 16:05:44 -0700575
Bill Buzbeea114add2012-05-03 15:00:40 -0700576 // If non-empty, apply optimizer/debug flags only to matching methods.
577 std::string compilerMethodMatch;
578 // Flips sense of compilerMethodMatch - apply flags if doesn't match.
579 bool compilerFlipMatch;
580 ArenaMemBlock* arenaHead;
581 ArenaMemBlock* currentArena;
582 int numArenaBlocks;
583 Memstats* mstats;
buzbee2cfc6392012-05-07 14:51:40 -0700584#if defined(ART_USE_QUICK_COMPILER)
585 bool genBitcode;
586 llvm::LLVMContext* context;
587 llvm::Module* module;
588 llvm::Function* func;
589 greenland::IntrinsicHelper* intrinsic_helper;
590 greenland::IRBuilder* irb;
591 llvm::BasicBlock* placeholderBB;
592 llvm::BasicBlock* entryBB;
buzbee4be777b2012-07-12 14:38:18 -0700593 llvm::BasicBlock* entryTargetBB;
buzbee2cfc6392012-05-07 14:51:40 -0700594 std::string bitcode_filename;
595 GrowableList llvmValues;
596 int32_t tempName;
597 SafeMap<llvm::BasicBlock*, LIR*> blockToLabelMap; // llvm bb -> LIR label
598 SafeMap<int32_t, llvm::BasicBlock*> idToBlockMap; // block id -> llvm bb
599 SafeMap<llvm::Value*, RegLocation> locMap; // llvm Value to loc rec
buzbeeb03f4872012-06-11 15:22:11 -0700600 bool requireShadowFrame;
601 int numShadowFrameEntries;
602 int* shadowMap;
buzbee2cfc6392012-05-07 14:51:40 -0700603#endif
buzbee3d661942012-03-14 17:37:27 -0700604#ifndef NDEBUG
Bill Buzbeea114add2012-05-03 15:00:40 -0700605 /*
606 * Sanity checking for the register temp tracking. The same ssa
607 * name should never be associated with one temp register per
608 * instruction compilation.
609 */
610 int liveSReg;
buzbee3d661942012-03-14 17:37:27 -0700611#endif
buzbee2cfc6392012-05-07 14:51:40 -0700612 int* opcodeCount; // Count Dalvik opcodes for tuning
Elliott Hughes719ace42012-03-09 18:06:03 -0800613};
buzbee67bf8852011-08-17 17:51:35 -0700614
Elliott Hughes719ace42012-03-09 18:06:03 -0800615enum OpSize {
Bill Buzbeea114add2012-05-03 15:00:40 -0700616 kWord,
617 kLong,
618 kSingle,
619 kDouble,
620 kUnsignedHalf,
621 kSignedHalf,
622 kUnsignedByte,
623 kSignedByte,
Elliott Hughes719ace42012-03-09 18:06:03 -0800624};
buzbeee3acd072012-02-25 17:03:10 -0800625
Elliott Hughes719ace42012-03-09 18:06:03 -0800626enum OpKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700627 kOpMov,
628 kOpMvn,
629 kOpCmp,
630 kOpLsl,
631 kOpLsr,
632 kOpAsr,
633 kOpRor,
634 kOpNot,
635 kOpAnd,
636 kOpOr,
637 kOpXor,
638 kOpNeg,
639 kOpAdd,
640 kOpAdc,
641 kOpSub,
642 kOpSbc,
643 kOpRsub,
644 kOpMul,
645 kOpDiv,
646 kOpRem,
647 kOpBic,
648 kOpCmn,
649 kOpTst,
650 kOpBkpt,
651 kOpBlx,
652 kOpPush,
653 kOpPop,
654 kOp2Char,
655 kOp2Short,
656 kOp2Byte,
657 kOpCondBr,
658 kOpUncondBr,
659 kOpBx,
660 kOpInvalid,
Elliott Hughes719ace42012-03-09 18:06:03 -0800661};
buzbee31a4a6f2012-02-28 15:36:15 -0800662
Ian Rogers680b1bd2012-03-07 20:18:49 -0800663std::ostream& operator<<(std::ostream& os, const OpKind& kind);
664
Elliott Hughes719ace42012-03-09 18:06:03 -0800665enum ConditionCode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700666 kCondEq, // equal
667 kCondNe, // not equal
668 kCondCs, // carry set (unsigned less than)
669 kCondUlt = kCondCs,
670 kCondCc, // carry clear (unsigned greater than or same)
671 kCondUge = kCondCc,
672 kCondMi, // minus
673 kCondPl, // plus, positive or zero
674 kCondVs, // overflow
675 kCondVc, // no overflow
676 kCondHi, // unsigned greater than
677 kCondLs, // unsigned lower or same
678 kCondGe, // signed greater than or equal
679 kCondLt, // signed less than
680 kCondGt, // signed greater than
681 kCondLe, // signed less than or equal
682 kCondAl, // always
683 kCondNv, // never
Elliott Hughes719ace42012-03-09 18:06:03 -0800684};
buzbee31a4a6f2012-02-28 15:36:15 -0800685
Elliott Hughes719ace42012-03-09 18:06:03 -0800686enum ThrowKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700687 kThrowNullPointer,
688 kThrowDivZero,
689 kThrowArrayBounds,
690 kThrowVerificationError,
691 kThrowNoSuchMethod,
692 kThrowStackOverflow,
Elliott Hughes719ace42012-03-09 18:06:03 -0800693};
buzbee31a4a6f2012-02-28 15:36:15 -0800694
Elliott Hughes719ace42012-03-09 18:06:03 -0800695struct SwitchTable {
Bill Buzbeea114add2012-05-03 15:00:40 -0700696 int offset;
697 const u2* table; // Original dex table
698 int vaddr; // Dalvik offset of switch opcode
699 LIR* anchor; // Reference instruction for relative offsets
700 LIR** targets; // Array of case targets
Elliott Hughes719ace42012-03-09 18:06:03 -0800701};
buzbee5de34942012-03-01 14:51:57 -0800702
Elliott Hughes719ace42012-03-09 18:06:03 -0800703struct FillArrayData {
Bill Buzbeea114add2012-05-03 15:00:40 -0700704 int offset;
705 const u2* table; // Original dex table
706 int size;
707 int vaddr; // Dalvik offset of FILL_ARRAY_DATA opcode
Elliott Hughes719ace42012-03-09 18:06:03 -0800708};
buzbee5de34942012-03-01 14:51:57 -0800709
buzbee16da88c2012-03-20 10:38:17 -0700710#define MAX_PATTERN_LEN 5
711
712enum SpecialCaseHandler {
Bill Buzbeea114add2012-05-03 15:00:40 -0700713 kNoHandler,
714 kNullMethod,
715 kConstFunction,
716 kIGet,
717 kIGetBoolean,
718 kIGetObject,
719 kIGetByte,
720 kIGetChar,
721 kIGetShort,
722 kIGetWide,
723 kIPut,
724 kIPutBoolean,
725 kIPutObject,
726 kIPutByte,
727 kIPutChar,
728 kIPutShort,
729 kIPutWide,
730 kIdentity,
buzbee16da88c2012-03-20 10:38:17 -0700731};
732
733struct CodePattern {
Bill Buzbeea114add2012-05-03 15:00:40 -0700734 const Instruction::Code opcodes[MAX_PATTERN_LEN];
735 const SpecialCaseHandler handlerCode;
buzbee16da88c2012-03-20 10:38:17 -0700736};
737
738static const CodePattern specialPatterns[] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700739 {{Instruction::RETURN_VOID}, kNullMethod},
740 {{Instruction::CONST, Instruction::RETURN}, kConstFunction},
741 {{Instruction::CONST_4, Instruction::RETURN}, kConstFunction},
742 {{Instruction::CONST_4, Instruction::RETURN_OBJECT}, kConstFunction},
743 {{Instruction::CONST_16, Instruction::RETURN}, kConstFunction},
744 {{Instruction::IGET, Instruction:: RETURN}, kIGet},
745 {{Instruction::IGET_BOOLEAN, Instruction::RETURN}, kIGetBoolean},
746 {{Instruction::IGET_OBJECT, Instruction::RETURN_OBJECT}, kIGetObject},
747 {{Instruction::IGET_BYTE, Instruction::RETURN}, kIGetByte},
748 {{Instruction::IGET_CHAR, Instruction::RETURN}, kIGetChar},
749 {{Instruction::IGET_SHORT, Instruction::RETURN}, kIGetShort},
750 {{Instruction::IGET_WIDE, Instruction::RETURN_WIDE}, kIGetWide},
751 {{Instruction::IPUT, Instruction::RETURN_VOID}, kIPut},
752 {{Instruction::IPUT_BOOLEAN, Instruction::RETURN_VOID}, kIPutBoolean},
753 {{Instruction::IPUT_OBJECT, Instruction::RETURN_VOID}, kIPutObject},
754 {{Instruction::IPUT_BYTE, Instruction::RETURN_VOID}, kIPutByte},
755 {{Instruction::IPUT_CHAR, Instruction::RETURN_VOID}, kIPutChar},
756 {{Instruction::IPUT_SHORT, Instruction::RETURN_VOID}, kIPutShort},
757 {{Instruction::IPUT_WIDE, Instruction::RETURN_VOID}, kIPutWide},
758 {{Instruction::RETURN}, kIdentity},
759 {{Instruction::RETURN_OBJECT}, kIdentity},
760 {{Instruction::RETURN_WIDE}, kIdentity},
buzbee16da88c2012-03-20 10:38:17 -0700761};
buzbee5de34942012-03-01 14:51:57 -0800762
buzbee5abfa3e2012-01-31 17:01:43 -0800763BasicBlock* oatNewBB(CompilationUnit* cUnit, BBType blockType, int blockId);
buzbee67bf8852011-08-17 17:51:35 -0700764
765void oatAppendMIR(BasicBlock* bb, MIR* mir);
766
767void oatPrependMIR(BasicBlock* bb, MIR* mir);
768
769void oatInsertMIRAfter(BasicBlock* bb, MIR* currentMIR, MIR* newMIR);
770
771void oatAppendLIR(CompilationUnit* cUnit, LIR* lir);
772
773void oatInsertLIRBefore(LIR* currentLIR, LIR* newLIR);
774
775void oatInsertLIRAfter(LIR* currentLIR, LIR* newLIR);
776
buzbee15bf9802012-06-12 17:49:27 -0700777MIR* oatFindMoveResult(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir);
buzbee67bf8852011-08-17 17:51:35 -0700778/* Debug Utilities */
779void oatDumpCompilationUnit(CompilationUnit* cUnit);
780
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800781} // namespace art
782
buzbee67bf8852011-08-17 17:51:35 -0700783#endif // ART_SRC_COMPILER_COMPILER_IR_H_