blob: 914d2ab78e2de2a617f17efa48da4fdb5285e6df [file] [log] [blame]
buzbee67bf8852011-08-17 17:51:35 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_SRC_COMPILER_COMPILER_IR_H_
18#define ART_SRC_COMPILER_COMPILER_IR_H_
19
Elliott Hughesa0e18062012-04-13 15:59:59 -070020#include <vector>
21
buzbee67bf8852011-08-17 17:51:35 -070022#include "codegen/Optimizer.h"
Ian Rogers1bddec32012-02-04 12:27:34 -080023#include "CompilerUtility.h"
buzbee31a4a6f2012-02-28 15:36:15 -080024#include "oat_compilation_unit.h"
Elliott Hughesa0e18062012-04-13 15:59:59 -070025#include "safe_map.h"
buzbee2cfc6392012-05-07 14:51:40 -070026#if defined(ART_USE_QUICK_COMPILER)
27#include "greenland/ir_builder.h"
28#include "llvm/Module.h"
29#endif
buzbee67bf8852011-08-17 17:51:35 -070030
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080031namespace art {
32
buzbee31a4a6f2012-02-28 15:36:15 -080033#define SLOW_FIELD_PATH (cUnit->enableDebug & (1 << kDebugSlowFieldPath))
34#define SLOW_INVOKE_PATH (cUnit->enableDebug & (1 << kDebugSlowInvokePath))
35#define SLOW_STRING_PATH (cUnit->enableDebug & (1 << kDebugSlowStringPath))
36#define SLOW_TYPE_PATH (cUnit->enableDebug & (1 << kDebugSlowTypePath))
37#define EXERCISE_SLOWEST_FIELD_PATH (cUnit->enableDebug & \
Bill Buzbeea114add2012-05-03 15:00:40 -070038 (1 << kDebugSlowestFieldPath))
buzbee31a4a6f2012-02-28 15:36:15 -080039#define EXERCISE_SLOWEST_STRING_PATH (cUnit->enableDebug & \
Bill Buzbeea114add2012-05-03 15:00:40 -070040 (1 << kDebugSlowestStringPath))
buzbee31a4a6f2012-02-28 15:36:15 -080041#define EXERCISE_RESOLVE_METHOD (cUnit->enableDebug & \
Bill Buzbeea114add2012-05-03 15:00:40 -070042 (1 << kDebugExerciseResolveMethod))
buzbee31a4a6f2012-02-28 15:36:15 -080043
buzbeeca7a5e42012-08-20 11:12:18 -070044// Minimum field size to contain Dalvik vReg number
45#define VREG_NUM_WIDTH 16
46
Elliott Hughes719ace42012-03-09 18:06:03 -080047enum RegisterClass {
Bill Buzbeea114add2012-05-03 15:00:40 -070048 kCoreReg,
49 kFPReg,
50 kAnyReg,
Elliott Hughes719ace42012-03-09 18:06:03 -080051};
buzbee67bf8852011-08-17 17:51:35 -070052
Elliott Hughes719ace42012-03-09 18:06:03 -080053enum RegLocationType {
Bill Buzbeea114add2012-05-03 15:00:40 -070054 kLocDalvikFrame = 0, // Normal Dalvik register
55 kLocPhysReg,
56 kLocCompilerTemp,
57 kLocInvalid
Elliott Hughes719ace42012-03-09 18:06:03 -080058};
buzbee67bf8852011-08-17 17:51:35 -070059
Elliott Hughes719ace42012-03-09 18:06:03 -080060struct PromotionMap {
Bill Buzbeea114add2012-05-03 15:00:40 -070061 RegLocationType coreLocation:3;
62 u1 coreReg;
63 RegLocationType fpLocation:3;
64 u1 fpReg;
65 bool firstInPair;
Elliott Hughes719ace42012-03-09 18:06:03 -080066};
buzbee67bc2362011-10-11 18:08:40 -070067
Elliott Hughes719ace42012-03-09 18:06:03 -080068struct RegLocation {
Bill Buzbeea114add2012-05-03 15:00:40 -070069 RegLocationType location:3;
70 unsigned wide:1;
71 unsigned defined:1; // Do we know the type?
buzbee2cfc6392012-05-07 14:51:40 -070072 unsigned isConst:1; // Constant, value in cUnit->constantValues[]
Bill Buzbeea114add2012-05-03 15:00:40 -070073 unsigned fp:1; // Floating point?
74 unsigned core:1; // Non-floating point?
buzbeebff24652012-05-06 16:22:05 -070075 unsigned ref:1; // Something GC cares about
Bill Buzbeea114add2012-05-03 15:00:40 -070076 unsigned highWord:1; // High word of pair?
77 unsigned home:1; // Does this represent the home location?
78 u1 lowReg; // First physical register
79 u1 highReg; // 2nd physical register (if wide)
80 int32_t sRegLow; // SSA name for low Dalvik word
buzbee2cfc6392012-05-07 14:51:40 -070081 int32_t origSReg; // TODO: remove after Bitcode gen complete
82 // and consolodate usage w/ sRegLow
buzbeee1965672012-03-11 18:39:19 -070083};
84
85struct CompilerTemp {
Bill Buzbeea114add2012-05-03 15:00:40 -070086 int sReg;
87 ArenaBitVector* bv;
Elliott Hughes719ace42012-03-09 18:06:03 -080088};
buzbee67bf8852011-08-17 17:51:35 -070089
buzbee3b3dbdd2012-06-13 13:39:34 -070090struct CallInfo {
buzbee15bf9802012-06-12 17:49:27 -070091 int numArgWords; // Note: word count, not arg count
92 RegLocation* args; // One for each word of arguments
93 RegLocation result; // Eventual target of MOVE_RESULT
94 int optFlags;
95 InvokeType type;
96 uint32_t dexIdx;
buzbee3b3dbdd2012-06-13 13:39:34 -070097 uint32_t index; // Method idx for invokes, type idx for FilledNewArray
buzbee15bf9802012-06-12 17:49:27 -070098 uintptr_t directCode;
99 uintptr_t directMethod;
100 RegLocation target; // Target of following move_result
101 bool skipThis;
102 bool isRange;
103 int offset; // Dalvik offset
104};
105
buzbeee3acd072012-02-25 17:03:10 -0800106 /*
107 * Data structure tracking the mapping between a Dalvik register (pair) and a
108 * native register (pair). The idea is to reuse the previously loaded value
109 * if possible, otherwise to keep the value in a native register as long as
110 * possible.
111 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800112struct RegisterInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700113 int reg; // Reg number
114 bool inUse; // Has it been allocated?
115 bool isTemp; // Can allocate as temp?
116 bool pair; // Part of a register pair?
117 int partner; // If pair, other reg of pair
118 bool live; // Is there an associated SSA name?
119 bool dirty; // If live, is it dirty?
120 int sReg; // Name of live value
121 LIR *defStart; // Starting inst in last def sequence
122 LIR *defEnd; // Ending inst in last def sequence
Elliott Hughes719ace42012-03-09 18:06:03 -0800123};
buzbeee3acd072012-02-25 17:03:10 -0800124
Elliott Hughes719ace42012-03-09 18:06:03 -0800125struct RegisterPool {
Bill Buzbeea114add2012-05-03 15:00:40 -0700126 int numCoreRegs;
127 RegisterInfo *coreRegs;
128 int nextCoreReg;
129 int numFPRegs;
130 RegisterInfo *FPRegs;
131 int nextFPReg;
Elliott Hughes719ace42012-03-09 18:06:03 -0800132};
buzbeee3acd072012-02-25 17:03:10 -0800133
buzbee67bf8852011-08-17 17:51:35 -0700134#define INVALID_SREG (-1)
buzbee3ddc0d12011-10-05 10:36:21 -0700135#define INVALID_VREG (0xFFFFU)
buzbee67bc2362011-10-11 18:08:40 -0700136#define INVALID_REG (0xFF)
buzbee67bf8852011-08-17 17:51:35 -0700137#define INVALID_OFFSET (-1)
138
buzbeee1965672012-03-11 18:39:19 -0700139/* SSA encodings for special registers */
buzbee9c044ce2012-03-18 13:24:07 -0700140#define SSA_METHOD_BASEREG (-2)
buzbeee1965672012-03-11 18:39:19 -0700141/* First compiler temp basereg, grows smaller */
buzbee9c044ce2012-03-18 13:24:07 -0700142#define SSA_CTEMP_BASEREG (SSA_METHOD_BASEREG - 1)
buzbee2cfc6392012-05-07 14:51:40 -0700143/* Max SSA name length */
144#define SSA_NAME_MAX 16
buzbeee1965672012-03-11 18:39:19 -0700145
buzbee99ba9642012-01-25 14:23:14 -0800146/*
147 * Some code patterns cause the generation of excessively large
148 * methods - in particular initialization sequences. There isn't much
149 * benefit in optimizing these methods, and the cost can be very high.
150 * We attempt to identify these cases, and avoid performing most dataflow
151 * analysis. Two thresholds are used - one for known initializers and one
buzbee5abfa3e2012-01-31 17:01:43 -0800152 * for everything else.
buzbee99ba9642012-01-25 14:23:14 -0800153 */
buzbee5abfa3e2012-01-31 17:01:43 -0800154#define MANY_BLOCKS_INITIALIZER 1000 /* Threshold for switching dataflow off */
155#define MANY_BLOCKS 4000 /* Non-initializer threshold */
buzbee99ba9642012-01-25 14:23:14 -0800156
Elliott Hughes719ace42012-03-09 18:06:03 -0800157enum BBType {
Bill Buzbeea114add2012-05-03 15:00:40 -0700158 kEntryBlock,
159 kDalvikByteCode,
160 kExitBlock,
161 kExceptionHandling,
162 kCatchEntry,
Elliott Hughes719ace42012-03-09 18:06:03 -0800163};
buzbee67bf8852011-08-17 17:51:35 -0700164
buzbee31a4a6f2012-02-28 15:36:15 -0800165/* Utility macros to traverse the LIR list */
166#define NEXT_LIR(lir) (lir->next)
167#define PREV_LIR(lir) (lir->prev)
168
169#define NEXT_LIR_LVALUE(lir) (lir)->next
170#define PREV_LIR_LVALUE(lir) (lir)->prev
171
Elliott Hughes719ace42012-03-09 18:06:03 -0800172struct LIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700173 int offset; // Offset of this instruction
174 int dalvikOffset; // Offset of Dalvik opcode
175 LIR* next;
176 LIR* prev;
177 LIR* target;
178 int opcode;
179 int operands[5]; // [0..4] = [dest, src1, src2, extra, extra2]
180 struct {
181 bool isNop:1; // LIR is optimized away
182 bool pcRelFixup:1; // May need pc-relative fixup
183 unsigned int age:4; // default is 0, set lazily by the optimizer
184 unsigned int size:5; // in bytes
185 unsigned int unused:21;
186 } flags;
187 int aliasInfo; // For Dalvik register & litpool disambiguation
188 u8 useMask; // Resource mask for use
189 u8 defMask; // Resource mask for def
Elliott Hughes719ace42012-03-09 18:06:03 -0800190};
buzbee67bf8852011-08-17 17:51:35 -0700191
192enum ExtendedMIROpcode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700193 kMirOpFirst = kNumPackedOpcodes,
194 kMirOpPhi = kMirOpFirst,
195 kMirOpCopy,
196 kMirOpFusedCmplFloat,
197 kMirOpFusedCmpgFloat,
198 kMirOpFusedCmplDouble,
199 kMirOpFusedCmpgDouble,
200 kMirOpFusedCmpLong,
201 kMirOpNop,
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700202 kMirOpNullCheck,
203 kMirOpRangeCheck,
204 kMirOpDivZeroCheck,
205 kMirOpCheck,
Bill Buzbeea114add2012-05-03 15:00:40 -0700206 kMirOpLast,
buzbee67bf8852011-08-17 17:51:35 -0700207};
208
209struct SSARepresentation;
210
Elliott Hughes719ace42012-03-09 18:06:03 -0800211enum MIROptimizationFlagPositons {
Bill Buzbeea114add2012-05-03 15:00:40 -0700212 kMIRIgnoreNullCheck = 0,
213 kMIRNullCheckOnly,
214 kMIRIgnoreRangeCheck,
215 kMIRRangeCheckOnly,
216 kMIRInlined, // Invoke is inlined (ie dead)
217 kMIRInlinedPred, // Invoke is inlined via prediction
218 kMIRCallee, // Instruction is inlined from callee
219 kMIRIgnoreSuspendCheck,
220 kMIRDup,
221 kMIRMark, // Temporary node mark
Elliott Hughes719ace42012-03-09 18:06:03 -0800222};
buzbee67bf8852011-08-17 17:51:35 -0700223
224#define MIR_IGNORE_NULL_CHECK (1 << kMIRIgnoreNullCheck)
225#define MIR_NULL_CHECK_ONLY (1 << kMIRNullCheckOnly)
226#define MIR_IGNORE_RANGE_CHECK (1 << kMIRIgnoreRangeCheck)
227#define MIR_RANGE_CHECK_ONLY (1 << kMIRRangeCheckOnly)
228#define MIR_INLINED (1 << kMIRInlined)
229#define MIR_INLINED_PRED (1 << kMIRInlinedPred)
230#define MIR_CALLEE (1 << kMIRCallee)
buzbeec1f45042011-09-21 16:03:19 -0700231#define MIR_IGNORE_SUSPEND_CHECK (1 << kMIRIgnoreSuspendCheck)
buzbeee1965672012-03-11 18:39:19 -0700232#define MIR_DUP (1 << kMIRDup)
buzbee239c4e72012-03-16 08:42:29 -0700233#define MIR_MARK (1 << kMIRMark)
buzbee67bf8852011-08-17 17:51:35 -0700234
Elliott Hughes719ace42012-03-09 18:06:03 -0800235struct CallsiteInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700236 const char* classDescriptor;
237 Object* classLoader;
238 const Method* method;
239 LIR* misPredBranchOver;
Elliott Hughes719ace42012-03-09 18:06:03 -0800240};
buzbee67bf8852011-08-17 17:51:35 -0700241
Elliott Hughes719ace42012-03-09 18:06:03 -0800242struct MIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700243 DecodedInstruction dalvikInsn;
244 unsigned int width;
245 unsigned int offset;
246 MIR* prev;
247 MIR* next;
248 SSARepresentation* ssaRep;
249 int optimizationFlags;
250 int seqNum;
251 union {
Bill Buzbeea114add2012-05-03 15:00:40 -0700252 // Used to quickly locate all Phi opcodes
253 MIR* phiNext;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700254 // Establish link between two halves of throwing instructions
255 MIR* throwInsn;
Bill Buzbeea114add2012-05-03 15:00:40 -0700256 } meta;
Elliott Hughes719ace42012-03-09 18:06:03 -0800257};
buzbee67bf8852011-08-17 17:51:35 -0700258
259struct BasicBlockDataFlow;
260
261/* For successorBlockList */
Elliott Hughes719ace42012-03-09 18:06:03 -0800262enum BlockListType {
Bill Buzbeea114add2012-05-03 15:00:40 -0700263 kNotUsed = 0,
264 kCatch,
265 kPackedSwitch,
266 kSparseSwitch,
Elliott Hughes719ace42012-03-09 18:06:03 -0800267};
buzbee67bf8852011-08-17 17:51:35 -0700268
Elliott Hughes719ace42012-03-09 18:06:03 -0800269struct BasicBlock {
Bill Buzbeea114add2012-05-03 15:00:40 -0700270 int id;
271 int dfsId;
272 bool visited;
273 bool hidden;
274 bool catchEntry;
275 bool fallThroughTarget; // Reached via fallthrough
buzbee2cfc6392012-05-07 14:51:40 -0700276#if defined(ART_USE_QUICK_COMPILER)
277 bool hasReturn;
278#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700279 uint16_t startOffset;
280 uint16_t nestingDepth;
281 const Method* containingMethod; // For blocks from the callee
282 BBType blockType;
Bill Buzbeea114add2012-05-03 15:00:40 -0700283 bool isFallThroughFromInvoke; // True means the block needs alignment
284 MIR* firstMIRInsn;
285 MIR* lastMIRInsn;
286 BasicBlock* fallThrough;
287 BasicBlock* taken;
288 BasicBlock* iDom; // Immediate dominator
289 BasicBlockDataFlow* dataFlowInfo;
290 GrowableList* predecessors;
291 ArenaBitVector* dominators;
292 ArenaBitVector* iDominated; // Set nodes being immediately dominated
293 ArenaBitVector* domFrontier; // Dominance frontier
294 struct { // For one-to-many successors like
295 BlockListType blockListType; // switch and exception handling
296 GrowableList blocks;
297 } successorBlockList;
Elliott Hughes719ace42012-03-09 18:06:03 -0800298};
buzbee67bf8852011-08-17 17:51:35 -0700299
300/*
301 * The "blocks" field in "successorBlockList" points to an array of
302 * elements with the type "SuccessorBlockInfo".
303 * For catch blocks, key is type index for the exception.
304 * For swtich blocks, key is the case value.
305 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800306struct SuccessorBlockInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700307 BasicBlock* block;
308 int key;
Elliott Hughes719ace42012-03-09 18:06:03 -0800309};
buzbee67bf8852011-08-17 17:51:35 -0700310
311struct LoopAnalysis;
312struct RegisterPool;
buzbeeba938cb2012-02-03 14:47:55 -0800313struct ArenaMemBlock;
314struct Memstats;
buzbee67bf8852011-08-17 17:51:35 -0700315
Elliott Hughes719ace42012-03-09 18:06:03 -0800316enum AssemblerStatus {
Bill Buzbeea114add2012-05-03 15:00:40 -0700317 kSuccess,
318 kRetryAll,
319 kRetryHalve
Elliott Hughes719ace42012-03-09 18:06:03 -0800320};
buzbee67bf8852011-08-17 17:51:35 -0700321
buzbee5b537102012-01-17 17:33:47 -0800322#define NOTVISITED (-1)
323
Elliott Hughes719ace42012-03-09 18:06:03 -0800324struct CompilationUnit {
Elliott Hughese52e49b2012-04-02 16:05:44 -0700325 CompilationUnit()
Bill Buzbeea114add2012-05-03 15:00:40 -0700326 : numBlocks(0),
327 compiler(NULL),
328 class_linker(NULL),
329 dex_file(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700330 class_loader(NULL),
331 method_idx(0),
332 code_item(NULL),
333 access_flags(0),
Ian Rogers08f753d2012-08-24 14:35:25 -0700334 invoke_type(kDirect),
Bill Buzbeea114add2012-05-03 15:00:40 -0700335 shorty(NULL),
336 firstLIRInsn(NULL),
337 lastLIRInsn(NULL),
338 literalList(NULL),
339 methodLiteralList(NULL),
340 codeLiteralList(NULL),
341 classPointerList(NULL),
342 numClassPointers(0),
343 chainCellOffsetLIR(NULL),
344 disableOpt(0),
345 enableDebug(0),
346 headerSize(0),
347 dataOffset(0),
348 totalSize(0),
349 assemblerStatus(kSuccess),
350 assemblerRetries(0),
351 genDebugger(false),
352 printMe(false),
353 hasClassLiterals(false),
354 hasLoop(false),
355 hasInvoke(false),
356 heapMemOp(false),
357 qdMode(false),
358 usesLinkRegister(false),
359 methodTraceSupport(false),
360 regPool(NULL),
361 optRound(0),
362 instructionSet(kNone),
363 numSSARegs(0),
364 ssaBaseVRegs(NULL),
365 ssaSubscripts(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700366 ssaStrings(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700367 vRegToSSAMap(NULL),
368 SSALastDefs(NULL),
369 isConstantV(NULL),
370 constantValues(NULL),
371 phiAliasMap(NULL),
372 phiList(NULL),
373 regLocation(NULL),
374 sequenceNumber(0),
375 promotionMap(NULL),
376 methodSReg(0),
377 switchOverflowPad(NULL),
378 numReachableBlocks(0),
379 numDalvikRegisters(0),
380 entryBlock(NULL),
381 exitBlock(NULL),
382 curBlock(NULL),
383 nextCodegenBlock(NULL),
384 iDomList(NULL),
385 tryBlockAddr(NULL),
386 defBlockMatrix(NULL),
387 tempBlockV(NULL),
388 tempDalvikRegisterV(NULL),
389 tempSSARegisterV(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700390 tempSSABlockIdV(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700391 printSSANames(false),
392 blockLabelList(NULL),
393 quitLoopMode(false),
394 preservedRegsUsed(0),
395 numIns(0),
396 numOuts(0),
397 numRegs(0),
398 numCoreSpills(0),
399 numFPSpills(0),
400 numCompilerTemps(0),
401 frameSize(0),
402 coreSpillMask(0U),
403 fpSpillMask(0U),
404 attrs(0U),
405 currentDalvikOffset(0),
406 insns(NULL),
407 insnsSize(0U),
408 disableDataflow(false),
409 defCount(0),
410 compilerFlipMatch(false),
411 arenaHead(NULL),
412 currentArena(NULL),
413 numArenaBlocks(0),
414 mstats(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700415#if defined(ART_USE_QUICK_COMPILER)
416 genBitcode(false),
417 context(NULL),
418 module(NULL),
419 func(NULL),
420 intrinsic_helper(NULL),
421 irb(NULL),
422 placeholderBB(NULL),
423 entryBB(NULL),
buzbee4be777b2012-07-12 14:38:18 -0700424 entryTargetBB(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700425 tempName(0),
buzbeeb03f4872012-06-11 15:22:11 -0700426 requireShadowFrame(false),
427 numShadowFrameEntries(0),
428 shadowMap(NULL),
Elliott Hughese52e49b2012-04-02 16:05:44 -0700429#endif
buzbee2cfc6392012-05-07 14:51:40 -0700430#ifndef NDEBUG
431 liveSReg(0),
432#endif
433 opcodeCount(NULL) {}
Elliott Hughese52e49b2012-04-02 16:05:44 -0700434
Bill Buzbeea114add2012-05-03 15:00:40 -0700435 int numBlocks;
436 GrowableList blockList;
437 Compiler* compiler; // Compiler driving this compiler
438 ClassLinker* class_linker; // Linker to resolve fields and methods
439 const DexFile* dex_file; // DexFile containing the method being compiled
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700440 jobject 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
Ian Rogers08f753d2012-08-24 14:35:25 -0700444 InvokeType invoke_type; // compiling method's invocation type
Bill Buzbeea114add2012-05-03 15:00:40 -0700445 const char* shorty; // compiling method's shorty
446 LIR* firstLIRInsn;
447 LIR* lastLIRInsn;
448 LIR* literalList; // Constants
449 LIR* methodLiteralList; // Method literals requiring patching
450 LIR* codeLiteralList; // Code literals requiring patching
451 LIR* classPointerList; // Relocatable
452 int numClassPointers;
453 LIR* chainCellOffsetLIR;
454 uint32_t disableOpt; // optControlVector flags
455 uint32_t enableDebug; // debugControlVector flags
456 int headerSize; // bytes before the first code ptr
457 int dataOffset; // starting offset of literal pool
458 int totalSize; // header + code size
459 AssemblerStatus assemblerStatus; // Success or fix and retry
460 int assemblerRetries;
461 std::vector<uint8_t> codeBuffer;
462 std::vector<uint32_t> mappingTable;
buzbeeca7a5e42012-08-20 11:12:18 -0700463 std::vector<uint32_t> coreVmapTable;
464 std::vector<uint32_t> fpVmapTable;
Bill Buzbeea114add2012-05-03 15:00:40 -0700465 bool genDebugger; // Generate code for debugger
466 bool printMe;
467 bool hasClassLiterals; // Contains class ptrs used as literals
468 bool hasLoop; // Contains a loop
469 bool hasInvoke; // Contains an invoke instruction
470 bool heapMemOp; // Mark mem ops for self verification
471 bool qdMode; // Compile for code size/compile time
472 bool usesLinkRegister; // For self-verification only
473 bool methodTraceSupport; // For TraceView profiling
474 RegisterPool* regPool;
475 int optRound; // round number to tell an LIR's age
476 InstructionSet instructionSet;
477 /* Number of total regs used in the whole cUnit after SSA transformation */
478 int numSSARegs;
479 /* Map SSA reg i to the base virtual register/subscript */
480 GrowableList* ssaBaseVRegs;
481 GrowableList* ssaSubscripts;
buzbee2cfc6392012-05-07 14:51:40 -0700482 GrowableList* ssaStrings;
buzbee67bf8852011-08-17 17:51:35 -0700483
Bill Buzbeea114add2012-05-03 15:00:40 -0700484 /* The following are new data structures to support SSA representations */
485 /* Map original Dalvik virtual reg i to the current SSA name */
486 int* vRegToSSAMap; // length == method->registersSize
487 int* SSALastDefs; // length == method->registersSize
488 ArenaBitVector* isConstantV; // length == numSSAReg
489 int* constantValues; // length == numSSAReg
490 int* phiAliasMap; // length == numSSAReg
491 MIR* phiList;
buzbee67bf8852011-08-17 17:51:35 -0700492
Bill Buzbeea114add2012-05-03 15:00:40 -0700493 /* Use counts of ssa names */
494 GrowableList useCounts; // Weighted by nesting depth
495 GrowableList rawUseCounts; // Not weighted
buzbee239c4e72012-03-16 08:42:29 -0700496
Bill Buzbeea114add2012-05-03 15:00:40 -0700497 /* Optimization support */
498 GrowableList loopHeaders;
buzbee239c4e72012-03-16 08:42:29 -0700499
Bill Buzbeea114add2012-05-03 15:00:40 -0700500 /* Map SSA names to location */
501 RegLocation* regLocation;
502 int sequenceNumber;
buzbee67bf8852011-08-17 17:51:35 -0700503
Bill Buzbeea114add2012-05-03 15:00:40 -0700504 /* Keep track of Dalvik vReg to physical register mappings */
505 PromotionMap* promotionMap;
buzbee67bc2362011-10-11 18:08:40 -0700506
Bill Buzbeea114add2012-05-03 15:00:40 -0700507 /* SSA name for Method* */
508 int methodSReg;
buzbeead8f15e2012-06-18 14:49:45 -0700509 RegLocation methodLoc; // Describes location of method*
buzbeee1965672012-03-11 18:39:19 -0700510
Bill Buzbeea114add2012-05-03 15:00:40 -0700511 /*
512 * Set to the Dalvik PC of the switch instruction if it has more than
513 * MAX_CHAINED_SWITCH_CASES cases.
514 */
515 const u2* switchOverflowPad;
buzbee67bf8852011-08-17 17:51:35 -0700516
Bill Buzbeea114add2012-05-03 15:00:40 -0700517 int numReachableBlocks;
518 int numDalvikRegisters; // method->registersSize
519 BasicBlock* entryBlock;
520 BasicBlock* exitBlock;
521 BasicBlock* curBlock;
522 BasicBlock* nextCodegenBlock; // for extended trace codegen
523 GrowableList dfsOrder;
524 GrowableList dfsPostOrder;
525 GrowableList domPostOrderTraversal;
526 GrowableList throwLaunchpads;
527 GrowableList suspendLaunchpads;
528 GrowableList intrinsicLaunchpads;
529 GrowableList compilerTemps;
530 int* iDomList;
531 ArenaBitVector* tryBlockAddr;
532 ArenaBitVector** defBlockMatrix; // numDalvikRegister x numBlocks
533 ArenaBitVector* tempBlockV;
534 ArenaBitVector* tempDalvikRegisterV;
535 ArenaBitVector* tempSSARegisterV; // numSSARegs
buzbee2cfc6392012-05-07 14:51:40 -0700536 int* tempSSABlockIdV; // working storage for Phi labels
Bill Buzbeea114add2012-05-03 15:00:40 -0700537 bool printSSANames;
buzbeea1da8a52012-07-09 14:00:21 -0700538 LIR* blockLabelList;
Bill Buzbeea114add2012-05-03 15:00:40 -0700539 bool quitLoopMode; // cold path/complex bytecode
540 int preservedRegsUsed; // How many callee save regs used
541 /*
542 * Frame layout details.
543 * NOTE: for debug support it will be necessary to add a structure
544 * to map the Dalvik virtual registers to the promoted registers.
545 * NOTE: "num" fields are in 4-byte words, "Size" and "Offset" in bytes.
546 */
547 int numIns;
548 int numOuts;
549 int numRegs; // Unlike numDalvikRegisters, does not include ins
550 int numCoreSpills;
551 int numFPSpills;
552 int numCompilerTemps;
553 int frameSize;
554 unsigned int coreSpillMask;
555 unsigned int fpSpillMask;
556 unsigned int attrs;
557 /*
558 * CLEANUP/RESTRUCTURE: The code generation utilities don't have a built-in
559 * mechanism to propagate the original Dalvik opcode address to the
560 * associated generated instructions. For the trace compiler, this wasn't
561 * necessary because the interpreter handled all throws and debugging
562 * requests. For now we'll handle this by placing the Dalvik offset
563 * in the CompilationUnit struct before codegen for each instruction.
564 * The low-level LIR creation utilites will pull it from here. Should
565 * be rewritten.
566 */
567 int currentDalvikOffset;
568 GrowableList switchTables;
569 GrowableList fillArrayData;
570 const u2* insns;
571 u4 insnsSize;
572 bool disableDataflow; // Skip dataflow analysis if possible
573 SafeMap<unsigned int, BasicBlock*> blockMap; // findBlock lookup cache
574 SafeMap<unsigned int, LIR*> boundaryMap; // boundary lookup cache
575 int defCount; // Used to estimate number of SSA names
Elliott Hughese52e49b2012-04-02 16:05:44 -0700576
Bill Buzbeea114add2012-05-03 15:00:40 -0700577 // If non-empty, apply optimizer/debug flags only to matching methods.
578 std::string compilerMethodMatch;
579 // Flips sense of compilerMethodMatch - apply flags if doesn't match.
580 bool compilerFlipMatch;
581 ArenaMemBlock* arenaHead;
582 ArenaMemBlock* currentArena;
583 int numArenaBlocks;
584 Memstats* mstats;
buzbee2cfc6392012-05-07 14:51:40 -0700585#if defined(ART_USE_QUICK_COMPILER)
586 bool genBitcode;
587 llvm::LLVMContext* context;
588 llvm::Module* module;
589 llvm::Function* func;
590 greenland::IntrinsicHelper* intrinsic_helper;
591 greenland::IRBuilder* irb;
592 llvm::BasicBlock* placeholderBB;
593 llvm::BasicBlock* entryBB;
buzbee4be777b2012-07-12 14:38:18 -0700594 llvm::BasicBlock* entryTargetBB;
buzbee2cfc6392012-05-07 14:51:40 -0700595 std::string bitcode_filename;
596 GrowableList llvmValues;
597 int32_t tempName;
598 SafeMap<llvm::BasicBlock*, LIR*> blockToLabelMap; // llvm bb -> LIR label
599 SafeMap<int32_t, llvm::BasicBlock*> idToBlockMap; // block id -> llvm bb
600 SafeMap<llvm::Value*, RegLocation> locMap; // llvm Value to loc rec
buzbeeb03f4872012-06-11 15:22:11 -0700601 bool requireShadowFrame;
602 int numShadowFrameEntries;
603 int* shadowMap;
buzbee2cfc6392012-05-07 14:51:40 -0700604#endif
buzbee3d661942012-03-14 17:37:27 -0700605#ifndef NDEBUG
Bill Buzbeea114add2012-05-03 15:00:40 -0700606 /*
607 * Sanity checking for the register temp tracking. The same ssa
608 * name should never be associated with one temp register per
609 * instruction compilation.
610 */
611 int liveSReg;
buzbee3d661942012-03-14 17:37:27 -0700612#endif
buzbee2cfc6392012-05-07 14:51:40 -0700613 int* opcodeCount; // Count Dalvik opcodes for tuning
Elliott Hughes719ace42012-03-09 18:06:03 -0800614};
buzbee67bf8852011-08-17 17:51:35 -0700615
Elliott Hughes719ace42012-03-09 18:06:03 -0800616enum OpSize {
Bill Buzbeea114add2012-05-03 15:00:40 -0700617 kWord,
618 kLong,
619 kSingle,
620 kDouble,
621 kUnsignedHalf,
622 kSignedHalf,
623 kUnsignedByte,
624 kSignedByte,
Elliott Hughes719ace42012-03-09 18:06:03 -0800625};
buzbeee3acd072012-02-25 17:03:10 -0800626
Elliott Hughes719ace42012-03-09 18:06:03 -0800627enum OpKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700628 kOpMov,
629 kOpMvn,
630 kOpCmp,
631 kOpLsl,
632 kOpLsr,
633 kOpAsr,
634 kOpRor,
635 kOpNot,
636 kOpAnd,
637 kOpOr,
638 kOpXor,
639 kOpNeg,
640 kOpAdd,
641 kOpAdc,
642 kOpSub,
643 kOpSbc,
644 kOpRsub,
645 kOpMul,
646 kOpDiv,
647 kOpRem,
648 kOpBic,
649 kOpCmn,
650 kOpTst,
651 kOpBkpt,
652 kOpBlx,
653 kOpPush,
654 kOpPop,
655 kOp2Char,
656 kOp2Short,
657 kOp2Byte,
658 kOpCondBr,
659 kOpUncondBr,
660 kOpBx,
661 kOpInvalid,
Elliott Hughes719ace42012-03-09 18:06:03 -0800662};
buzbee31a4a6f2012-02-28 15:36:15 -0800663
Ian Rogers680b1bd2012-03-07 20:18:49 -0800664std::ostream& operator<<(std::ostream& os, const OpKind& kind);
665
Elliott Hughes719ace42012-03-09 18:06:03 -0800666enum ConditionCode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700667 kCondEq, // equal
668 kCondNe, // not equal
669 kCondCs, // carry set (unsigned less than)
670 kCondUlt = kCondCs,
671 kCondCc, // carry clear (unsigned greater than or same)
672 kCondUge = kCondCc,
673 kCondMi, // minus
674 kCondPl, // plus, positive or zero
675 kCondVs, // overflow
676 kCondVc, // no overflow
677 kCondHi, // unsigned greater than
678 kCondLs, // unsigned lower or same
679 kCondGe, // signed greater than or equal
680 kCondLt, // signed less than
681 kCondGt, // signed greater than
682 kCondLe, // signed less than or equal
683 kCondAl, // always
684 kCondNv, // never
Elliott Hughes719ace42012-03-09 18:06:03 -0800685};
buzbee31a4a6f2012-02-28 15:36:15 -0800686
Elliott Hughes719ace42012-03-09 18:06:03 -0800687enum ThrowKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700688 kThrowNullPointer,
689 kThrowDivZero,
690 kThrowArrayBounds,
691 kThrowVerificationError,
692 kThrowNoSuchMethod,
693 kThrowStackOverflow,
Elliott Hughes719ace42012-03-09 18:06:03 -0800694};
buzbee31a4a6f2012-02-28 15:36:15 -0800695
Elliott Hughes719ace42012-03-09 18:06:03 -0800696struct SwitchTable {
Bill Buzbeea114add2012-05-03 15:00:40 -0700697 int offset;
698 const u2* table; // Original dex table
699 int vaddr; // Dalvik offset of switch opcode
700 LIR* anchor; // Reference instruction for relative offsets
701 LIR** targets; // Array of case targets
Elliott Hughes719ace42012-03-09 18:06:03 -0800702};
buzbee5de34942012-03-01 14:51:57 -0800703
Elliott Hughes719ace42012-03-09 18:06:03 -0800704struct FillArrayData {
Bill Buzbeea114add2012-05-03 15:00:40 -0700705 int offset;
706 const u2* table; // Original dex table
707 int size;
708 int vaddr; // Dalvik offset of FILL_ARRAY_DATA opcode
Elliott Hughes719ace42012-03-09 18:06:03 -0800709};
buzbee5de34942012-03-01 14:51:57 -0800710
buzbee16da88c2012-03-20 10:38:17 -0700711#define MAX_PATTERN_LEN 5
712
713enum SpecialCaseHandler {
Bill Buzbeea114add2012-05-03 15:00:40 -0700714 kNoHandler,
715 kNullMethod,
716 kConstFunction,
717 kIGet,
718 kIGetBoolean,
719 kIGetObject,
720 kIGetByte,
721 kIGetChar,
722 kIGetShort,
723 kIGetWide,
724 kIPut,
725 kIPutBoolean,
726 kIPutObject,
727 kIPutByte,
728 kIPutChar,
729 kIPutShort,
730 kIPutWide,
731 kIdentity,
buzbee16da88c2012-03-20 10:38:17 -0700732};
733
734struct CodePattern {
Bill Buzbeea114add2012-05-03 15:00:40 -0700735 const Instruction::Code opcodes[MAX_PATTERN_LEN];
736 const SpecialCaseHandler handlerCode;
buzbee16da88c2012-03-20 10:38:17 -0700737};
738
739static const CodePattern specialPatterns[] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700740 {{Instruction::RETURN_VOID}, kNullMethod},
741 {{Instruction::CONST, Instruction::RETURN}, kConstFunction},
742 {{Instruction::CONST_4, Instruction::RETURN}, kConstFunction},
743 {{Instruction::CONST_4, Instruction::RETURN_OBJECT}, kConstFunction},
744 {{Instruction::CONST_16, Instruction::RETURN}, kConstFunction},
745 {{Instruction::IGET, Instruction:: RETURN}, kIGet},
746 {{Instruction::IGET_BOOLEAN, Instruction::RETURN}, kIGetBoolean},
747 {{Instruction::IGET_OBJECT, Instruction::RETURN_OBJECT}, kIGetObject},
748 {{Instruction::IGET_BYTE, Instruction::RETURN}, kIGetByte},
749 {{Instruction::IGET_CHAR, Instruction::RETURN}, kIGetChar},
750 {{Instruction::IGET_SHORT, Instruction::RETURN}, kIGetShort},
751 {{Instruction::IGET_WIDE, Instruction::RETURN_WIDE}, kIGetWide},
752 {{Instruction::IPUT, Instruction::RETURN_VOID}, kIPut},
753 {{Instruction::IPUT_BOOLEAN, Instruction::RETURN_VOID}, kIPutBoolean},
754 {{Instruction::IPUT_OBJECT, Instruction::RETURN_VOID}, kIPutObject},
755 {{Instruction::IPUT_BYTE, Instruction::RETURN_VOID}, kIPutByte},
756 {{Instruction::IPUT_CHAR, Instruction::RETURN_VOID}, kIPutChar},
757 {{Instruction::IPUT_SHORT, Instruction::RETURN_VOID}, kIPutShort},
758 {{Instruction::IPUT_WIDE, Instruction::RETURN_VOID}, kIPutWide},
759 {{Instruction::RETURN}, kIdentity},
760 {{Instruction::RETURN_OBJECT}, kIdentity},
761 {{Instruction::RETURN_WIDE}, kIdentity},
buzbee16da88c2012-03-20 10:38:17 -0700762};
buzbee5de34942012-03-01 14:51:57 -0800763
buzbee5abfa3e2012-01-31 17:01:43 -0800764BasicBlock* oatNewBB(CompilationUnit* cUnit, BBType blockType, int blockId);
buzbee67bf8852011-08-17 17:51:35 -0700765
766void oatAppendMIR(BasicBlock* bb, MIR* mir);
767
768void oatPrependMIR(BasicBlock* bb, MIR* mir);
769
770void oatInsertMIRAfter(BasicBlock* bb, MIR* currentMIR, MIR* newMIR);
771
772void oatAppendLIR(CompilationUnit* cUnit, LIR* lir);
773
774void oatInsertLIRBefore(LIR* currentLIR, LIR* newLIR);
775
776void oatInsertLIRAfter(LIR* currentLIR, LIR* newLIR);
777
buzbee15bf9802012-06-12 17:49:27 -0700778MIR* oatFindMoveResult(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir);
buzbee67bf8852011-08-17 17:51:35 -0700779/* Debug Utilities */
780void oatDumpCompilationUnit(CompilationUnit* cUnit);
781
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800782} // namespace art
783
buzbee67bf8852011-08-17 17:51:35 -0700784#endif // ART_SRC_COMPILER_COMPILER_IR_H_