blob: 5a10831a0db1d2e31362c202bbf020b90e5732f3 [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;
Bill Buzbeea5b30242012-09-28 07:19:44 -0700429 /*
430 * Holds mapping from native PC to dex PC for safepoints where we may deoptimize.
431 * Native PC is on the return address of the safepointed operation. Dex PC is for
432 * the instruction being executed at the safepoint.
433 */
434 std::vector<uint32_t> pc2dexMappingTable;
435 /*
436 * Holds mapping from Dex PC to native PC for catch entry points. Native PC and Dex PC
437 * immediately preceed the instruction.
438 */
439 std::vector<uint32_t> dex2pcMappingTable;
440 std::vector<uint32_t> combinedMappingTable;
buzbeeca7a5e42012-08-20 11:12:18 -0700441 std::vector<uint32_t> coreVmapTable;
442 std::vector<uint32_t> fpVmapTable;
Ian Rogers0c7abda2012-09-19 13:33:42 -0700443 std::vector<uint8_t> nativeGcMap;
Bill Buzbeea114add2012-05-03 15:00:40 -0700444 bool genDebugger; // Generate code for debugger
445 bool printMe;
Bill Buzbeea114add2012-05-03 15:00:40 -0700446 bool hasLoop; // Contains a loop
447 bool hasInvoke; // Contains an invoke instruction
Bill Buzbeea114add2012-05-03 15:00:40 -0700448 bool qdMode; // Compile for code size/compile time
Bill Buzbeea114add2012-05-03 15:00:40 -0700449 RegisterPool* regPool;
Bill Buzbeea114add2012-05-03 15:00:40 -0700450 InstructionSet instructionSet;
451 /* Number of total regs used in the whole cUnit after SSA transformation */
452 int numSSARegs;
453 /* Map SSA reg i to the base virtual register/subscript */
454 GrowableList* ssaBaseVRegs;
455 GrowableList* ssaSubscripts;
buzbee2cfc6392012-05-07 14:51:40 -0700456 GrowableList* ssaStrings;
buzbee67bf8852011-08-17 17:51:35 -0700457
Bill Buzbeea114add2012-05-03 15:00:40 -0700458 /* The following are new data structures to support SSA representations */
459 /* Map original Dalvik virtual reg i to the current SSA name */
460 int* vRegToSSAMap; // length == method->registersSize
461 int* SSALastDefs; // length == method->registersSize
462 ArenaBitVector* isConstantV; // length == numSSAReg
463 int* constantValues; // length == numSSAReg
464 int* phiAliasMap; // length == numSSAReg
465 MIR* phiList;
buzbee67bf8852011-08-17 17:51:35 -0700466
Bill Buzbeea114add2012-05-03 15:00:40 -0700467 /* Use counts of ssa names */
468 GrowableList useCounts; // Weighted by nesting depth
469 GrowableList rawUseCounts; // Not weighted
buzbee239c4e72012-03-16 08:42:29 -0700470
Bill Buzbeea114add2012-05-03 15:00:40 -0700471 /* Optimization support */
472 GrowableList loopHeaders;
buzbee239c4e72012-03-16 08:42:29 -0700473
Bill Buzbeea114add2012-05-03 15:00:40 -0700474 /* Map SSA names to location */
475 RegLocation* regLocation;
buzbee67bf8852011-08-17 17:51:35 -0700476
Bill Buzbeea114add2012-05-03 15:00:40 -0700477 /* Keep track of Dalvik vReg to physical register mappings */
478 PromotionMap* promotionMap;
buzbee67bc2362011-10-11 18:08:40 -0700479
Bill Buzbeea114add2012-05-03 15:00:40 -0700480 /* SSA name for Method* */
481 int methodSReg;
buzbeead8f15e2012-06-18 14:49:45 -0700482 RegLocation methodLoc; // Describes location of method*
buzbeee1965672012-03-11 18:39:19 -0700483
Bill Buzbeea114add2012-05-03 15:00:40 -0700484 int numReachableBlocks;
485 int numDalvikRegisters; // method->registersSize
486 BasicBlock* entryBlock;
487 BasicBlock* exitBlock;
488 BasicBlock* curBlock;
Bill Buzbeea114add2012-05-03 15:00:40 -0700489 GrowableList dfsOrder;
490 GrowableList dfsPostOrder;
491 GrowableList domPostOrderTraversal;
492 GrowableList throwLaunchpads;
493 GrowableList suspendLaunchpads;
494 GrowableList intrinsicLaunchpads;
495 GrowableList compilerTemps;
496 int* iDomList;
497 ArenaBitVector* tryBlockAddr;
498 ArenaBitVector** defBlockMatrix; // numDalvikRegister x numBlocks
499 ArenaBitVector* tempBlockV;
500 ArenaBitVector* tempDalvikRegisterV;
501 ArenaBitVector* tempSSARegisterV; // numSSARegs
buzbee2cfc6392012-05-07 14:51:40 -0700502 int* tempSSABlockIdV; // working storage for Phi labels
buzbeea1da8a52012-07-09 14:00:21 -0700503 LIR* blockLabelList;
Bill Buzbeea114add2012-05-03 15:00:40 -0700504 /*
505 * Frame layout details.
506 * NOTE: for debug support it will be necessary to add a structure
507 * to map the Dalvik virtual registers to the promoted registers.
508 * NOTE: "num" fields are in 4-byte words, "Size" and "Offset" in bytes.
509 */
510 int numIns;
511 int numOuts;
512 int numRegs; // Unlike numDalvikRegisters, does not include ins
513 int numCoreSpills;
514 int numFPSpills;
515 int numCompilerTemps;
516 int frameSize;
517 unsigned int coreSpillMask;
518 unsigned int fpSpillMask;
519 unsigned int attrs;
520 /*
521 * CLEANUP/RESTRUCTURE: The code generation utilities don't have a built-in
522 * mechanism to propagate the original Dalvik opcode address to the
523 * associated generated instructions. For the trace compiler, this wasn't
524 * necessary because the interpreter handled all throws and debugging
525 * requests. For now we'll handle this by placing the Dalvik offset
526 * in the CompilationUnit struct before codegen for each instruction.
527 * The low-level LIR creation utilites will pull it from here. Should
528 * be rewritten.
529 */
530 int currentDalvikOffset;
531 GrowableList switchTables;
532 GrowableList fillArrayData;
533 const u2* insns;
534 u4 insnsSize;
535 bool disableDataflow; // Skip dataflow analysis if possible
536 SafeMap<unsigned int, BasicBlock*> blockMap; // findBlock lookup cache
buzbeed1643e42012-09-05 14:06:51 -0700537 SafeMap<unsigned int, unsigned int> blockIdMap; // Block collapse lookup cache
Bill Buzbeea114add2012-05-03 15:00:40 -0700538 SafeMap<unsigned int, LIR*> boundaryMap; // boundary lookup cache
539 int defCount; // Used to estimate number of SSA names
Elliott Hughese52e49b2012-04-02 16:05:44 -0700540
Bill Buzbeea114add2012-05-03 15:00:40 -0700541 // If non-empty, apply optimizer/debug flags only to matching methods.
542 std::string compilerMethodMatch;
543 // Flips sense of compilerMethodMatch - apply flags if doesn't match.
544 bool compilerFlipMatch;
545 ArenaMemBlock* arenaHead;
546 ArenaMemBlock* currentArena;
547 int numArenaBlocks;
548 Memstats* mstats;
buzbeed1643e42012-09-05 14:06:51 -0700549 Checkstats* checkstats;
buzbee2cfc6392012-05-07 14:51:40 -0700550#if defined(ART_USE_QUICK_COMPILER)
551 bool genBitcode;
buzbee4df2bbd2012-10-11 14:46:06 -0700552 LLVMInfo* llvm_info;
buzbee2cfc6392012-05-07 14:51:40 -0700553 llvm::LLVMContext* context;
554 llvm::Module* module;
555 llvm::Function* func;
556 greenland::IntrinsicHelper* intrinsic_helper;
557 greenland::IRBuilder* irb;
558 llvm::BasicBlock* placeholderBB;
559 llvm::BasicBlock* entryBB;
buzbee4be777b2012-07-12 14:38:18 -0700560 llvm::BasicBlock* entryTargetBB;
buzbee2cfc6392012-05-07 14:51:40 -0700561 std::string bitcode_filename;
562 GrowableList llvmValues;
563 int32_t tempName;
564 SafeMap<llvm::BasicBlock*, LIR*> blockToLabelMap; // llvm bb -> LIR label
565 SafeMap<int32_t, llvm::BasicBlock*> idToBlockMap; // block id -> llvm bb
566 SafeMap<llvm::Value*, RegLocation> locMap; // llvm Value to loc rec
buzbeeb03f4872012-06-11 15:22:11 -0700567 int numShadowFrameEntries;
568 int* shadowMap;
buzbee0967a252012-09-14 10:43:54 -0700569 std::set<llvm::BasicBlock*> llvmBlocks;
buzbee2cfc6392012-05-07 14:51:40 -0700570#endif
buzbee3d661942012-03-14 17:37:27 -0700571#ifndef NDEBUG
Bill Buzbeea114add2012-05-03 15:00:40 -0700572 /*
573 * Sanity checking for the register temp tracking. The same ssa
574 * name should never be associated with one temp register per
575 * instruction compilation.
576 */
577 int liveSReg;
buzbee3d661942012-03-14 17:37:27 -0700578#endif
buzbee6459e7c2012-10-02 14:42:41 -0700579 std::set<uint32_t> catches;
buzbee2cfc6392012-05-07 14:51:40 -0700580 int* opcodeCount; // Count Dalvik opcodes for tuning
Elliott Hughes719ace42012-03-09 18:06:03 -0800581};
buzbee67bf8852011-08-17 17:51:35 -0700582
Elliott Hughes719ace42012-03-09 18:06:03 -0800583enum OpSize {
Bill Buzbeea114add2012-05-03 15:00:40 -0700584 kWord,
585 kLong,
586 kSingle,
587 kDouble,
588 kUnsignedHalf,
589 kSignedHalf,
590 kUnsignedByte,
591 kSignedByte,
Elliott Hughes719ace42012-03-09 18:06:03 -0800592};
buzbeee3acd072012-02-25 17:03:10 -0800593
Elliott Hughes719ace42012-03-09 18:06:03 -0800594enum OpKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700595 kOpMov,
596 kOpMvn,
597 kOpCmp,
598 kOpLsl,
599 kOpLsr,
600 kOpAsr,
601 kOpRor,
602 kOpNot,
603 kOpAnd,
604 kOpOr,
605 kOpXor,
606 kOpNeg,
607 kOpAdd,
608 kOpAdc,
609 kOpSub,
610 kOpSbc,
611 kOpRsub,
612 kOpMul,
613 kOpDiv,
614 kOpRem,
615 kOpBic,
616 kOpCmn,
617 kOpTst,
618 kOpBkpt,
619 kOpBlx,
620 kOpPush,
621 kOpPop,
622 kOp2Char,
623 kOp2Short,
624 kOp2Byte,
625 kOpCondBr,
626 kOpUncondBr,
627 kOpBx,
628 kOpInvalid,
Elliott Hughes719ace42012-03-09 18:06:03 -0800629};
buzbee31a4a6f2012-02-28 15:36:15 -0800630
Ian Rogers680b1bd2012-03-07 20:18:49 -0800631std::ostream& operator<<(std::ostream& os, const OpKind& kind);
632
Elliott Hughes719ace42012-03-09 18:06:03 -0800633enum ConditionCode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700634 kCondEq, // equal
635 kCondNe, // not equal
636 kCondCs, // carry set (unsigned less than)
637 kCondUlt = kCondCs,
638 kCondCc, // carry clear (unsigned greater than or same)
639 kCondUge = kCondCc,
640 kCondMi, // minus
641 kCondPl, // plus, positive or zero
642 kCondVs, // overflow
643 kCondVc, // no overflow
644 kCondHi, // unsigned greater than
645 kCondLs, // unsigned lower or same
646 kCondGe, // signed greater than or equal
647 kCondLt, // signed less than
648 kCondGt, // signed greater than
649 kCondLe, // signed less than or equal
650 kCondAl, // always
651 kCondNv, // never
Elliott Hughes719ace42012-03-09 18:06:03 -0800652};
buzbee31a4a6f2012-02-28 15:36:15 -0800653
Elliott Hughes719ace42012-03-09 18:06:03 -0800654enum ThrowKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700655 kThrowNullPointer,
656 kThrowDivZero,
657 kThrowArrayBounds,
Bill Buzbeea114add2012-05-03 15:00:40 -0700658 kThrowNoSuchMethod,
659 kThrowStackOverflow,
Elliott Hughes719ace42012-03-09 18:06:03 -0800660};
buzbee31a4a6f2012-02-28 15:36:15 -0800661
Elliott Hughes719ace42012-03-09 18:06:03 -0800662struct SwitchTable {
Bill Buzbeea114add2012-05-03 15:00:40 -0700663 int offset;
664 const u2* table; // Original dex table
665 int vaddr; // Dalvik offset of switch opcode
666 LIR* anchor; // Reference instruction for relative offsets
667 LIR** targets; // Array of case targets
Elliott Hughes719ace42012-03-09 18:06:03 -0800668};
buzbee5de34942012-03-01 14:51:57 -0800669
Elliott Hughes719ace42012-03-09 18:06:03 -0800670struct FillArrayData {
Bill Buzbeea114add2012-05-03 15:00:40 -0700671 int offset;
672 const u2* table; // Original dex table
673 int size;
674 int vaddr; // Dalvik offset of FILL_ARRAY_DATA opcode
Elliott Hughes719ace42012-03-09 18:06:03 -0800675};
buzbee5de34942012-03-01 14:51:57 -0800676
buzbee16da88c2012-03-20 10:38:17 -0700677#define MAX_PATTERN_LEN 5
678
679enum SpecialCaseHandler {
Bill Buzbeea114add2012-05-03 15:00:40 -0700680 kNoHandler,
681 kNullMethod,
682 kConstFunction,
683 kIGet,
684 kIGetBoolean,
685 kIGetObject,
686 kIGetByte,
687 kIGetChar,
688 kIGetShort,
689 kIGetWide,
690 kIPut,
691 kIPutBoolean,
692 kIPutObject,
693 kIPutByte,
694 kIPutChar,
695 kIPutShort,
696 kIPutWide,
697 kIdentity,
buzbee16da88c2012-03-20 10:38:17 -0700698};
699
700struct CodePattern {
Bill Buzbeea114add2012-05-03 15:00:40 -0700701 const Instruction::Code opcodes[MAX_PATTERN_LEN];
702 const SpecialCaseHandler handlerCode;
buzbee16da88c2012-03-20 10:38:17 -0700703};
704
705static const CodePattern specialPatterns[] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700706 {{Instruction::RETURN_VOID}, kNullMethod},
707 {{Instruction::CONST, Instruction::RETURN}, kConstFunction},
708 {{Instruction::CONST_4, Instruction::RETURN}, kConstFunction},
709 {{Instruction::CONST_4, Instruction::RETURN_OBJECT}, kConstFunction},
710 {{Instruction::CONST_16, Instruction::RETURN}, kConstFunction},
711 {{Instruction::IGET, Instruction:: RETURN}, kIGet},
712 {{Instruction::IGET_BOOLEAN, Instruction::RETURN}, kIGetBoolean},
713 {{Instruction::IGET_OBJECT, Instruction::RETURN_OBJECT}, kIGetObject},
714 {{Instruction::IGET_BYTE, Instruction::RETURN}, kIGetByte},
715 {{Instruction::IGET_CHAR, Instruction::RETURN}, kIGetChar},
716 {{Instruction::IGET_SHORT, Instruction::RETURN}, kIGetShort},
717 {{Instruction::IGET_WIDE, Instruction::RETURN_WIDE}, kIGetWide},
718 {{Instruction::IPUT, Instruction::RETURN_VOID}, kIPut},
719 {{Instruction::IPUT_BOOLEAN, Instruction::RETURN_VOID}, kIPutBoolean},
720 {{Instruction::IPUT_OBJECT, Instruction::RETURN_VOID}, kIPutObject},
721 {{Instruction::IPUT_BYTE, Instruction::RETURN_VOID}, kIPutByte},
722 {{Instruction::IPUT_CHAR, Instruction::RETURN_VOID}, kIPutChar},
723 {{Instruction::IPUT_SHORT, Instruction::RETURN_VOID}, kIPutShort},
724 {{Instruction::IPUT_WIDE, Instruction::RETURN_VOID}, kIPutWide},
725 {{Instruction::RETURN}, kIdentity},
726 {{Instruction::RETURN_OBJECT}, kIdentity},
727 {{Instruction::RETURN_WIDE}, kIdentity},
buzbee16da88c2012-03-20 10:38:17 -0700728};
buzbee5de34942012-03-01 14:51:57 -0800729
buzbee5abfa3e2012-01-31 17:01:43 -0800730BasicBlock* oatNewBB(CompilationUnit* cUnit, BBType blockType, int blockId);
buzbee67bf8852011-08-17 17:51:35 -0700731
732void oatAppendMIR(BasicBlock* bb, MIR* mir);
733
734void oatPrependMIR(BasicBlock* bb, MIR* mir);
735
736void oatInsertMIRAfter(BasicBlock* bb, MIR* currentMIR, MIR* newMIR);
737
738void oatAppendLIR(CompilationUnit* cUnit, LIR* lir);
739
740void oatInsertLIRBefore(LIR* currentLIR, LIR* newLIR);
741
742void oatInsertLIRAfter(LIR* currentLIR, LIR* newLIR);
743
buzbee15bf9802012-06-12 17:49:27 -0700744MIR* oatFindMoveResult(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir);
buzbee67bf8852011-08-17 17:51:35 -0700745/* Debug Utilities */
746void oatDumpCompilationUnit(CompilationUnit* cUnit);
747
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800748} // namespace art
749
buzbee67bf8852011-08-17 17:51:35 -0700750#endif // ART_SRC_COMPILER_COMPILER_IR_H_