blob: d08af073d13f2e5cee2555113de7429b69b5974a [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#include "greenland/ir_builder.h"
27#include "llvm/Module.h"
buzbee67bf8852011-08-17 17:51:35 -070028
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080029namespace art {
30
buzbee31a4a6f2012-02-28 15:36:15 -080031#define SLOW_FIELD_PATH (cUnit->enableDebug & (1 << kDebugSlowFieldPath))
32#define SLOW_INVOKE_PATH (cUnit->enableDebug & (1 << kDebugSlowInvokePath))
33#define SLOW_STRING_PATH (cUnit->enableDebug & (1 << kDebugSlowStringPath))
34#define SLOW_TYPE_PATH (cUnit->enableDebug & (1 << kDebugSlowTypePath))
buzbee31a4a6f2012-02-28 15:36:15 -080035#define EXERCISE_SLOWEST_STRING_PATH (cUnit->enableDebug & \
Bill Buzbeea114add2012-05-03 15:00:40 -070036 (1 << kDebugSlowestStringPath))
buzbee31a4a6f2012-02-28 15:36:15 -080037
buzbeeca7a5e42012-08-20 11:12:18 -070038// Minimum field size to contain Dalvik vReg number
39#define VREG_NUM_WIDTH 16
40
Elliott Hughes719ace42012-03-09 18:06:03 -080041enum RegisterClass {
Bill Buzbeea114add2012-05-03 15:00:40 -070042 kCoreReg,
43 kFPReg,
44 kAnyReg,
Elliott Hughes719ace42012-03-09 18:06:03 -080045};
buzbee67bf8852011-08-17 17:51:35 -070046
Elliott Hughes719ace42012-03-09 18:06:03 -080047enum RegLocationType {
Bill Buzbeea114add2012-05-03 15:00:40 -070048 kLocDalvikFrame = 0, // Normal Dalvik register
49 kLocPhysReg,
50 kLocCompilerTemp,
51 kLocInvalid
Elliott Hughes719ace42012-03-09 18:06:03 -080052};
buzbee67bf8852011-08-17 17:51:35 -070053
Elliott Hughes719ace42012-03-09 18:06:03 -080054struct PromotionMap {
Bill Buzbeea114add2012-05-03 15:00:40 -070055 RegLocationType coreLocation:3;
56 u1 coreReg;
57 RegLocationType fpLocation:3;
58 u1 fpReg;
59 bool firstInPair;
Elliott Hughes719ace42012-03-09 18:06:03 -080060};
buzbee67bc2362011-10-11 18:08:40 -070061
Elliott Hughes719ace42012-03-09 18:06:03 -080062struct RegLocation {
Bill Buzbeea114add2012-05-03 15:00:40 -070063 RegLocationType location:3;
64 unsigned wide:1;
65 unsigned defined:1; // Do we know the type?
buzbee2cfc6392012-05-07 14:51:40 -070066 unsigned isConst:1; // Constant, value in cUnit->constantValues[]
Bill Buzbeea114add2012-05-03 15:00:40 -070067 unsigned fp:1; // Floating point?
68 unsigned core:1; // Non-floating point?
buzbeebff24652012-05-06 16:22:05 -070069 unsigned ref:1; // Something GC cares about
Bill Buzbeea114add2012-05-03 15:00:40 -070070 unsigned highWord:1; // High word of pair?
71 unsigned home:1; // Does this represent the home location?
72 u1 lowReg; // First physical register
73 u1 highReg; // 2nd physical register (if wide)
74 int32_t sRegLow; // SSA name for low Dalvik word
buzbee2cfc6392012-05-07 14:51:40 -070075 int32_t origSReg; // TODO: remove after Bitcode gen complete
76 // and consolodate usage w/ sRegLow
buzbeee1965672012-03-11 18:39:19 -070077};
78
79struct CompilerTemp {
Bill Buzbeea114add2012-05-03 15:00:40 -070080 int sReg;
81 ArenaBitVector* bv;
Elliott Hughes719ace42012-03-09 18:06:03 -080082};
buzbee67bf8852011-08-17 17:51:35 -070083
buzbee3b3dbdd2012-06-13 13:39:34 -070084struct CallInfo {
buzbee15bf9802012-06-12 17:49:27 -070085 int numArgWords; // Note: word count, not arg count
86 RegLocation* args; // One for each word of arguments
87 RegLocation result; // Eventual target of MOVE_RESULT
88 int optFlags;
89 InvokeType type;
90 uint32_t dexIdx;
buzbee3b3dbdd2012-06-13 13:39:34 -070091 uint32_t index; // Method idx for invokes, type idx for FilledNewArray
buzbee15bf9802012-06-12 17:49:27 -070092 uintptr_t directCode;
93 uintptr_t directMethod;
94 RegLocation target; // Target of following move_result
95 bool skipThis;
96 bool isRange;
97 int offset; // Dalvik offset
98};
99
buzbeee3acd072012-02-25 17:03:10 -0800100 /*
101 * Data structure tracking the mapping between a Dalvik register (pair) and a
102 * native register (pair). The idea is to reuse the previously loaded value
103 * if possible, otherwise to keep the value in a native register as long as
104 * possible.
105 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800106struct RegisterInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700107 int reg; // Reg number
108 bool inUse; // Has it been allocated?
109 bool isTemp; // Can allocate as temp?
110 bool pair; // Part of a register pair?
111 int partner; // If pair, other reg of pair
112 bool live; // Is there an associated SSA name?
113 bool dirty; // If live, is it dirty?
114 int sReg; // Name of live value
115 LIR *defStart; // Starting inst in last def sequence
116 LIR *defEnd; // Ending inst in last def sequence
Elliott Hughes719ace42012-03-09 18:06:03 -0800117};
buzbeee3acd072012-02-25 17:03:10 -0800118
Elliott Hughes719ace42012-03-09 18:06:03 -0800119struct RegisterPool {
Bill Buzbeea114add2012-05-03 15:00:40 -0700120 int numCoreRegs;
121 RegisterInfo *coreRegs;
122 int nextCoreReg;
123 int numFPRegs;
124 RegisterInfo *FPRegs;
125 int nextFPReg;
Elliott Hughes719ace42012-03-09 18:06:03 -0800126};
buzbeee3acd072012-02-25 17:03:10 -0800127
buzbee67bf8852011-08-17 17:51:35 -0700128#define INVALID_SREG (-1)
buzbee3ddc0d12011-10-05 10:36:21 -0700129#define INVALID_VREG (0xFFFFU)
buzbee67bc2362011-10-11 18:08:40 -0700130#define INVALID_REG (0xFF)
buzbee67bf8852011-08-17 17:51:35 -0700131
buzbeee1965672012-03-11 18:39:19 -0700132/* SSA encodings for special registers */
buzbee9c044ce2012-03-18 13:24:07 -0700133#define SSA_METHOD_BASEREG (-2)
buzbeee1965672012-03-11 18:39:19 -0700134/* First compiler temp basereg, grows smaller */
buzbee9c044ce2012-03-18 13:24:07 -0700135#define SSA_CTEMP_BASEREG (SSA_METHOD_BASEREG - 1)
buzbeee1965672012-03-11 18:39:19 -0700136
buzbee99ba9642012-01-25 14:23:14 -0800137/*
138 * Some code patterns cause the generation of excessively large
139 * methods - in particular initialization sequences. There isn't much
140 * benefit in optimizing these methods, and the cost can be very high.
141 * We attempt to identify these cases, and avoid performing most dataflow
142 * analysis. Two thresholds are used - one for known initializers and one
buzbee5abfa3e2012-01-31 17:01:43 -0800143 * for everything else.
buzbee99ba9642012-01-25 14:23:14 -0800144 */
buzbee5abfa3e2012-01-31 17:01:43 -0800145#define MANY_BLOCKS_INITIALIZER 1000 /* Threshold for switching dataflow off */
146#define MANY_BLOCKS 4000 /* Non-initializer threshold */
buzbee99ba9642012-01-25 14:23:14 -0800147
Elliott Hughes719ace42012-03-09 18:06:03 -0800148enum BBType {
Bill Buzbeea114add2012-05-03 15:00:40 -0700149 kEntryBlock,
150 kDalvikByteCode,
151 kExitBlock,
152 kExceptionHandling,
buzbeed1643e42012-09-05 14:06:51 -0700153 kDead,
Elliott Hughes719ace42012-03-09 18:06:03 -0800154};
buzbee67bf8852011-08-17 17:51:35 -0700155
buzbee31a4a6f2012-02-28 15:36:15 -0800156/* Utility macros to traverse the LIR list */
157#define NEXT_LIR(lir) (lir->next)
158#define PREV_LIR(lir) (lir->prev)
159
Elliott Hughes719ace42012-03-09 18:06:03 -0800160struct LIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700161 int offset; // Offset of this instruction
162 int dalvikOffset; // Offset of Dalvik opcode
163 LIR* next;
164 LIR* prev;
165 LIR* target;
166 int opcode;
167 int operands[5]; // [0..4] = [dest, src1, src2, extra, extra2]
168 struct {
169 bool isNop:1; // LIR is optimized away
170 bool pcRelFixup:1; // May need pc-relative fixup
Bill Buzbeea114add2012-05-03 15:00:40 -0700171 unsigned int size:5; // in bytes
buzbeef5f5a122012-09-21 13:57:36 -0700172 unsigned int unused:25;
Bill Buzbeea114add2012-05-03 15:00:40 -0700173 } flags;
174 int aliasInfo; // For Dalvik register & litpool disambiguation
175 u8 useMask; // Resource mask for use
176 u8 defMask; // Resource mask for def
Elliott Hughes719ace42012-03-09 18:06:03 -0800177};
buzbee67bf8852011-08-17 17:51:35 -0700178
179enum ExtendedMIROpcode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700180 kMirOpFirst = kNumPackedOpcodes,
181 kMirOpPhi = kMirOpFirst,
182 kMirOpCopy,
183 kMirOpFusedCmplFloat,
184 kMirOpFusedCmpgFloat,
185 kMirOpFusedCmplDouble,
186 kMirOpFusedCmpgDouble,
187 kMirOpFusedCmpLong,
188 kMirOpNop,
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700189 kMirOpNullCheck,
190 kMirOpRangeCheck,
191 kMirOpDivZeroCheck,
192 kMirOpCheck,
Bill Buzbeea114add2012-05-03 15:00:40 -0700193 kMirOpLast,
buzbee67bf8852011-08-17 17:51:35 -0700194};
195
196struct SSARepresentation;
197
Elliott Hughes719ace42012-03-09 18:06:03 -0800198enum MIROptimizationFlagPositons {
Bill Buzbeea114add2012-05-03 15:00:40 -0700199 kMIRIgnoreNullCheck = 0,
200 kMIRNullCheckOnly,
201 kMIRIgnoreRangeCheck,
202 kMIRRangeCheckOnly,
203 kMIRInlined, // Invoke is inlined (ie dead)
204 kMIRInlinedPred, // Invoke is inlined via prediction
205 kMIRCallee, // Instruction is inlined from callee
206 kMIRIgnoreSuspendCheck,
207 kMIRDup,
208 kMIRMark, // Temporary node mark
Elliott Hughes719ace42012-03-09 18:06:03 -0800209};
buzbee67bf8852011-08-17 17:51:35 -0700210
211#define MIR_IGNORE_NULL_CHECK (1 << kMIRIgnoreNullCheck)
212#define MIR_NULL_CHECK_ONLY (1 << kMIRNullCheckOnly)
213#define MIR_IGNORE_RANGE_CHECK (1 << kMIRIgnoreRangeCheck)
214#define MIR_RANGE_CHECK_ONLY (1 << kMIRRangeCheckOnly)
215#define MIR_INLINED (1 << kMIRInlined)
216#define MIR_INLINED_PRED (1 << kMIRInlinedPred)
217#define MIR_CALLEE (1 << kMIRCallee)
buzbeec1f45042011-09-21 16:03:19 -0700218#define MIR_IGNORE_SUSPEND_CHECK (1 << kMIRIgnoreSuspendCheck)
buzbeee1965672012-03-11 18:39:19 -0700219#define MIR_DUP (1 << kMIRDup)
buzbee239c4e72012-03-16 08:42:29 -0700220#define MIR_MARK (1 << kMIRMark)
buzbee67bf8852011-08-17 17:51:35 -0700221
buzbeed1643e42012-09-05 14:06:51 -0700222struct Checkstats {
223 int nullChecks;
224 int nullChecksEliminated;
225 int rangeChecks;
226 int rangeChecksEliminated;
227};
228
Elliott Hughes719ace42012-03-09 18:06:03 -0800229struct MIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700230 DecodedInstruction dalvikInsn;
231 unsigned int width;
232 unsigned int offset;
233 MIR* prev;
234 MIR* next;
235 SSARepresentation* ssaRep;
236 int optimizationFlags;
Bill Buzbeea114add2012-05-03 15:00:40 -0700237 union {
Bill Buzbeea114add2012-05-03 15:00:40 -0700238 // Used to quickly locate all Phi opcodes
239 MIR* phiNext;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700240 // Establish link between two halves of throwing instructions
241 MIR* throwInsn;
Bill Buzbeea114add2012-05-03 15:00:40 -0700242 } meta;
Elliott Hughes719ace42012-03-09 18:06:03 -0800243};
buzbee67bf8852011-08-17 17:51:35 -0700244
245struct BasicBlockDataFlow;
246
247/* For successorBlockList */
Elliott Hughes719ace42012-03-09 18:06:03 -0800248enum BlockListType {
Bill Buzbeea114add2012-05-03 15:00:40 -0700249 kNotUsed = 0,
250 kCatch,
251 kPackedSwitch,
252 kSparseSwitch,
Elliott Hughes719ace42012-03-09 18:06:03 -0800253};
buzbee67bf8852011-08-17 17:51:35 -0700254
Elliott Hughes719ace42012-03-09 18:06:03 -0800255struct BasicBlock {
Bill Buzbeea114add2012-05-03 15:00:40 -0700256 int id;
257 int dfsId;
258 bool visited;
259 bool hidden;
260 bool catchEntry;
buzbee0967a252012-09-14 10:43:54 -0700261 bool explicitThrow;
262 bool conditionalBranch;
buzbee2cfc6392012-05-07 14:51:40 -0700263 bool hasReturn;
Bill Buzbeea114add2012-05-03 15:00:40 -0700264 uint16_t startOffset;
265 uint16_t nestingDepth;
Bill Buzbeea114add2012-05-03 15:00:40 -0700266 BBType blockType;
Bill Buzbeea114add2012-05-03 15:00:40 -0700267 MIR* firstMIRInsn;
268 MIR* lastMIRInsn;
269 BasicBlock* fallThrough;
270 BasicBlock* taken;
271 BasicBlock* iDom; // Immediate dominator
272 BasicBlockDataFlow* dataFlowInfo;
273 GrowableList* predecessors;
274 ArenaBitVector* dominators;
275 ArenaBitVector* iDominated; // Set nodes being immediately dominated
276 ArenaBitVector* domFrontier; // Dominance frontier
277 struct { // For one-to-many successors like
278 BlockListType blockListType; // switch and exception handling
279 GrowableList blocks;
280 } successorBlockList;
Elliott Hughes719ace42012-03-09 18:06:03 -0800281};
buzbee67bf8852011-08-17 17:51:35 -0700282
283/*
284 * The "blocks" field in "successorBlockList" points to an array of
285 * elements with the type "SuccessorBlockInfo".
286 * For catch blocks, key is type index for the exception.
287 * For swtich blocks, key is the case value.
288 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800289struct SuccessorBlockInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700290 BasicBlock* block;
291 int key;
Elliott Hughes719ace42012-03-09 18:06:03 -0800292};
buzbee67bf8852011-08-17 17:51:35 -0700293
294struct LoopAnalysis;
295struct RegisterPool;
buzbeeba938cb2012-02-03 14:47:55 -0800296struct ArenaMemBlock;
297struct Memstats;
buzbee67bf8852011-08-17 17:51:35 -0700298
Elliott Hughes719ace42012-03-09 18:06:03 -0800299enum AssemblerStatus {
Bill Buzbeea114add2012-05-03 15:00:40 -0700300 kSuccess,
301 kRetryAll,
Elliott Hughes719ace42012-03-09 18:06:03 -0800302};
buzbee67bf8852011-08-17 17:51:35 -0700303
buzbee5b537102012-01-17 17:33:47 -0800304#define NOTVISITED (-1)
305
Elliott Hughes719ace42012-03-09 18:06:03 -0800306struct CompilationUnit {
Elliott Hughese52e49b2012-04-02 16:05:44 -0700307 CompilationUnit()
Bill Buzbeea114add2012-05-03 15:00:40 -0700308 : numBlocks(0),
309 compiler(NULL),
310 class_linker(NULL),
311 dex_file(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700312 class_loader(NULL),
313 method_idx(0),
314 code_item(NULL),
315 access_flags(0),
Ian Rogers08f753d2012-08-24 14:35:25 -0700316 invoke_type(kDirect),
Bill Buzbeea114add2012-05-03 15:00:40 -0700317 shorty(NULL),
318 firstLIRInsn(NULL),
319 lastLIRInsn(NULL),
320 literalList(NULL),
321 methodLiteralList(NULL),
322 codeLiteralList(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700323 disableOpt(0),
324 enableDebug(0),
Bill Buzbeea114add2012-05-03 15:00:40 -0700325 dataOffset(0),
326 totalSize(0),
327 assemblerStatus(kSuccess),
328 assemblerRetries(0),
329 genDebugger(false),
330 printMe(false),
Bill Buzbeea114add2012-05-03 15:00:40 -0700331 hasLoop(false),
332 hasInvoke(false),
Bill Buzbeea114add2012-05-03 15:00:40 -0700333 qdMode(false),
Bill Buzbeea114add2012-05-03 15:00:40 -0700334 regPool(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700335 instructionSet(kNone),
336 numSSARegs(0),
337 ssaBaseVRegs(NULL),
338 ssaSubscripts(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700339 ssaStrings(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700340 vRegToSSAMap(NULL),
341 SSALastDefs(NULL),
342 isConstantV(NULL),
343 constantValues(NULL),
344 phiAliasMap(NULL),
345 phiList(NULL),
346 regLocation(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700347 promotionMap(NULL),
348 methodSReg(0),
Bill Buzbeea114add2012-05-03 15:00:40 -0700349 numReachableBlocks(0),
350 numDalvikRegisters(0),
351 entryBlock(NULL),
352 exitBlock(NULL),
353 curBlock(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700354 iDomList(NULL),
355 tryBlockAddr(NULL),
356 defBlockMatrix(NULL),
357 tempBlockV(NULL),
358 tempDalvikRegisterV(NULL),
359 tempSSARegisterV(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700360 tempSSABlockIdV(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700361 blockLabelList(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700362 numIns(0),
363 numOuts(0),
364 numRegs(0),
365 numCoreSpills(0),
366 numFPSpills(0),
367 numCompilerTemps(0),
368 frameSize(0),
369 coreSpillMask(0U),
370 fpSpillMask(0U),
371 attrs(0U),
372 currentDalvikOffset(0),
373 insns(NULL),
374 insnsSize(0U),
375 disableDataflow(false),
376 defCount(0),
377 compilerFlipMatch(false),
378 arenaHead(NULL),
379 currentArena(NULL),
380 numArenaBlocks(0),
381 mstats(NULL),
buzbeed1643e42012-09-05 14:06:51 -0700382 checkstats(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700383 genBitcode(false),
384 context(NULL),
385 module(NULL),
386 func(NULL),
387 intrinsic_helper(NULL),
388 irb(NULL),
389 placeholderBB(NULL),
390 entryBB(NULL),
buzbee4be777b2012-07-12 14:38:18 -0700391 entryTargetBB(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700392 tempName(0),
buzbeeb03f4872012-06-11 15:22:11 -0700393 numShadowFrameEntries(0),
394 shadowMap(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700395#ifndef NDEBUG
396 liveSReg(0),
397#endif
398 opcodeCount(NULL) {}
Elliott Hughese52e49b2012-04-02 16:05:44 -0700399
Bill Buzbeea114add2012-05-03 15:00:40 -0700400 int numBlocks;
401 GrowableList blockList;
402 Compiler* compiler; // Compiler driving this compiler
403 ClassLinker* class_linker; // Linker to resolve fields and methods
404 const DexFile* dex_file; // DexFile containing the method being compiled
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700405 jobject class_loader; // compiling method's class loader
Bill Buzbeea114add2012-05-03 15:00:40 -0700406 uint32_t method_idx; // compiling method's index into method_ids of DexFile
407 const DexFile::CodeItem* code_item; // compiling method's DexFile code_item
408 uint32_t access_flags; // compiling method's access flags
Ian Rogers08f753d2012-08-24 14:35:25 -0700409 InvokeType invoke_type; // compiling method's invocation type
Bill Buzbeea114add2012-05-03 15:00:40 -0700410 const char* shorty; // compiling method's shorty
411 LIR* firstLIRInsn;
412 LIR* lastLIRInsn;
413 LIR* literalList; // Constants
414 LIR* methodLiteralList; // Method literals requiring patching
415 LIR* codeLiteralList; // Code literals requiring patching
Bill Buzbeea114add2012-05-03 15:00:40 -0700416 uint32_t disableOpt; // optControlVector flags
417 uint32_t enableDebug; // debugControlVector flags
Bill Buzbeea114add2012-05-03 15:00:40 -0700418 int dataOffset; // starting offset of literal pool
419 int totalSize; // header + code size
420 AssemblerStatus assemblerStatus; // Success or fix and retry
421 int assemblerRetries;
422 std::vector<uint8_t> codeBuffer;
Bill Buzbeea5b30242012-09-28 07:19:44 -0700423 /*
424 * Holds mapping from native PC to dex PC for safepoints where we may deoptimize.
425 * Native PC is on the return address of the safepointed operation. Dex PC is for
426 * the instruction being executed at the safepoint.
427 */
428 std::vector<uint32_t> pc2dexMappingTable;
429 /*
430 * Holds mapping from Dex PC to native PC for catch entry points. Native PC and Dex PC
431 * immediately preceed the instruction.
432 */
433 std::vector<uint32_t> dex2pcMappingTable;
434 std::vector<uint32_t> combinedMappingTable;
buzbeeca7a5e42012-08-20 11:12:18 -0700435 std::vector<uint32_t> coreVmapTable;
436 std::vector<uint32_t> fpVmapTable;
Ian Rogers0c7abda2012-09-19 13:33:42 -0700437 std::vector<uint8_t> nativeGcMap;
Bill Buzbeea114add2012-05-03 15:00:40 -0700438 bool genDebugger; // Generate code for debugger
439 bool printMe;
Bill Buzbeea114add2012-05-03 15:00:40 -0700440 bool hasLoop; // Contains a loop
441 bool hasInvoke; // Contains an invoke instruction
Bill Buzbeea114add2012-05-03 15:00:40 -0700442 bool qdMode; // Compile for code size/compile time
Bill Buzbeea114add2012-05-03 15:00:40 -0700443 RegisterPool* regPool;
Bill Buzbeea114add2012-05-03 15:00:40 -0700444 InstructionSet instructionSet;
445 /* Number of total regs used in the whole cUnit after SSA transformation */
446 int numSSARegs;
447 /* Map SSA reg i to the base virtual register/subscript */
448 GrowableList* ssaBaseVRegs;
449 GrowableList* ssaSubscripts;
buzbee2cfc6392012-05-07 14:51:40 -0700450 GrowableList* ssaStrings;
buzbee67bf8852011-08-17 17:51:35 -0700451
Bill Buzbeea114add2012-05-03 15:00:40 -0700452 /* The following are new data structures to support SSA representations */
453 /* Map original Dalvik virtual reg i to the current SSA name */
454 int* vRegToSSAMap; // length == method->registersSize
455 int* SSALastDefs; // length == method->registersSize
456 ArenaBitVector* isConstantV; // length == numSSAReg
457 int* constantValues; // length == numSSAReg
458 int* phiAliasMap; // length == numSSAReg
459 MIR* phiList;
buzbee67bf8852011-08-17 17:51:35 -0700460
Bill Buzbeea114add2012-05-03 15:00:40 -0700461 /* Use counts of ssa names */
462 GrowableList useCounts; // Weighted by nesting depth
463 GrowableList rawUseCounts; // Not weighted
buzbee239c4e72012-03-16 08:42:29 -0700464
Bill Buzbeea114add2012-05-03 15:00:40 -0700465 /* Optimization support */
466 GrowableList loopHeaders;
buzbee239c4e72012-03-16 08:42:29 -0700467
Bill Buzbeea114add2012-05-03 15:00:40 -0700468 /* Map SSA names to location */
469 RegLocation* regLocation;
buzbee67bf8852011-08-17 17:51:35 -0700470
Bill Buzbeea114add2012-05-03 15:00:40 -0700471 /* Keep track of Dalvik vReg to physical register mappings */
472 PromotionMap* promotionMap;
buzbee67bc2362011-10-11 18:08:40 -0700473
Bill Buzbeea114add2012-05-03 15:00:40 -0700474 /* SSA name for Method* */
475 int methodSReg;
buzbeead8f15e2012-06-18 14:49:45 -0700476 RegLocation methodLoc; // Describes location of method*
buzbeee1965672012-03-11 18:39:19 -0700477
Bill Buzbeea114add2012-05-03 15:00:40 -0700478 int numReachableBlocks;
479 int numDalvikRegisters; // method->registersSize
480 BasicBlock* entryBlock;
481 BasicBlock* exitBlock;
482 BasicBlock* curBlock;
Bill Buzbeea114add2012-05-03 15:00:40 -0700483 GrowableList dfsOrder;
484 GrowableList dfsPostOrder;
485 GrowableList domPostOrderTraversal;
486 GrowableList throwLaunchpads;
487 GrowableList suspendLaunchpads;
488 GrowableList intrinsicLaunchpads;
489 GrowableList compilerTemps;
490 int* iDomList;
491 ArenaBitVector* tryBlockAddr;
492 ArenaBitVector** defBlockMatrix; // numDalvikRegister x numBlocks
493 ArenaBitVector* tempBlockV;
494 ArenaBitVector* tempDalvikRegisterV;
495 ArenaBitVector* tempSSARegisterV; // numSSARegs
buzbee2cfc6392012-05-07 14:51:40 -0700496 int* tempSSABlockIdV; // working storage for Phi labels
buzbeea1da8a52012-07-09 14:00:21 -0700497 LIR* blockLabelList;
Bill Buzbeea114add2012-05-03 15:00:40 -0700498 /*
499 * Frame layout details.
500 * NOTE: for debug support it will be necessary to add a structure
501 * to map the Dalvik virtual registers to the promoted registers.
502 * NOTE: "num" fields are in 4-byte words, "Size" and "Offset" in bytes.
503 */
504 int numIns;
505 int numOuts;
506 int numRegs; // Unlike numDalvikRegisters, does not include ins
507 int numCoreSpills;
508 int numFPSpills;
509 int numCompilerTemps;
510 int frameSize;
511 unsigned int coreSpillMask;
512 unsigned int fpSpillMask;
513 unsigned int attrs;
514 /*
515 * CLEANUP/RESTRUCTURE: The code generation utilities don't have a built-in
516 * mechanism to propagate the original Dalvik opcode address to the
517 * associated generated instructions. For the trace compiler, this wasn't
518 * necessary because the interpreter handled all throws and debugging
519 * requests. For now we'll handle this by placing the Dalvik offset
520 * in the CompilationUnit struct before codegen for each instruction.
521 * The low-level LIR creation utilites will pull it from here. Should
522 * be rewritten.
523 */
524 int currentDalvikOffset;
525 GrowableList switchTables;
526 GrowableList fillArrayData;
527 const u2* insns;
528 u4 insnsSize;
529 bool disableDataflow; // Skip dataflow analysis if possible
530 SafeMap<unsigned int, BasicBlock*> blockMap; // findBlock lookup cache
buzbeed1643e42012-09-05 14:06:51 -0700531 SafeMap<unsigned int, unsigned int> blockIdMap; // Block collapse lookup cache
Bill Buzbeea114add2012-05-03 15:00:40 -0700532 SafeMap<unsigned int, LIR*> boundaryMap; // boundary lookup cache
533 int defCount; // Used to estimate number of SSA names
Elliott Hughese52e49b2012-04-02 16:05:44 -0700534
Bill Buzbeea114add2012-05-03 15:00:40 -0700535 // If non-empty, apply optimizer/debug flags only to matching methods.
536 std::string compilerMethodMatch;
537 // Flips sense of compilerMethodMatch - apply flags if doesn't match.
538 bool compilerFlipMatch;
539 ArenaMemBlock* arenaHead;
540 ArenaMemBlock* currentArena;
541 int numArenaBlocks;
542 Memstats* mstats;
buzbeed1643e42012-09-05 14:06:51 -0700543 Checkstats* checkstats;
buzbee2cfc6392012-05-07 14:51:40 -0700544 bool genBitcode;
buzbee4df2bbd2012-10-11 14:46:06 -0700545 LLVMInfo* llvm_info;
buzbee2cfc6392012-05-07 14:51:40 -0700546 llvm::LLVMContext* context;
547 llvm::Module* module;
548 llvm::Function* func;
549 greenland::IntrinsicHelper* intrinsic_helper;
550 greenland::IRBuilder* irb;
551 llvm::BasicBlock* placeholderBB;
552 llvm::BasicBlock* entryBB;
buzbee4be777b2012-07-12 14:38:18 -0700553 llvm::BasicBlock* entryTargetBB;
buzbee2cfc6392012-05-07 14:51:40 -0700554 std::string bitcode_filename;
555 GrowableList llvmValues;
556 int32_t tempName;
557 SafeMap<llvm::BasicBlock*, LIR*> blockToLabelMap; // llvm bb -> LIR label
558 SafeMap<int32_t, llvm::BasicBlock*> idToBlockMap; // block id -> llvm bb
559 SafeMap<llvm::Value*, RegLocation> locMap; // llvm Value to loc rec
buzbeeb03f4872012-06-11 15:22:11 -0700560 int numShadowFrameEntries;
561 int* shadowMap;
buzbee0967a252012-09-14 10:43:54 -0700562 std::set<llvm::BasicBlock*> llvmBlocks;
buzbee3d661942012-03-14 17:37:27 -0700563#ifndef NDEBUG
Bill Buzbeea114add2012-05-03 15:00:40 -0700564 /*
565 * Sanity checking for the register temp tracking. The same ssa
566 * name should never be associated with one temp register per
567 * instruction compilation.
568 */
569 int liveSReg;
buzbee3d661942012-03-14 17:37:27 -0700570#endif
buzbee6459e7c2012-10-02 14:42:41 -0700571 std::set<uint32_t> catches;
buzbee2cfc6392012-05-07 14:51:40 -0700572 int* opcodeCount; // Count Dalvik opcodes for tuning
Elliott Hughes719ace42012-03-09 18:06:03 -0800573};
buzbee67bf8852011-08-17 17:51:35 -0700574
Elliott Hughes719ace42012-03-09 18:06:03 -0800575enum OpSize {
Bill Buzbeea114add2012-05-03 15:00:40 -0700576 kWord,
577 kLong,
578 kSingle,
579 kDouble,
580 kUnsignedHalf,
581 kSignedHalf,
582 kUnsignedByte,
583 kSignedByte,
Elliott Hughes719ace42012-03-09 18:06:03 -0800584};
buzbeee3acd072012-02-25 17:03:10 -0800585
Elliott Hughes719ace42012-03-09 18:06:03 -0800586enum OpKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700587 kOpMov,
588 kOpMvn,
589 kOpCmp,
590 kOpLsl,
591 kOpLsr,
592 kOpAsr,
593 kOpRor,
594 kOpNot,
595 kOpAnd,
596 kOpOr,
597 kOpXor,
598 kOpNeg,
599 kOpAdd,
600 kOpAdc,
601 kOpSub,
602 kOpSbc,
603 kOpRsub,
604 kOpMul,
605 kOpDiv,
606 kOpRem,
607 kOpBic,
608 kOpCmn,
609 kOpTst,
610 kOpBkpt,
611 kOpBlx,
612 kOpPush,
613 kOpPop,
614 kOp2Char,
615 kOp2Short,
616 kOp2Byte,
617 kOpCondBr,
618 kOpUncondBr,
619 kOpBx,
620 kOpInvalid,
Elliott Hughes719ace42012-03-09 18:06:03 -0800621};
buzbee31a4a6f2012-02-28 15:36:15 -0800622
Ian Rogers680b1bd2012-03-07 20:18:49 -0800623std::ostream& operator<<(std::ostream& os, const OpKind& kind);
624
Elliott Hughes719ace42012-03-09 18:06:03 -0800625enum ConditionCode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700626 kCondEq, // equal
627 kCondNe, // not equal
628 kCondCs, // carry set (unsigned less than)
629 kCondUlt = kCondCs,
630 kCondCc, // carry clear (unsigned greater than or same)
631 kCondUge = kCondCc,
632 kCondMi, // minus
633 kCondPl, // plus, positive or zero
634 kCondVs, // overflow
635 kCondVc, // no overflow
636 kCondHi, // unsigned greater than
637 kCondLs, // unsigned lower or same
638 kCondGe, // signed greater than or equal
639 kCondLt, // signed less than
640 kCondGt, // signed greater than
641 kCondLe, // signed less than or equal
642 kCondAl, // always
643 kCondNv, // never
Elliott Hughes719ace42012-03-09 18:06:03 -0800644};
buzbee31a4a6f2012-02-28 15:36:15 -0800645
Elliott Hughes719ace42012-03-09 18:06:03 -0800646enum ThrowKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700647 kThrowNullPointer,
648 kThrowDivZero,
649 kThrowArrayBounds,
Bill Buzbeea114add2012-05-03 15:00:40 -0700650 kThrowNoSuchMethod,
651 kThrowStackOverflow,
Elliott Hughes719ace42012-03-09 18:06:03 -0800652};
buzbee31a4a6f2012-02-28 15:36:15 -0800653
Elliott Hughes719ace42012-03-09 18:06:03 -0800654struct SwitchTable {
Bill Buzbeea114add2012-05-03 15:00:40 -0700655 int offset;
656 const u2* table; // Original dex table
657 int vaddr; // Dalvik offset of switch opcode
658 LIR* anchor; // Reference instruction for relative offsets
659 LIR** targets; // Array of case targets
Elliott Hughes719ace42012-03-09 18:06:03 -0800660};
buzbee5de34942012-03-01 14:51:57 -0800661
Elliott Hughes719ace42012-03-09 18:06:03 -0800662struct FillArrayData {
Bill Buzbeea114add2012-05-03 15:00:40 -0700663 int offset;
664 const u2* table; // Original dex table
665 int size;
666 int vaddr; // Dalvik offset of FILL_ARRAY_DATA opcode
Elliott Hughes719ace42012-03-09 18:06:03 -0800667};
buzbee5de34942012-03-01 14:51:57 -0800668
buzbee16da88c2012-03-20 10:38:17 -0700669#define MAX_PATTERN_LEN 5
670
671enum SpecialCaseHandler {
Bill Buzbeea114add2012-05-03 15:00:40 -0700672 kNoHandler,
673 kNullMethod,
674 kConstFunction,
675 kIGet,
676 kIGetBoolean,
677 kIGetObject,
678 kIGetByte,
679 kIGetChar,
680 kIGetShort,
681 kIGetWide,
682 kIPut,
683 kIPutBoolean,
684 kIPutObject,
685 kIPutByte,
686 kIPutChar,
687 kIPutShort,
688 kIPutWide,
689 kIdentity,
buzbee16da88c2012-03-20 10:38:17 -0700690};
691
692struct CodePattern {
Bill Buzbeea114add2012-05-03 15:00:40 -0700693 const Instruction::Code opcodes[MAX_PATTERN_LEN];
694 const SpecialCaseHandler handlerCode;
buzbee16da88c2012-03-20 10:38:17 -0700695};
696
697static const CodePattern specialPatterns[] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700698 {{Instruction::RETURN_VOID}, kNullMethod},
699 {{Instruction::CONST, Instruction::RETURN}, kConstFunction},
700 {{Instruction::CONST_4, Instruction::RETURN}, kConstFunction},
701 {{Instruction::CONST_4, Instruction::RETURN_OBJECT}, kConstFunction},
702 {{Instruction::CONST_16, Instruction::RETURN}, kConstFunction},
703 {{Instruction::IGET, Instruction:: RETURN}, kIGet},
704 {{Instruction::IGET_BOOLEAN, Instruction::RETURN}, kIGetBoolean},
705 {{Instruction::IGET_OBJECT, Instruction::RETURN_OBJECT}, kIGetObject},
706 {{Instruction::IGET_BYTE, Instruction::RETURN}, kIGetByte},
707 {{Instruction::IGET_CHAR, Instruction::RETURN}, kIGetChar},
708 {{Instruction::IGET_SHORT, Instruction::RETURN}, kIGetShort},
709 {{Instruction::IGET_WIDE, Instruction::RETURN_WIDE}, kIGetWide},
710 {{Instruction::IPUT, Instruction::RETURN_VOID}, kIPut},
711 {{Instruction::IPUT_BOOLEAN, Instruction::RETURN_VOID}, kIPutBoolean},
712 {{Instruction::IPUT_OBJECT, Instruction::RETURN_VOID}, kIPutObject},
713 {{Instruction::IPUT_BYTE, Instruction::RETURN_VOID}, kIPutByte},
714 {{Instruction::IPUT_CHAR, Instruction::RETURN_VOID}, kIPutChar},
715 {{Instruction::IPUT_SHORT, Instruction::RETURN_VOID}, kIPutShort},
716 {{Instruction::IPUT_WIDE, Instruction::RETURN_VOID}, kIPutWide},
717 {{Instruction::RETURN}, kIdentity},
718 {{Instruction::RETURN_OBJECT}, kIdentity},
719 {{Instruction::RETURN_WIDE}, kIdentity},
buzbee16da88c2012-03-20 10:38:17 -0700720};
buzbee5de34942012-03-01 14:51:57 -0800721
buzbee5abfa3e2012-01-31 17:01:43 -0800722BasicBlock* oatNewBB(CompilationUnit* cUnit, BBType blockType, int blockId);
buzbee67bf8852011-08-17 17:51:35 -0700723
724void oatAppendMIR(BasicBlock* bb, MIR* mir);
725
726void oatPrependMIR(BasicBlock* bb, MIR* mir);
727
728void oatInsertMIRAfter(BasicBlock* bb, MIR* currentMIR, MIR* newMIR);
729
730void oatAppendLIR(CompilationUnit* cUnit, LIR* lir);
731
732void oatInsertLIRBefore(LIR* currentLIR, LIR* newLIR);
733
734void oatInsertLIRAfter(LIR* currentLIR, LIR* newLIR);
735
buzbee15bf9802012-06-12 17:49:27 -0700736MIR* oatFindMoveResult(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir);
buzbee67bf8852011-08-17 17:51:35 -0700737/* Debug Utilities */
738void oatDumpCompilationUnit(CompilationUnit* cUnit);
739
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800740} // namespace art
741
buzbee67bf8852011-08-17 17:51:35 -0700742#endif // ART_SRC_COMPILER_COMPILER_IR_H_