blob: 56ae4867c3b82010277a5e8ae9d29d43f7b2b118 [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))
buzbee31a4a6f2012-02-28 15:36:15 -080037#define EXERCISE_SLOWEST_STRING_PATH (cUnit->enableDebug & \
Bill Buzbeea114add2012-05-03 15:00:40 -070038 (1 << kDebugSlowestStringPath))
buzbee31a4a6f2012-02-28 15:36:15 -080039
buzbeeca7a5e42012-08-20 11:12:18 -070040// Minimum field size to contain Dalvik vReg number
41#define VREG_NUM_WIDTH 16
42
Elliott Hughes719ace42012-03-09 18:06:03 -080043enum RegisterClass {
Bill Buzbeea114add2012-05-03 15:00:40 -070044 kCoreReg,
45 kFPReg,
46 kAnyReg,
Elliott Hughes719ace42012-03-09 18:06:03 -080047};
buzbee67bf8852011-08-17 17:51:35 -070048
Elliott Hughes719ace42012-03-09 18:06:03 -080049enum RegLocationType {
Bill Buzbeea114add2012-05-03 15:00:40 -070050 kLocDalvikFrame = 0, // Normal Dalvik register
51 kLocPhysReg,
52 kLocCompilerTemp,
53 kLocInvalid
Elliott Hughes719ace42012-03-09 18:06:03 -080054};
buzbee67bf8852011-08-17 17:51:35 -070055
Elliott Hughes719ace42012-03-09 18:06:03 -080056struct PromotionMap {
Bill Buzbeea114add2012-05-03 15:00:40 -070057 RegLocationType coreLocation:3;
58 u1 coreReg;
59 RegLocationType fpLocation:3;
60 u1 fpReg;
61 bool firstInPair;
Elliott Hughes719ace42012-03-09 18:06:03 -080062};
buzbee67bc2362011-10-11 18:08:40 -070063
Elliott Hughes719ace42012-03-09 18:06:03 -080064struct RegLocation {
Bill Buzbeea114add2012-05-03 15:00:40 -070065 RegLocationType location:3;
66 unsigned wide:1;
67 unsigned defined:1; // Do we know the type?
buzbee2cfc6392012-05-07 14:51:40 -070068 unsigned isConst:1; // Constant, value in cUnit->constantValues[]
Bill Buzbeea114add2012-05-03 15:00:40 -070069 unsigned fp:1; // Floating point?
70 unsigned core:1; // Non-floating point?
buzbeebff24652012-05-06 16:22:05 -070071 unsigned ref:1; // Something GC cares about
Bill Buzbeea114add2012-05-03 15:00:40 -070072 unsigned highWord:1; // High word of pair?
73 unsigned home:1; // Does this represent the home location?
74 u1 lowReg; // First physical register
75 u1 highReg; // 2nd physical register (if wide)
76 int32_t sRegLow; // SSA name for low Dalvik word
buzbee2cfc6392012-05-07 14:51:40 -070077 int32_t origSReg; // TODO: remove after Bitcode gen complete
78 // and consolodate usage w/ sRegLow
buzbeee1965672012-03-11 18:39:19 -070079};
80
81struct CompilerTemp {
Bill Buzbeea114add2012-05-03 15:00:40 -070082 int sReg;
83 ArenaBitVector* bv;
Elliott Hughes719ace42012-03-09 18:06:03 -080084};
buzbee67bf8852011-08-17 17:51:35 -070085
buzbee3b3dbdd2012-06-13 13:39:34 -070086struct CallInfo {
buzbee15bf9802012-06-12 17:49:27 -070087 int numArgWords; // Note: word count, not arg count
88 RegLocation* args; // One for each word of arguments
89 RegLocation result; // Eventual target of MOVE_RESULT
90 int optFlags;
91 InvokeType type;
92 uint32_t dexIdx;
buzbee3b3dbdd2012-06-13 13:39:34 -070093 uint32_t index; // Method idx for invokes, type idx for FilledNewArray
buzbee15bf9802012-06-12 17:49:27 -070094 uintptr_t directCode;
95 uintptr_t directMethod;
96 RegLocation target; // Target of following move_result
97 bool skipThis;
98 bool isRange;
99 int offset; // Dalvik offset
100};
101
buzbeee3acd072012-02-25 17:03:10 -0800102 /*
103 * Data structure tracking the mapping between a Dalvik register (pair) and a
104 * native register (pair). The idea is to reuse the previously loaded value
105 * if possible, otherwise to keep the value in a native register as long as
106 * possible.
107 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800108struct RegisterInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700109 int reg; // Reg number
110 bool inUse; // Has it been allocated?
111 bool isTemp; // Can allocate as temp?
112 bool pair; // Part of a register pair?
113 int partner; // If pair, other reg of pair
114 bool live; // Is there an associated SSA name?
115 bool dirty; // If live, is it dirty?
116 int sReg; // Name of live value
117 LIR *defStart; // Starting inst in last def sequence
118 LIR *defEnd; // Ending inst in last def sequence
Elliott Hughes719ace42012-03-09 18:06:03 -0800119};
buzbeee3acd072012-02-25 17:03:10 -0800120
Elliott Hughes719ace42012-03-09 18:06:03 -0800121struct RegisterPool {
Bill Buzbeea114add2012-05-03 15:00:40 -0700122 int numCoreRegs;
123 RegisterInfo *coreRegs;
124 int nextCoreReg;
125 int numFPRegs;
126 RegisterInfo *FPRegs;
127 int nextFPReg;
Elliott Hughes719ace42012-03-09 18:06:03 -0800128};
buzbeee3acd072012-02-25 17:03:10 -0800129
buzbee67bf8852011-08-17 17:51:35 -0700130#define INVALID_SREG (-1)
buzbee3ddc0d12011-10-05 10:36:21 -0700131#define INVALID_VREG (0xFFFFU)
buzbee67bc2362011-10-11 18:08:40 -0700132#define INVALID_REG (0xFF)
buzbee67bf8852011-08-17 17:51:35 -0700133
buzbeee1965672012-03-11 18:39:19 -0700134/* SSA encodings for special registers */
buzbee9c044ce2012-03-18 13:24:07 -0700135#define SSA_METHOD_BASEREG (-2)
buzbeee1965672012-03-11 18:39:19 -0700136/* First compiler temp basereg, grows smaller */
buzbee9c044ce2012-03-18 13:24:07 -0700137#define SSA_CTEMP_BASEREG (SSA_METHOD_BASEREG - 1)
buzbeee1965672012-03-11 18:39:19 -0700138
buzbee99ba9642012-01-25 14:23:14 -0800139/*
140 * Some code patterns cause the generation of excessively large
141 * methods - in particular initialization sequences. There isn't much
142 * benefit in optimizing these methods, and the cost can be very high.
143 * We attempt to identify these cases, and avoid performing most dataflow
144 * analysis. Two thresholds are used - one for known initializers and one
buzbee5abfa3e2012-01-31 17:01:43 -0800145 * for everything else.
buzbee99ba9642012-01-25 14:23:14 -0800146 */
buzbee5abfa3e2012-01-31 17:01:43 -0800147#define MANY_BLOCKS_INITIALIZER 1000 /* Threshold for switching dataflow off */
148#define MANY_BLOCKS 4000 /* Non-initializer threshold */
buzbee99ba9642012-01-25 14:23:14 -0800149
Elliott Hughes719ace42012-03-09 18:06:03 -0800150enum BBType {
Bill Buzbeea114add2012-05-03 15:00:40 -0700151 kEntryBlock,
152 kDalvikByteCode,
153 kExitBlock,
154 kExceptionHandling,
buzbeed1643e42012-09-05 14:06:51 -0700155 kDead,
Elliott Hughes719ace42012-03-09 18:06:03 -0800156};
buzbee67bf8852011-08-17 17:51:35 -0700157
buzbee31a4a6f2012-02-28 15:36:15 -0800158/* Utility macros to traverse the LIR list */
159#define NEXT_LIR(lir) (lir->next)
160#define PREV_LIR(lir) (lir->prev)
161
Elliott Hughes719ace42012-03-09 18:06:03 -0800162struct LIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700163 int offset; // Offset of this instruction
164 int dalvikOffset; // Offset of Dalvik opcode
165 LIR* next;
166 LIR* prev;
167 LIR* target;
168 int opcode;
169 int operands[5]; // [0..4] = [dest, src1, src2, extra, extra2]
170 struct {
171 bool isNop:1; // LIR is optimized away
172 bool pcRelFixup:1; // May need pc-relative fixup
Bill Buzbeea114add2012-05-03 15:00:40 -0700173 unsigned int size:5; // in bytes
buzbeef5f5a122012-09-21 13:57:36 -0700174 unsigned int unused:25;
Bill Buzbeea114add2012-05-03 15:00:40 -0700175 } flags;
176 int aliasInfo; // For Dalvik register & litpool disambiguation
177 u8 useMask; // Resource mask for use
178 u8 defMask; // Resource mask for def
Elliott Hughes719ace42012-03-09 18:06:03 -0800179};
buzbee67bf8852011-08-17 17:51:35 -0700180
181enum ExtendedMIROpcode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700182 kMirOpFirst = kNumPackedOpcodes,
183 kMirOpPhi = kMirOpFirst,
184 kMirOpCopy,
185 kMirOpFusedCmplFloat,
186 kMirOpFusedCmpgFloat,
187 kMirOpFusedCmplDouble,
188 kMirOpFusedCmpgDouble,
189 kMirOpFusedCmpLong,
190 kMirOpNop,
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700191 kMirOpNullCheck,
192 kMirOpRangeCheck,
193 kMirOpDivZeroCheck,
194 kMirOpCheck,
Bill Buzbeea114add2012-05-03 15:00:40 -0700195 kMirOpLast,
buzbee67bf8852011-08-17 17:51:35 -0700196};
197
198struct SSARepresentation;
199
Elliott Hughes719ace42012-03-09 18:06:03 -0800200enum MIROptimizationFlagPositons {
Bill Buzbeea114add2012-05-03 15:00:40 -0700201 kMIRIgnoreNullCheck = 0,
202 kMIRNullCheckOnly,
203 kMIRIgnoreRangeCheck,
204 kMIRRangeCheckOnly,
205 kMIRInlined, // Invoke is inlined (ie dead)
206 kMIRInlinedPred, // Invoke is inlined via prediction
207 kMIRCallee, // Instruction is inlined from callee
208 kMIRIgnoreSuspendCheck,
209 kMIRDup,
210 kMIRMark, // Temporary node mark
Elliott Hughes719ace42012-03-09 18:06:03 -0800211};
buzbee67bf8852011-08-17 17:51:35 -0700212
213#define MIR_IGNORE_NULL_CHECK (1 << kMIRIgnoreNullCheck)
214#define MIR_NULL_CHECK_ONLY (1 << kMIRNullCheckOnly)
215#define MIR_IGNORE_RANGE_CHECK (1 << kMIRIgnoreRangeCheck)
216#define MIR_RANGE_CHECK_ONLY (1 << kMIRRangeCheckOnly)
217#define MIR_INLINED (1 << kMIRInlined)
218#define MIR_INLINED_PRED (1 << kMIRInlinedPred)
219#define MIR_CALLEE (1 << kMIRCallee)
buzbeec1f45042011-09-21 16:03:19 -0700220#define MIR_IGNORE_SUSPEND_CHECK (1 << kMIRIgnoreSuspendCheck)
buzbeee1965672012-03-11 18:39:19 -0700221#define MIR_DUP (1 << kMIRDup)
buzbee239c4e72012-03-16 08:42:29 -0700222#define MIR_MARK (1 << kMIRMark)
buzbee67bf8852011-08-17 17:51:35 -0700223
buzbeed1643e42012-09-05 14:06:51 -0700224struct Checkstats {
225 int nullChecks;
226 int nullChecksEliminated;
227 int rangeChecks;
228 int rangeChecksEliminated;
229};
230
Elliott Hughes719ace42012-03-09 18:06:03 -0800231struct MIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700232 DecodedInstruction dalvikInsn;
233 unsigned int width;
234 unsigned int offset;
235 MIR* prev;
236 MIR* next;
237 SSARepresentation* ssaRep;
238 int optimizationFlags;
Bill Buzbeea114add2012-05-03 15:00:40 -0700239 union {
Bill Buzbeea114add2012-05-03 15:00:40 -0700240 // Used to quickly locate all Phi opcodes
241 MIR* phiNext;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700242 // Establish link between two halves of throwing instructions
243 MIR* throwInsn;
Bill Buzbeea114add2012-05-03 15:00:40 -0700244 } meta;
Elliott Hughes719ace42012-03-09 18:06:03 -0800245};
buzbee67bf8852011-08-17 17:51:35 -0700246
247struct BasicBlockDataFlow;
248
249/* For successorBlockList */
Elliott Hughes719ace42012-03-09 18:06:03 -0800250enum BlockListType {
Bill Buzbeea114add2012-05-03 15:00:40 -0700251 kNotUsed = 0,
252 kCatch,
253 kPackedSwitch,
254 kSparseSwitch,
Elliott Hughes719ace42012-03-09 18:06:03 -0800255};
buzbee67bf8852011-08-17 17:51:35 -0700256
Elliott Hughes719ace42012-03-09 18:06:03 -0800257struct BasicBlock {
Bill Buzbeea114add2012-05-03 15:00:40 -0700258 int id;
259 int dfsId;
260 bool visited;
261 bool hidden;
262 bool catchEntry;
buzbee0967a252012-09-14 10:43:54 -0700263 bool explicitThrow;
264 bool conditionalBranch;
buzbee2cfc6392012-05-07 14:51:40 -0700265#if defined(ART_USE_QUICK_COMPILER)
266 bool hasReturn;
267#endif
Bill Buzbeea114add2012-05-03 15:00:40 -0700268 uint16_t startOffset;
269 uint16_t nestingDepth;
Bill Buzbeea114add2012-05-03 15:00:40 -0700270 BBType blockType;
Bill Buzbeea114add2012-05-03 15:00:40 -0700271 MIR* firstMIRInsn;
272 MIR* lastMIRInsn;
273 BasicBlock* fallThrough;
274 BasicBlock* taken;
275 BasicBlock* iDom; // Immediate dominator
276 BasicBlockDataFlow* dataFlowInfo;
277 GrowableList* predecessors;
278 ArenaBitVector* dominators;
279 ArenaBitVector* iDominated; // Set nodes being immediately dominated
280 ArenaBitVector* domFrontier; // Dominance frontier
281 struct { // For one-to-many successors like
282 BlockListType blockListType; // switch and exception handling
283 GrowableList blocks;
284 } successorBlockList;
Elliott Hughes719ace42012-03-09 18:06:03 -0800285};
buzbee67bf8852011-08-17 17:51:35 -0700286
287/*
288 * The "blocks" field in "successorBlockList" points to an array of
289 * elements with the type "SuccessorBlockInfo".
290 * For catch blocks, key is type index for the exception.
291 * For swtich blocks, key is the case value.
292 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800293struct SuccessorBlockInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700294 BasicBlock* block;
295 int key;
Elliott Hughes719ace42012-03-09 18:06:03 -0800296};
buzbee67bf8852011-08-17 17:51:35 -0700297
298struct LoopAnalysis;
299struct RegisterPool;
buzbeeba938cb2012-02-03 14:47:55 -0800300struct ArenaMemBlock;
301struct Memstats;
buzbee67bf8852011-08-17 17:51:35 -0700302
Elliott Hughes719ace42012-03-09 18:06:03 -0800303enum AssemblerStatus {
Bill Buzbeea114add2012-05-03 15:00:40 -0700304 kSuccess,
305 kRetryAll,
Elliott Hughes719ace42012-03-09 18:06:03 -0800306};
buzbee67bf8852011-08-17 17:51:35 -0700307
buzbee5b537102012-01-17 17:33:47 -0800308#define NOTVISITED (-1)
309
Elliott Hughes719ace42012-03-09 18:06:03 -0800310struct CompilationUnit {
Elliott Hughese52e49b2012-04-02 16:05:44 -0700311 CompilationUnit()
Bill Buzbeea114add2012-05-03 15:00:40 -0700312 : numBlocks(0),
313 compiler(NULL),
314 class_linker(NULL),
315 dex_file(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700316 class_loader(NULL),
317 method_idx(0),
318 code_item(NULL),
319 access_flags(0),
Ian Rogers08f753d2012-08-24 14:35:25 -0700320 invoke_type(kDirect),
Bill Buzbeea114add2012-05-03 15:00:40 -0700321 shorty(NULL),
322 firstLIRInsn(NULL),
323 lastLIRInsn(NULL),
324 literalList(NULL),
325 methodLiteralList(NULL),
326 codeLiteralList(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700327 disableOpt(0),
328 enableDebug(0),
Bill Buzbeea114add2012-05-03 15:00:40 -0700329 dataOffset(0),
330 totalSize(0),
331 assemblerStatus(kSuccess),
332 assemblerRetries(0),
333 genDebugger(false),
334 printMe(false),
Bill Buzbeea114add2012-05-03 15:00:40 -0700335 hasLoop(false),
336 hasInvoke(false),
Bill Buzbeea114add2012-05-03 15:00:40 -0700337 qdMode(false),
Bill Buzbeea114add2012-05-03 15:00:40 -0700338 regPool(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700339 instructionSet(kNone),
340 numSSARegs(0),
341 ssaBaseVRegs(NULL),
342 ssaSubscripts(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700343 ssaStrings(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700344 vRegToSSAMap(NULL),
345 SSALastDefs(NULL),
346 isConstantV(NULL),
347 constantValues(NULL),
348 phiAliasMap(NULL),
349 phiList(NULL),
350 regLocation(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700351 promotionMap(NULL),
352 methodSReg(0),
Bill Buzbeea114add2012-05-03 15:00:40 -0700353 numReachableBlocks(0),
354 numDalvikRegisters(0),
355 entryBlock(NULL),
356 exitBlock(NULL),
357 curBlock(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700358 iDomList(NULL),
359 tryBlockAddr(NULL),
360 defBlockMatrix(NULL),
361 tempBlockV(NULL),
362 tempDalvikRegisterV(NULL),
363 tempSSARegisterV(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700364 tempSSABlockIdV(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700365 blockLabelList(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700366 numIns(0),
367 numOuts(0),
368 numRegs(0),
369 numCoreSpills(0),
370 numFPSpills(0),
371 numCompilerTemps(0),
372 frameSize(0),
373 coreSpillMask(0U),
374 fpSpillMask(0U),
375 attrs(0U),
376 currentDalvikOffset(0),
377 insns(NULL),
378 insnsSize(0U),
379 disableDataflow(false),
380 defCount(0),
381 compilerFlipMatch(false),
382 arenaHead(NULL),
383 currentArena(NULL),
384 numArenaBlocks(0),
385 mstats(NULL),
buzbeed1643e42012-09-05 14:06:51 -0700386 checkstats(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700387#if defined(ART_USE_QUICK_COMPILER)
388 genBitcode(false),
389 context(NULL),
390 module(NULL),
391 func(NULL),
392 intrinsic_helper(NULL),
393 irb(NULL),
394 placeholderBB(NULL),
395 entryBB(NULL),
buzbee4be777b2012-07-12 14:38:18 -0700396 entryTargetBB(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700397 tempName(0),
buzbeeb03f4872012-06-11 15:22:11 -0700398 numShadowFrameEntries(0),
399 shadowMap(NULL),
Elliott Hughese52e49b2012-04-02 16:05:44 -0700400#endif
buzbee2cfc6392012-05-07 14:51:40 -0700401#ifndef NDEBUG
402 liveSReg(0),
403#endif
404 opcodeCount(NULL) {}
Elliott Hughese52e49b2012-04-02 16:05:44 -0700405
Bill Buzbeea114add2012-05-03 15:00:40 -0700406 int numBlocks;
407 GrowableList blockList;
408 Compiler* compiler; // Compiler driving this compiler
409 ClassLinker* class_linker; // Linker to resolve fields and methods
410 const DexFile* dex_file; // DexFile containing the method being compiled
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700411 jobject class_loader; // compiling method's class loader
Bill Buzbeea114add2012-05-03 15:00:40 -0700412 uint32_t method_idx; // compiling method's index into method_ids of DexFile
413 const DexFile::CodeItem* code_item; // compiling method's DexFile code_item
414 uint32_t access_flags; // compiling method's access flags
Ian Rogers08f753d2012-08-24 14:35:25 -0700415 InvokeType invoke_type; // compiling method's invocation type
Bill Buzbeea114add2012-05-03 15:00:40 -0700416 const char* shorty; // compiling method's shorty
417 LIR* firstLIRInsn;
418 LIR* lastLIRInsn;
419 LIR* literalList; // Constants
420 LIR* methodLiteralList; // Method literals requiring patching
421 LIR* codeLiteralList; // Code literals requiring patching
Bill Buzbeea114add2012-05-03 15:00:40 -0700422 uint32_t disableOpt; // optControlVector flags
423 uint32_t enableDebug; // debugControlVector flags
Bill Buzbeea114add2012-05-03 15:00:40 -0700424 int dataOffset; // starting offset of literal pool
425 int totalSize; // header + code size
426 AssemblerStatus assemblerStatus; // Success or fix and retry
427 int assemblerRetries;
428 std::vector<uint8_t> codeBuffer;
429 std::vector<uint32_t> mappingTable;
buzbeeca7a5e42012-08-20 11:12:18 -0700430 std::vector<uint32_t> coreVmapTable;
431 std::vector<uint32_t> fpVmapTable;
Ian Rogers0c7abda2012-09-19 13:33:42 -0700432 std::vector<uint8_t> nativeGcMap;
Bill Buzbeea114add2012-05-03 15:00:40 -0700433 bool genDebugger; // Generate code for debugger
434 bool printMe;
Bill Buzbeea114add2012-05-03 15:00:40 -0700435 bool hasLoop; // Contains a loop
436 bool hasInvoke; // Contains an invoke instruction
Bill Buzbeea114add2012-05-03 15:00:40 -0700437 bool qdMode; // Compile for code size/compile time
Bill Buzbeea114add2012-05-03 15:00:40 -0700438 RegisterPool* regPool;
Bill Buzbeea114add2012-05-03 15:00:40 -0700439 InstructionSet instructionSet;
440 /* Number of total regs used in the whole cUnit after SSA transformation */
441 int numSSARegs;
442 /* Map SSA reg i to the base virtual register/subscript */
443 GrowableList* ssaBaseVRegs;
444 GrowableList* ssaSubscripts;
buzbee2cfc6392012-05-07 14:51:40 -0700445 GrowableList* ssaStrings;
buzbee67bf8852011-08-17 17:51:35 -0700446
Bill Buzbeea114add2012-05-03 15:00:40 -0700447 /* The following are new data structures to support SSA representations */
448 /* Map original Dalvik virtual reg i to the current SSA name */
449 int* vRegToSSAMap; // length == method->registersSize
450 int* SSALastDefs; // length == method->registersSize
451 ArenaBitVector* isConstantV; // length == numSSAReg
452 int* constantValues; // length == numSSAReg
453 int* phiAliasMap; // length == numSSAReg
454 MIR* phiList;
buzbee67bf8852011-08-17 17:51:35 -0700455
Bill Buzbeea114add2012-05-03 15:00:40 -0700456 /* Use counts of ssa names */
457 GrowableList useCounts; // Weighted by nesting depth
458 GrowableList rawUseCounts; // Not weighted
buzbee239c4e72012-03-16 08:42:29 -0700459
Bill Buzbeea114add2012-05-03 15:00:40 -0700460 /* Optimization support */
461 GrowableList loopHeaders;
buzbee239c4e72012-03-16 08:42:29 -0700462
Bill Buzbeea114add2012-05-03 15:00:40 -0700463 /* Map SSA names to location */
464 RegLocation* regLocation;
buzbee67bf8852011-08-17 17:51:35 -0700465
Bill Buzbeea114add2012-05-03 15:00:40 -0700466 /* Keep track of Dalvik vReg to physical register mappings */
467 PromotionMap* promotionMap;
buzbee67bc2362011-10-11 18:08:40 -0700468
Bill Buzbeea114add2012-05-03 15:00:40 -0700469 /* SSA name for Method* */
470 int methodSReg;
buzbeead8f15e2012-06-18 14:49:45 -0700471 RegLocation methodLoc; // Describes location of method*
buzbeee1965672012-03-11 18:39:19 -0700472
Bill Buzbeea114add2012-05-03 15:00:40 -0700473 int numReachableBlocks;
474 int numDalvikRegisters; // method->registersSize
475 BasicBlock* entryBlock;
476 BasicBlock* exitBlock;
477 BasicBlock* curBlock;
Bill Buzbeea114add2012-05-03 15:00:40 -0700478 GrowableList dfsOrder;
479 GrowableList dfsPostOrder;
480 GrowableList domPostOrderTraversal;
481 GrowableList throwLaunchpads;
482 GrowableList suspendLaunchpads;
483 GrowableList intrinsicLaunchpads;
484 GrowableList compilerTemps;
485 int* iDomList;
486 ArenaBitVector* tryBlockAddr;
487 ArenaBitVector** defBlockMatrix; // numDalvikRegister x numBlocks
488 ArenaBitVector* tempBlockV;
489 ArenaBitVector* tempDalvikRegisterV;
490 ArenaBitVector* tempSSARegisterV; // numSSARegs
buzbee2cfc6392012-05-07 14:51:40 -0700491 int* tempSSABlockIdV; // working storage for Phi labels
buzbeea1da8a52012-07-09 14:00:21 -0700492 LIR* blockLabelList;
Bill Buzbeea114add2012-05-03 15:00:40 -0700493 /*
494 * Frame layout details.
495 * NOTE: for debug support it will be necessary to add a structure
496 * to map the Dalvik virtual registers to the promoted registers.
497 * NOTE: "num" fields are in 4-byte words, "Size" and "Offset" in bytes.
498 */
499 int numIns;
500 int numOuts;
501 int numRegs; // Unlike numDalvikRegisters, does not include ins
502 int numCoreSpills;
503 int numFPSpills;
504 int numCompilerTemps;
505 int frameSize;
506 unsigned int coreSpillMask;
507 unsigned int fpSpillMask;
508 unsigned int attrs;
509 /*
510 * CLEANUP/RESTRUCTURE: The code generation utilities don't have a built-in
511 * mechanism to propagate the original Dalvik opcode address to the
512 * associated generated instructions. For the trace compiler, this wasn't
513 * necessary because the interpreter handled all throws and debugging
514 * requests. For now we'll handle this by placing the Dalvik offset
515 * in the CompilationUnit struct before codegen for each instruction.
516 * The low-level LIR creation utilites will pull it from here. Should
517 * be rewritten.
518 */
519 int currentDalvikOffset;
520 GrowableList switchTables;
521 GrowableList fillArrayData;
522 const u2* insns;
523 u4 insnsSize;
524 bool disableDataflow; // Skip dataflow analysis if possible
525 SafeMap<unsigned int, BasicBlock*> blockMap; // findBlock lookup cache
buzbeed1643e42012-09-05 14:06:51 -0700526 SafeMap<unsigned int, unsigned int> blockIdMap; // Block collapse lookup cache
Bill Buzbeea114add2012-05-03 15:00:40 -0700527 SafeMap<unsigned int, LIR*> boundaryMap; // boundary lookup cache
528 int defCount; // Used to estimate number of SSA names
Elliott Hughese52e49b2012-04-02 16:05:44 -0700529
Bill Buzbeea114add2012-05-03 15:00:40 -0700530 // If non-empty, apply optimizer/debug flags only to matching methods.
531 std::string compilerMethodMatch;
532 // Flips sense of compilerMethodMatch - apply flags if doesn't match.
533 bool compilerFlipMatch;
534 ArenaMemBlock* arenaHead;
535 ArenaMemBlock* currentArena;
536 int numArenaBlocks;
537 Memstats* mstats;
buzbeed1643e42012-09-05 14:06:51 -0700538 Checkstats* checkstats;
buzbee2cfc6392012-05-07 14:51:40 -0700539#if defined(ART_USE_QUICK_COMPILER)
540 bool genBitcode;
TDYa12755e5e6c2012-09-11 15:14:42 -0700541 QuickCompiler* quick_compiler;
buzbee2cfc6392012-05-07 14:51:40 -0700542 llvm::LLVMContext* context;
543 llvm::Module* module;
544 llvm::Function* func;
545 greenland::IntrinsicHelper* intrinsic_helper;
546 greenland::IRBuilder* irb;
547 llvm::BasicBlock* placeholderBB;
548 llvm::BasicBlock* entryBB;
buzbee4be777b2012-07-12 14:38:18 -0700549 llvm::BasicBlock* entryTargetBB;
buzbee2cfc6392012-05-07 14:51:40 -0700550 std::string bitcode_filename;
551 GrowableList llvmValues;
552 int32_t tempName;
553 SafeMap<llvm::BasicBlock*, LIR*> blockToLabelMap; // llvm bb -> LIR label
554 SafeMap<int32_t, llvm::BasicBlock*> idToBlockMap; // block id -> llvm bb
555 SafeMap<llvm::Value*, RegLocation> locMap; // llvm Value to loc rec
buzbeeb03f4872012-06-11 15:22:11 -0700556 int numShadowFrameEntries;
557 int* shadowMap;
buzbee0967a252012-09-14 10:43:54 -0700558 std::set<llvm::BasicBlock*> llvmBlocks;
buzbee2cfc6392012-05-07 14:51:40 -0700559#endif
buzbee3d661942012-03-14 17:37:27 -0700560#ifndef NDEBUG
Bill Buzbeea114add2012-05-03 15:00:40 -0700561 /*
562 * Sanity checking for the register temp tracking. The same ssa
563 * name should never be associated with one temp register per
564 * instruction compilation.
565 */
566 int liveSReg;
buzbee3d661942012-03-14 17:37:27 -0700567#endif
buzbee2cfc6392012-05-07 14:51:40 -0700568 int* opcodeCount; // Count Dalvik opcodes for tuning
Elliott Hughes719ace42012-03-09 18:06:03 -0800569};
buzbee67bf8852011-08-17 17:51:35 -0700570
Elliott Hughes719ace42012-03-09 18:06:03 -0800571enum OpSize {
Bill Buzbeea114add2012-05-03 15:00:40 -0700572 kWord,
573 kLong,
574 kSingle,
575 kDouble,
576 kUnsignedHalf,
577 kSignedHalf,
578 kUnsignedByte,
579 kSignedByte,
Elliott Hughes719ace42012-03-09 18:06:03 -0800580};
buzbeee3acd072012-02-25 17:03:10 -0800581
Elliott Hughes719ace42012-03-09 18:06:03 -0800582enum OpKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700583 kOpMov,
584 kOpMvn,
585 kOpCmp,
586 kOpLsl,
587 kOpLsr,
588 kOpAsr,
589 kOpRor,
590 kOpNot,
591 kOpAnd,
592 kOpOr,
593 kOpXor,
594 kOpNeg,
595 kOpAdd,
596 kOpAdc,
597 kOpSub,
598 kOpSbc,
599 kOpRsub,
600 kOpMul,
601 kOpDiv,
602 kOpRem,
603 kOpBic,
604 kOpCmn,
605 kOpTst,
606 kOpBkpt,
607 kOpBlx,
608 kOpPush,
609 kOpPop,
610 kOp2Char,
611 kOp2Short,
612 kOp2Byte,
613 kOpCondBr,
614 kOpUncondBr,
615 kOpBx,
616 kOpInvalid,
Elliott Hughes719ace42012-03-09 18:06:03 -0800617};
buzbee31a4a6f2012-02-28 15:36:15 -0800618
Ian Rogers680b1bd2012-03-07 20:18:49 -0800619std::ostream& operator<<(std::ostream& os, const OpKind& kind);
620
Elliott Hughes719ace42012-03-09 18:06:03 -0800621enum ConditionCode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700622 kCondEq, // equal
623 kCondNe, // not equal
624 kCondCs, // carry set (unsigned less than)
625 kCondUlt = kCondCs,
626 kCondCc, // carry clear (unsigned greater than or same)
627 kCondUge = kCondCc,
628 kCondMi, // minus
629 kCondPl, // plus, positive or zero
630 kCondVs, // overflow
631 kCondVc, // no overflow
632 kCondHi, // unsigned greater than
633 kCondLs, // unsigned lower or same
634 kCondGe, // signed greater than or equal
635 kCondLt, // signed less than
636 kCondGt, // signed greater than
637 kCondLe, // signed less than or equal
638 kCondAl, // always
639 kCondNv, // never
Elliott Hughes719ace42012-03-09 18:06:03 -0800640};
buzbee31a4a6f2012-02-28 15:36:15 -0800641
Elliott Hughes719ace42012-03-09 18:06:03 -0800642enum ThrowKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700643 kThrowNullPointer,
644 kThrowDivZero,
645 kThrowArrayBounds,
Bill Buzbeea114add2012-05-03 15:00:40 -0700646 kThrowNoSuchMethod,
647 kThrowStackOverflow,
Elliott Hughes719ace42012-03-09 18:06:03 -0800648};
buzbee31a4a6f2012-02-28 15:36:15 -0800649
Elliott Hughes719ace42012-03-09 18:06:03 -0800650struct SwitchTable {
Bill Buzbeea114add2012-05-03 15:00:40 -0700651 int offset;
652 const u2* table; // Original dex table
653 int vaddr; // Dalvik offset of switch opcode
654 LIR* anchor; // Reference instruction for relative offsets
655 LIR** targets; // Array of case targets
Elliott Hughes719ace42012-03-09 18:06:03 -0800656};
buzbee5de34942012-03-01 14:51:57 -0800657
Elliott Hughes719ace42012-03-09 18:06:03 -0800658struct FillArrayData {
Bill Buzbeea114add2012-05-03 15:00:40 -0700659 int offset;
660 const u2* table; // Original dex table
661 int size;
662 int vaddr; // Dalvik offset of FILL_ARRAY_DATA opcode
Elliott Hughes719ace42012-03-09 18:06:03 -0800663};
buzbee5de34942012-03-01 14:51:57 -0800664
buzbee16da88c2012-03-20 10:38:17 -0700665#define MAX_PATTERN_LEN 5
666
667enum SpecialCaseHandler {
Bill Buzbeea114add2012-05-03 15:00:40 -0700668 kNoHandler,
669 kNullMethod,
670 kConstFunction,
671 kIGet,
672 kIGetBoolean,
673 kIGetObject,
674 kIGetByte,
675 kIGetChar,
676 kIGetShort,
677 kIGetWide,
678 kIPut,
679 kIPutBoolean,
680 kIPutObject,
681 kIPutByte,
682 kIPutChar,
683 kIPutShort,
684 kIPutWide,
685 kIdentity,
buzbee16da88c2012-03-20 10:38:17 -0700686};
687
688struct CodePattern {
Bill Buzbeea114add2012-05-03 15:00:40 -0700689 const Instruction::Code opcodes[MAX_PATTERN_LEN];
690 const SpecialCaseHandler handlerCode;
buzbee16da88c2012-03-20 10:38:17 -0700691};
692
693static const CodePattern specialPatterns[] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700694 {{Instruction::RETURN_VOID}, kNullMethod},
695 {{Instruction::CONST, Instruction::RETURN}, kConstFunction},
696 {{Instruction::CONST_4, Instruction::RETURN}, kConstFunction},
697 {{Instruction::CONST_4, Instruction::RETURN_OBJECT}, kConstFunction},
698 {{Instruction::CONST_16, Instruction::RETURN}, kConstFunction},
699 {{Instruction::IGET, Instruction:: RETURN}, kIGet},
700 {{Instruction::IGET_BOOLEAN, Instruction::RETURN}, kIGetBoolean},
701 {{Instruction::IGET_OBJECT, Instruction::RETURN_OBJECT}, kIGetObject},
702 {{Instruction::IGET_BYTE, Instruction::RETURN}, kIGetByte},
703 {{Instruction::IGET_CHAR, Instruction::RETURN}, kIGetChar},
704 {{Instruction::IGET_SHORT, Instruction::RETURN}, kIGetShort},
705 {{Instruction::IGET_WIDE, Instruction::RETURN_WIDE}, kIGetWide},
706 {{Instruction::IPUT, Instruction::RETURN_VOID}, kIPut},
707 {{Instruction::IPUT_BOOLEAN, Instruction::RETURN_VOID}, kIPutBoolean},
708 {{Instruction::IPUT_OBJECT, Instruction::RETURN_VOID}, kIPutObject},
709 {{Instruction::IPUT_BYTE, Instruction::RETURN_VOID}, kIPutByte},
710 {{Instruction::IPUT_CHAR, Instruction::RETURN_VOID}, kIPutChar},
711 {{Instruction::IPUT_SHORT, Instruction::RETURN_VOID}, kIPutShort},
712 {{Instruction::IPUT_WIDE, Instruction::RETURN_VOID}, kIPutWide},
713 {{Instruction::RETURN}, kIdentity},
714 {{Instruction::RETURN_OBJECT}, kIdentity},
715 {{Instruction::RETURN_WIDE}, kIdentity},
buzbee16da88c2012-03-20 10:38:17 -0700716};
buzbee5de34942012-03-01 14:51:57 -0800717
buzbee5abfa3e2012-01-31 17:01:43 -0800718BasicBlock* oatNewBB(CompilationUnit* cUnit, BBType blockType, int blockId);
buzbee67bf8852011-08-17 17:51:35 -0700719
720void oatAppendMIR(BasicBlock* bb, MIR* mir);
721
722void oatPrependMIR(BasicBlock* bb, MIR* mir);
723
724void oatInsertMIRAfter(BasicBlock* bb, MIR* currentMIR, MIR* newMIR);
725
726void oatAppendLIR(CompilationUnit* cUnit, LIR* lir);
727
728void oatInsertLIRBefore(LIR* currentLIR, LIR* newLIR);
729
730void oatInsertLIRAfter(LIR* currentLIR, LIR* newLIR);
731
buzbee15bf9802012-06-12 17:49:27 -0700732MIR* oatFindMoveResult(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir);
buzbee67bf8852011-08-17 17:51:35 -0700733/* Debug Utilities */
734void oatDumpCompilationUnit(CompilationUnit* cUnit);
735
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800736} // namespace art
737
buzbee67bf8852011-08-17 17:51:35 -0700738#endif // ART_SRC_COMPILER_COMPILER_IR_H_