blob: 4327fb68efc02c65a958f69c75a042d965e298cd [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)
buzbeeb046e162012-10-30 15:48:42 -0700131#define INVALID_OFFSET (0xDEADF00FU)
buzbee67bf8852011-08-17 17:51:35 -0700132
buzbeee1965672012-03-11 18:39:19 -0700133/* SSA encodings for special registers */
buzbee9c044ce2012-03-18 13:24:07 -0700134#define SSA_METHOD_BASEREG (-2)
buzbeee1965672012-03-11 18:39:19 -0700135/* First compiler temp basereg, grows smaller */
buzbee9c044ce2012-03-18 13:24:07 -0700136#define SSA_CTEMP_BASEREG (SSA_METHOD_BASEREG - 1)
buzbeee1965672012-03-11 18:39:19 -0700137
buzbee99ba9642012-01-25 14:23:14 -0800138/*
139 * Some code patterns cause the generation of excessively large
140 * methods - in particular initialization sequences. There isn't much
141 * benefit in optimizing these methods, and the cost can be very high.
142 * We attempt to identify these cases, and avoid performing most dataflow
143 * analysis. Two thresholds are used - one for known initializers and one
buzbee5abfa3e2012-01-31 17:01:43 -0800144 * for everything else.
buzbee99ba9642012-01-25 14:23:14 -0800145 */
buzbee5abfa3e2012-01-31 17:01:43 -0800146#define MANY_BLOCKS_INITIALIZER 1000 /* Threshold for switching dataflow off */
147#define MANY_BLOCKS 4000 /* Non-initializer threshold */
buzbee99ba9642012-01-25 14:23:14 -0800148
Elliott Hughes719ace42012-03-09 18:06:03 -0800149enum BBType {
Bill Buzbeea114add2012-05-03 15:00:40 -0700150 kEntryBlock,
151 kDalvikByteCode,
152 kExitBlock,
153 kExceptionHandling,
buzbeed1643e42012-09-05 14:06:51 -0700154 kDead,
Elliott Hughes719ace42012-03-09 18:06:03 -0800155};
buzbee67bf8852011-08-17 17:51:35 -0700156
buzbee31a4a6f2012-02-28 15:36:15 -0800157/* Utility macros to traverse the LIR list */
158#define NEXT_LIR(lir) (lir->next)
159#define PREV_LIR(lir) (lir->prev)
160
Elliott Hughes719ace42012-03-09 18:06:03 -0800161struct LIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700162 int offset; // Offset of this instruction
163 int dalvikOffset; // Offset of Dalvik opcode
164 LIR* next;
165 LIR* prev;
166 LIR* target;
167 int opcode;
168 int operands[5]; // [0..4] = [dest, src1, src2, extra, extra2]
169 struct {
170 bool isNop:1; // LIR is optimized away
171 bool pcRelFixup:1; // May need pc-relative fixup
Bill Buzbeea114add2012-05-03 15:00:40 -0700172 unsigned int size:5; // in bytes
buzbeef5f5a122012-09-21 13:57:36 -0700173 unsigned int unused:25;
Bill Buzbeea114add2012-05-03 15:00:40 -0700174 } flags;
175 int aliasInfo; // For Dalvik register & litpool disambiguation
176 u8 useMask; // Resource mask for use
177 u8 defMask; // Resource mask for def
Elliott Hughes719ace42012-03-09 18:06:03 -0800178};
buzbee67bf8852011-08-17 17:51:35 -0700179
buzbeeb046e162012-10-30 15:48:42 -0700180/* Shared pseudo opcodes - must be < 0 */
181enum LIRPseudoOpcode {
182 kPseudoExportedPC = -18,
183 kPseudoSafepointPC = -17,
184 kPseudoIntrinsicRetry = -16,
185 kPseudoSuspendTarget = -15,
186 kPseudoThrowTarget = -14,
187 kPseudoCaseLabel = -13,
188 kPseudoMethodEntry = -12,
189 kPseudoMethodExit = -11,
190 kPseudoBarrier = -10,
191 kPseudoExtended = -9,
192 kPseudoSSARep = -8,
193 kPseudoEntryBlock = -7,
194 kPseudoExitBlock = -6,
195 kPseudoTargetLabel = -5,
196 kPseudoDalvikByteCodeBoundary = -4,
197 kPseudoPseudoAlign4 = -3,
198 kPseudoEHBlockLabel = -2,
199 kPseudoNormalBlockLabel = -1,
200};
201
buzbee67bf8852011-08-17 17:51:35 -0700202enum ExtendedMIROpcode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700203 kMirOpFirst = kNumPackedOpcodes,
204 kMirOpPhi = kMirOpFirst,
205 kMirOpCopy,
206 kMirOpFusedCmplFloat,
207 kMirOpFusedCmpgFloat,
208 kMirOpFusedCmplDouble,
209 kMirOpFusedCmpgDouble,
210 kMirOpFusedCmpLong,
211 kMirOpNop,
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700212 kMirOpNullCheck,
213 kMirOpRangeCheck,
214 kMirOpDivZeroCheck,
215 kMirOpCheck,
Bill Buzbeea114add2012-05-03 15:00:40 -0700216 kMirOpLast,
buzbee67bf8852011-08-17 17:51:35 -0700217};
218
219struct SSARepresentation;
220
Elliott Hughes719ace42012-03-09 18:06:03 -0800221enum MIROptimizationFlagPositons {
Bill Buzbeea114add2012-05-03 15:00:40 -0700222 kMIRIgnoreNullCheck = 0,
223 kMIRNullCheckOnly,
224 kMIRIgnoreRangeCheck,
225 kMIRRangeCheckOnly,
226 kMIRInlined, // Invoke is inlined (ie dead)
227 kMIRInlinedPred, // Invoke is inlined via prediction
228 kMIRCallee, // Instruction is inlined from callee
229 kMIRIgnoreSuspendCheck,
230 kMIRDup,
231 kMIRMark, // Temporary node mark
Elliott Hughes719ace42012-03-09 18:06:03 -0800232};
buzbee67bf8852011-08-17 17:51:35 -0700233
234#define MIR_IGNORE_NULL_CHECK (1 << kMIRIgnoreNullCheck)
235#define MIR_NULL_CHECK_ONLY (1 << kMIRNullCheckOnly)
236#define MIR_IGNORE_RANGE_CHECK (1 << kMIRIgnoreRangeCheck)
237#define MIR_RANGE_CHECK_ONLY (1 << kMIRRangeCheckOnly)
238#define MIR_INLINED (1 << kMIRInlined)
239#define MIR_INLINED_PRED (1 << kMIRInlinedPred)
240#define MIR_CALLEE (1 << kMIRCallee)
buzbeec1f45042011-09-21 16:03:19 -0700241#define MIR_IGNORE_SUSPEND_CHECK (1 << kMIRIgnoreSuspendCheck)
buzbeee1965672012-03-11 18:39:19 -0700242#define MIR_DUP (1 << kMIRDup)
buzbee239c4e72012-03-16 08:42:29 -0700243#define MIR_MARK (1 << kMIRMark)
buzbee67bf8852011-08-17 17:51:35 -0700244
buzbeed1643e42012-09-05 14:06:51 -0700245struct Checkstats {
246 int nullChecks;
247 int nullChecksEliminated;
248 int rangeChecks;
249 int rangeChecksEliminated;
250};
251
Elliott Hughes719ace42012-03-09 18:06:03 -0800252struct MIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700253 DecodedInstruction dalvikInsn;
254 unsigned int width;
255 unsigned int offset;
256 MIR* prev;
257 MIR* next;
258 SSARepresentation* ssaRep;
259 int optimizationFlags;
Bill Buzbeea114add2012-05-03 15:00:40 -0700260 union {
Bill Buzbeea114add2012-05-03 15:00:40 -0700261 // Used to quickly locate all Phi opcodes
262 MIR* phiNext;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700263 // Establish link between two halves of throwing instructions
264 MIR* throwInsn;
Bill Buzbeea114add2012-05-03 15:00:40 -0700265 } meta;
Elliott Hughes719ace42012-03-09 18:06:03 -0800266};
buzbee67bf8852011-08-17 17:51:35 -0700267
268struct BasicBlockDataFlow;
269
270/* For successorBlockList */
Elliott Hughes719ace42012-03-09 18:06:03 -0800271enum BlockListType {
Bill Buzbeea114add2012-05-03 15:00:40 -0700272 kNotUsed = 0,
273 kCatch,
274 kPackedSwitch,
275 kSparseSwitch,
Elliott Hughes719ace42012-03-09 18:06:03 -0800276};
buzbee67bf8852011-08-17 17:51:35 -0700277
Elliott Hughes719ace42012-03-09 18:06:03 -0800278struct BasicBlock {
Bill Buzbeea114add2012-05-03 15:00:40 -0700279 int id;
280 int dfsId;
281 bool visited;
282 bool hidden;
283 bool catchEntry;
buzbee0967a252012-09-14 10:43:54 -0700284 bool explicitThrow;
285 bool conditionalBranch;
buzbee2cfc6392012-05-07 14:51:40 -0700286 bool hasReturn;
Bill Buzbeea114add2012-05-03 15:00:40 -0700287 uint16_t startOffset;
288 uint16_t nestingDepth;
Bill Buzbeea114add2012-05-03 15:00:40 -0700289 BBType blockType;
Bill Buzbeea114add2012-05-03 15:00:40 -0700290 MIR* firstMIRInsn;
291 MIR* lastMIRInsn;
292 BasicBlock* fallThrough;
293 BasicBlock* taken;
294 BasicBlock* iDom; // Immediate dominator
295 BasicBlockDataFlow* dataFlowInfo;
296 GrowableList* predecessors;
297 ArenaBitVector* dominators;
298 ArenaBitVector* iDominated; // Set nodes being immediately dominated
299 ArenaBitVector* domFrontier; // Dominance frontier
300 struct { // For one-to-many successors like
301 BlockListType blockListType; // switch and exception handling
302 GrowableList blocks;
303 } successorBlockList;
Elliott Hughes719ace42012-03-09 18:06:03 -0800304};
buzbee67bf8852011-08-17 17:51:35 -0700305
306/*
307 * The "blocks" field in "successorBlockList" points to an array of
308 * elements with the type "SuccessorBlockInfo".
309 * For catch blocks, key is type index for the exception.
310 * For swtich blocks, key is the case value.
311 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800312struct SuccessorBlockInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700313 BasicBlock* block;
314 int key;
Elliott Hughes719ace42012-03-09 18:06:03 -0800315};
buzbee67bf8852011-08-17 17:51:35 -0700316
317struct LoopAnalysis;
318struct RegisterPool;
buzbeeba938cb2012-02-03 14:47:55 -0800319struct ArenaMemBlock;
320struct Memstats;
buzbee67bf8852011-08-17 17:51:35 -0700321
Elliott Hughes719ace42012-03-09 18:06:03 -0800322enum AssemblerStatus {
Bill Buzbeea114add2012-05-03 15:00:40 -0700323 kSuccess,
324 kRetryAll,
Elliott Hughes719ace42012-03-09 18:06:03 -0800325};
buzbee67bf8852011-08-17 17:51:35 -0700326
buzbee5b537102012-01-17 17:33:47 -0800327#define NOTVISITED (-1)
328
Elliott Hughes719ace42012-03-09 18:06:03 -0800329struct CompilationUnit {
Elliott Hughese52e49b2012-04-02 16:05:44 -0700330 CompilationUnit()
Bill Buzbeea114add2012-05-03 15:00:40 -0700331 : numBlocks(0),
332 compiler(NULL),
333 class_linker(NULL),
334 dex_file(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700335 class_loader(NULL),
336 method_idx(0),
337 code_item(NULL),
338 access_flags(0),
Ian Rogers08f753d2012-08-24 14:35:25 -0700339 invoke_type(kDirect),
Bill Buzbeea114add2012-05-03 15:00:40 -0700340 shorty(NULL),
341 firstLIRInsn(NULL),
342 lastLIRInsn(NULL),
343 literalList(NULL),
344 methodLiteralList(NULL),
345 codeLiteralList(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700346 disableOpt(0),
347 enableDebug(0),
Bill Buzbeea114add2012-05-03 15:00:40 -0700348 dataOffset(0),
349 totalSize(0),
350 assemblerStatus(kSuccess),
351 assemblerRetries(0),
Bill Buzbeea114add2012-05-03 15:00:40 -0700352 printMe(false),
Bill Buzbeea114add2012-05-03 15:00:40 -0700353 hasLoop(false),
354 hasInvoke(false),
Bill Buzbeea114add2012-05-03 15:00:40 -0700355 qdMode(false),
Bill Buzbeea114add2012-05-03 15:00:40 -0700356 regPool(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700357 instructionSet(kNone),
358 numSSARegs(0),
359 ssaBaseVRegs(NULL),
360 ssaSubscripts(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700361 ssaStrings(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700362 vRegToSSAMap(NULL),
363 SSALastDefs(NULL),
364 isConstantV(NULL),
365 constantValues(NULL),
366 phiAliasMap(NULL),
367 phiList(NULL),
368 regLocation(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700369 promotionMap(NULL),
370 methodSReg(0),
Bill Buzbeea114add2012-05-03 15:00:40 -0700371 numReachableBlocks(0),
372 numDalvikRegisters(0),
373 entryBlock(NULL),
374 exitBlock(NULL),
375 curBlock(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700376 iDomList(NULL),
377 tryBlockAddr(NULL),
378 defBlockMatrix(NULL),
379 tempBlockV(NULL),
380 tempDalvikRegisterV(NULL),
381 tempSSARegisterV(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700382 tempSSABlockIdV(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700383 blockLabelList(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700384 numIns(0),
385 numOuts(0),
386 numRegs(0),
387 numCoreSpills(0),
388 numFPSpills(0),
389 numCompilerTemps(0),
390 frameSize(0),
391 coreSpillMask(0U),
392 fpSpillMask(0U),
393 attrs(0U),
394 currentDalvikOffset(0),
395 insns(NULL),
396 insnsSize(0U),
397 disableDataflow(false),
398 defCount(0),
399 compilerFlipMatch(false),
400 arenaHead(NULL),
401 currentArena(NULL),
402 numArenaBlocks(0),
403 mstats(NULL),
buzbeed1643e42012-09-05 14:06:51 -0700404 checkstats(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700405 genBitcode(false),
406 context(NULL),
407 module(NULL),
408 func(NULL),
409 intrinsic_helper(NULL),
410 irb(NULL),
411 placeholderBB(NULL),
412 entryBB(NULL),
buzbee4be777b2012-07-12 14:38:18 -0700413 entryTargetBB(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700414 tempName(0),
buzbeeb03f4872012-06-11 15:22:11 -0700415 numShadowFrameEntries(0),
416 shadowMap(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700417#ifndef NDEBUG
418 liveSReg(0),
419#endif
420 opcodeCount(NULL) {}
Elliott Hughese52e49b2012-04-02 16:05:44 -0700421
Bill Buzbeea114add2012-05-03 15:00:40 -0700422 int numBlocks;
423 GrowableList blockList;
424 Compiler* compiler; // Compiler driving this compiler
425 ClassLinker* class_linker; // Linker to resolve fields and methods
426 const DexFile* dex_file; // DexFile containing the method being compiled
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700427 jobject class_loader; // compiling method's class loader
Bill Buzbeea114add2012-05-03 15:00:40 -0700428 uint32_t method_idx; // compiling method's index into method_ids of DexFile
429 const DexFile::CodeItem* code_item; // compiling method's DexFile code_item
430 uint32_t access_flags; // compiling method's access flags
Ian Rogers08f753d2012-08-24 14:35:25 -0700431 InvokeType invoke_type; // compiling method's invocation type
Bill Buzbeea114add2012-05-03 15:00:40 -0700432 const char* shorty; // compiling method's shorty
433 LIR* firstLIRInsn;
434 LIR* lastLIRInsn;
435 LIR* literalList; // Constants
436 LIR* methodLiteralList; // Method literals requiring patching
437 LIR* codeLiteralList; // Code literals requiring patching
Bill Buzbeea114add2012-05-03 15:00:40 -0700438 uint32_t disableOpt; // optControlVector flags
439 uint32_t enableDebug; // debugControlVector flags
Bill Buzbeea114add2012-05-03 15:00:40 -0700440 int dataOffset; // starting offset of literal pool
441 int totalSize; // header + code size
442 AssemblerStatus assemblerStatus; // Success or fix and retry
443 int assemblerRetries;
444 std::vector<uint8_t> codeBuffer;
Bill Buzbeea5b30242012-09-28 07:19:44 -0700445 /*
446 * Holds mapping from native PC to dex PC for safepoints where we may deoptimize.
447 * Native PC is on the return address of the safepointed operation. Dex PC is for
448 * the instruction being executed at the safepoint.
449 */
450 std::vector<uint32_t> pc2dexMappingTable;
451 /*
452 * Holds mapping from Dex PC to native PC for catch entry points. Native PC and Dex PC
453 * immediately preceed the instruction.
454 */
455 std::vector<uint32_t> dex2pcMappingTable;
456 std::vector<uint32_t> combinedMappingTable;
buzbeeca7a5e42012-08-20 11:12:18 -0700457 std::vector<uint32_t> coreVmapTable;
458 std::vector<uint32_t> fpVmapTable;
Ian Rogers0c7abda2012-09-19 13:33:42 -0700459 std::vector<uint8_t> nativeGcMap;
Bill Buzbeea114add2012-05-03 15:00:40 -0700460 bool printMe;
Bill Buzbeea114add2012-05-03 15:00:40 -0700461 bool hasLoop; // Contains a loop
462 bool hasInvoke; // Contains an invoke instruction
Bill Buzbeea114add2012-05-03 15:00:40 -0700463 bool qdMode; // Compile for code size/compile time
Bill Buzbeea114add2012-05-03 15:00:40 -0700464 RegisterPool* regPool;
Bill Buzbeea114add2012-05-03 15:00:40 -0700465 InstructionSet instructionSet;
466 /* Number of total regs used in the whole cUnit after SSA transformation */
467 int numSSARegs;
468 /* Map SSA reg i to the base virtual register/subscript */
469 GrowableList* ssaBaseVRegs;
470 GrowableList* ssaSubscripts;
buzbee2cfc6392012-05-07 14:51:40 -0700471 GrowableList* ssaStrings;
buzbee67bf8852011-08-17 17:51:35 -0700472
Bill Buzbeea114add2012-05-03 15:00:40 -0700473 /* The following are new data structures to support SSA representations */
474 /* Map original Dalvik virtual reg i to the current SSA name */
475 int* vRegToSSAMap; // length == method->registersSize
476 int* SSALastDefs; // length == method->registersSize
477 ArenaBitVector* isConstantV; // length == numSSAReg
478 int* constantValues; // length == numSSAReg
479 int* phiAliasMap; // length == numSSAReg
480 MIR* phiList;
buzbee67bf8852011-08-17 17:51:35 -0700481
Bill Buzbeea114add2012-05-03 15:00:40 -0700482 /* Use counts of ssa names */
483 GrowableList useCounts; // Weighted by nesting depth
484 GrowableList rawUseCounts; // Not weighted
buzbee239c4e72012-03-16 08:42:29 -0700485
Bill Buzbeea114add2012-05-03 15:00:40 -0700486 /* Optimization support */
487 GrowableList loopHeaders;
buzbee239c4e72012-03-16 08:42:29 -0700488
Bill Buzbeea114add2012-05-03 15:00:40 -0700489 /* Map SSA names to location */
490 RegLocation* regLocation;
buzbee67bf8852011-08-17 17:51:35 -0700491
Bill Buzbeea114add2012-05-03 15:00:40 -0700492 /* Keep track of Dalvik vReg to physical register mappings */
493 PromotionMap* promotionMap;
buzbee67bc2362011-10-11 18:08:40 -0700494
Bill Buzbeea114add2012-05-03 15:00:40 -0700495 /* SSA name for Method* */
496 int methodSReg;
buzbeead8f15e2012-06-18 14:49:45 -0700497 RegLocation methodLoc; // Describes location of method*
buzbeee1965672012-03-11 18:39:19 -0700498
Bill Buzbeea114add2012-05-03 15:00:40 -0700499 int numReachableBlocks;
500 int numDalvikRegisters; // method->registersSize
501 BasicBlock* entryBlock;
502 BasicBlock* exitBlock;
503 BasicBlock* curBlock;
Bill Buzbeea114add2012-05-03 15:00:40 -0700504 GrowableList dfsOrder;
505 GrowableList dfsPostOrder;
506 GrowableList domPostOrderTraversal;
507 GrowableList throwLaunchpads;
508 GrowableList suspendLaunchpads;
509 GrowableList intrinsicLaunchpads;
510 GrowableList compilerTemps;
511 int* iDomList;
512 ArenaBitVector* tryBlockAddr;
513 ArenaBitVector** defBlockMatrix; // numDalvikRegister x numBlocks
514 ArenaBitVector* tempBlockV;
515 ArenaBitVector* tempDalvikRegisterV;
516 ArenaBitVector* tempSSARegisterV; // numSSARegs
buzbee2cfc6392012-05-07 14:51:40 -0700517 int* tempSSABlockIdV; // working storage for Phi labels
buzbeea1da8a52012-07-09 14:00:21 -0700518 LIR* blockLabelList;
Bill Buzbeea114add2012-05-03 15:00:40 -0700519 /*
520 * Frame layout details.
521 * NOTE: for debug support it will be necessary to add a structure
522 * to map the Dalvik virtual registers to the promoted registers.
523 * NOTE: "num" fields are in 4-byte words, "Size" and "Offset" in bytes.
524 */
525 int numIns;
526 int numOuts;
527 int numRegs; // Unlike numDalvikRegisters, does not include ins
528 int numCoreSpills;
529 int numFPSpills;
530 int numCompilerTemps;
531 int frameSize;
532 unsigned int coreSpillMask;
533 unsigned int fpSpillMask;
534 unsigned int attrs;
535 /*
536 * CLEANUP/RESTRUCTURE: The code generation utilities don't have a built-in
537 * mechanism to propagate the original Dalvik opcode address to the
538 * associated generated instructions. For the trace compiler, this wasn't
539 * necessary because the interpreter handled all throws and debugging
540 * requests. For now we'll handle this by placing the Dalvik offset
541 * in the CompilationUnit struct before codegen for each instruction.
542 * The low-level LIR creation utilites will pull it from here. Should
543 * be rewritten.
544 */
545 int currentDalvikOffset;
546 GrowableList switchTables;
547 GrowableList fillArrayData;
548 const u2* insns;
549 u4 insnsSize;
550 bool disableDataflow; // Skip dataflow analysis if possible
551 SafeMap<unsigned int, BasicBlock*> blockMap; // findBlock lookup cache
buzbeed1643e42012-09-05 14:06:51 -0700552 SafeMap<unsigned int, unsigned int> blockIdMap; // Block collapse lookup cache
Bill Buzbeea114add2012-05-03 15:00:40 -0700553 SafeMap<unsigned int, LIR*> boundaryMap; // boundary lookup cache
554 int defCount; // Used to estimate number of SSA names
Elliott Hughese52e49b2012-04-02 16:05:44 -0700555
Bill Buzbeea114add2012-05-03 15:00:40 -0700556 // If non-empty, apply optimizer/debug flags only to matching methods.
557 std::string compilerMethodMatch;
558 // Flips sense of compilerMethodMatch - apply flags if doesn't match.
559 bool compilerFlipMatch;
560 ArenaMemBlock* arenaHead;
561 ArenaMemBlock* currentArena;
562 int numArenaBlocks;
563 Memstats* mstats;
buzbeed1643e42012-09-05 14:06:51 -0700564 Checkstats* checkstats;
buzbee2cfc6392012-05-07 14:51:40 -0700565 bool genBitcode;
buzbee4df2bbd2012-10-11 14:46:06 -0700566 LLVMInfo* llvm_info;
buzbee2cfc6392012-05-07 14:51:40 -0700567 llvm::LLVMContext* context;
568 llvm::Module* module;
569 llvm::Function* func;
570 greenland::IntrinsicHelper* intrinsic_helper;
571 greenland::IRBuilder* irb;
572 llvm::BasicBlock* placeholderBB;
573 llvm::BasicBlock* entryBB;
buzbee4be777b2012-07-12 14:38:18 -0700574 llvm::BasicBlock* entryTargetBB;
buzbee2cfc6392012-05-07 14:51:40 -0700575 std::string bitcode_filename;
576 GrowableList llvmValues;
577 int32_t tempName;
578 SafeMap<llvm::BasicBlock*, LIR*> blockToLabelMap; // llvm bb -> LIR label
579 SafeMap<int32_t, llvm::BasicBlock*> idToBlockMap; // block id -> llvm bb
580 SafeMap<llvm::Value*, RegLocation> locMap; // llvm Value to loc rec
buzbeeb03f4872012-06-11 15:22:11 -0700581 int numShadowFrameEntries;
582 int* shadowMap;
buzbee0967a252012-09-14 10:43:54 -0700583 std::set<llvm::BasicBlock*> llvmBlocks;
buzbee3d661942012-03-14 17:37:27 -0700584#ifndef NDEBUG
Bill Buzbeea114add2012-05-03 15:00:40 -0700585 /*
586 * Sanity checking for the register temp tracking. The same ssa
587 * name should never be associated with one temp register per
588 * instruction compilation.
589 */
590 int liveSReg;
buzbee3d661942012-03-14 17:37:27 -0700591#endif
buzbee6459e7c2012-10-02 14:42:41 -0700592 std::set<uint32_t> catches;
buzbee2cfc6392012-05-07 14:51:40 -0700593 int* opcodeCount; // Count Dalvik opcodes for tuning
Elliott Hughes719ace42012-03-09 18:06:03 -0800594};
buzbee67bf8852011-08-17 17:51:35 -0700595
Elliott Hughes719ace42012-03-09 18:06:03 -0800596enum OpSize {
Bill Buzbeea114add2012-05-03 15:00:40 -0700597 kWord,
598 kLong,
599 kSingle,
600 kDouble,
601 kUnsignedHalf,
602 kSignedHalf,
603 kUnsignedByte,
604 kSignedByte,
Elliott Hughes719ace42012-03-09 18:06:03 -0800605};
buzbeee3acd072012-02-25 17:03:10 -0800606
Elliott Hughes719ace42012-03-09 18:06:03 -0800607enum OpKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700608 kOpMov,
609 kOpMvn,
610 kOpCmp,
611 kOpLsl,
612 kOpLsr,
613 kOpAsr,
614 kOpRor,
615 kOpNot,
616 kOpAnd,
617 kOpOr,
618 kOpXor,
619 kOpNeg,
620 kOpAdd,
621 kOpAdc,
622 kOpSub,
623 kOpSbc,
624 kOpRsub,
625 kOpMul,
626 kOpDiv,
627 kOpRem,
628 kOpBic,
629 kOpCmn,
630 kOpTst,
631 kOpBkpt,
632 kOpBlx,
633 kOpPush,
634 kOpPop,
635 kOp2Char,
636 kOp2Short,
637 kOp2Byte,
638 kOpCondBr,
639 kOpUncondBr,
640 kOpBx,
641 kOpInvalid,
Elliott Hughes719ace42012-03-09 18:06:03 -0800642};
buzbee31a4a6f2012-02-28 15:36:15 -0800643
Ian Rogers680b1bd2012-03-07 20:18:49 -0800644std::ostream& operator<<(std::ostream& os, const OpKind& kind);
645
Elliott Hughes719ace42012-03-09 18:06:03 -0800646enum ConditionCode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700647 kCondEq, // equal
648 kCondNe, // not equal
649 kCondCs, // carry set (unsigned less than)
650 kCondUlt = kCondCs,
651 kCondCc, // carry clear (unsigned greater than or same)
652 kCondUge = kCondCc,
653 kCondMi, // minus
654 kCondPl, // plus, positive or zero
655 kCondVs, // overflow
656 kCondVc, // no overflow
657 kCondHi, // unsigned greater than
658 kCondLs, // unsigned lower or same
659 kCondGe, // signed greater than or equal
660 kCondLt, // signed less than
661 kCondGt, // signed greater than
662 kCondLe, // signed less than or equal
663 kCondAl, // always
664 kCondNv, // never
Elliott Hughes719ace42012-03-09 18:06:03 -0800665};
buzbee31a4a6f2012-02-28 15:36:15 -0800666
buzbeeb046e162012-10-30 15:48:42 -0700667// Target specific condition encodings
668enum ArmConditionCode {
669 kArmCondEq = 0x0, /* 0000 */
670 kArmCondNe = 0x1, /* 0001 */
671 kArmCondCs = 0x2, /* 0010 */
672 kArmCondCc = 0x3, /* 0011 */
673 kArmCondMi = 0x4, /* 0100 */
674 kArmCondPl = 0x5, /* 0101 */
675 kArmCondVs = 0x6, /* 0110 */
676 kArmCondVc = 0x7, /* 0111 */
677 kArmCondHi = 0x8, /* 1000 */
678 kArmCondLs = 0x9, /* 1001 */
679 kArmCondGe = 0xa, /* 1010 */
680 kArmCondLt = 0xb, /* 1011 */
681 kArmCondGt = 0xc, /* 1100 */
682 kArmCondLe = 0xd, /* 1101 */
683 kArmCondAl = 0xe, /* 1110 */
684 kArmCondNv = 0xf, /* 1111 */
685};
686
687enum X86ConditionCode {
688 kX86CondO = 0x0, // overflow
689 kX86CondNo = 0x1, // not overflow
690
691 kX86CondB = 0x2, // below
692 kX86CondNae = kX86CondB, // not-above-equal
693 kX86CondC = kX86CondB, // carry
694
695 kX86CondNb = 0x3, // not-below
696 kX86CondAe = kX86CondNb, // above-equal
697 kX86CondNc = kX86CondNb, // not-carry
698
699 kX86CondZ = 0x4, // zero
700 kX86CondEq = kX86CondZ, // equal
701
702 kX86CondNz = 0x5, // not-zero
703 kX86CondNe = kX86CondNz, // not-equal
704
705 kX86CondBe = 0x6, // below-equal
706 kX86CondNa = kX86CondBe, // not-above
707
708 kX86CondNbe = 0x7, // not-below-equal
709 kX86CondA = kX86CondNbe,// above
710
711 kX86CondS = 0x8, // sign
712 kX86CondNs = 0x9, // not-sign
713
714 kX86CondP = 0xA, // 8-bit parity even
715 kX86CondPE = kX86CondP,
716
717 kX86CondNp = 0xB, // 8-bit parity odd
718 kX86CondPo = kX86CondNp,
719
720 kX86CondL = 0xC, // less-than
721 kX86CondNge = kX86CondL, // not-greater-equal
722
723 kX86CondNl = 0xD, // not-less-than
724 kX86CondGe = kX86CondNl, // not-greater-equal
725
726 kX86CondLe = 0xE, // less-than-equal
727 kX86CondNg = kX86CondLe, // not-greater
728
729 kX86CondNle = 0xF, // not-less-than
730 kX86CondG = kX86CondNle,// greater
731};
732
733
Elliott Hughes719ace42012-03-09 18:06:03 -0800734enum ThrowKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700735 kThrowNullPointer,
736 kThrowDivZero,
737 kThrowArrayBounds,
Bill Buzbeea114add2012-05-03 15:00:40 -0700738 kThrowNoSuchMethod,
739 kThrowStackOverflow,
Elliott Hughes719ace42012-03-09 18:06:03 -0800740};
buzbee31a4a6f2012-02-28 15:36:15 -0800741
Elliott Hughes719ace42012-03-09 18:06:03 -0800742struct SwitchTable {
Bill Buzbeea114add2012-05-03 15:00:40 -0700743 int offset;
744 const u2* table; // Original dex table
745 int vaddr; // Dalvik offset of switch opcode
746 LIR* anchor; // Reference instruction for relative offsets
747 LIR** targets; // Array of case targets
Elliott Hughes719ace42012-03-09 18:06:03 -0800748};
buzbee5de34942012-03-01 14:51:57 -0800749
Elliott Hughes719ace42012-03-09 18:06:03 -0800750struct FillArrayData {
Bill Buzbeea114add2012-05-03 15:00:40 -0700751 int offset;
752 const u2* table; // Original dex table
753 int size;
754 int vaddr; // Dalvik offset of FILL_ARRAY_DATA opcode
Elliott Hughes719ace42012-03-09 18:06:03 -0800755};
buzbee5de34942012-03-01 14:51:57 -0800756
buzbee16da88c2012-03-20 10:38:17 -0700757#define MAX_PATTERN_LEN 5
758
759enum SpecialCaseHandler {
Bill Buzbeea114add2012-05-03 15:00:40 -0700760 kNoHandler,
761 kNullMethod,
762 kConstFunction,
763 kIGet,
764 kIGetBoolean,
765 kIGetObject,
766 kIGetByte,
767 kIGetChar,
768 kIGetShort,
769 kIGetWide,
770 kIPut,
771 kIPutBoolean,
772 kIPutObject,
773 kIPutByte,
774 kIPutChar,
775 kIPutShort,
776 kIPutWide,
777 kIdentity,
buzbee16da88c2012-03-20 10:38:17 -0700778};
779
780struct CodePattern {
Bill Buzbeea114add2012-05-03 15:00:40 -0700781 const Instruction::Code opcodes[MAX_PATTERN_LEN];
782 const SpecialCaseHandler handlerCode;
buzbee16da88c2012-03-20 10:38:17 -0700783};
784
785static const CodePattern specialPatterns[] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700786 {{Instruction::RETURN_VOID}, kNullMethod},
787 {{Instruction::CONST, Instruction::RETURN}, kConstFunction},
788 {{Instruction::CONST_4, Instruction::RETURN}, kConstFunction},
789 {{Instruction::CONST_4, Instruction::RETURN_OBJECT}, kConstFunction},
790 {{Instruction::CONST_16, Instruction::RETURN}, kConstFunction},
791 {{Instruction::IGET, Instruction:: RETURN}, kIGet},
792 {{Instruction::IGET_BOOLEAN, Instruction::RETURN}, kIGetBoolean},
793 {{Instruction::IGET_OBJECT, Instruction::RETURN_OBJECT}, kIGetObject},
794 {{Instruction::IGET_BYTE, Instruction::RETURN}, kIGetByte},
795 {{Instruction::IGET_CHAR, Instruction::RETURN}, kIGetChar},
796 {{Instruction::IGET_SHORT, Instruction::RETURN}, kIGetShort},
797 {{Instruction::IGET_WIDE, Instruction::RETURN_WIDE}, kIGetWide},
798 {{Instruction::IPUT, Instruction::RETURN_VOID}, kIPut},
799 {{Instruction::IPUT_BOOLEAN, Instruction::RETURN_VOID}, kIPutBoolean},
800 {{Instruction::IPUT_OBJECT, Instruction::RETURN_VOID}, kIPutObject},
801 {{Instruction::IPUT_BYTE, Instruction::RETURN_VOID}, kIPutByte},
802 {{Instruction::IPUT_CHAR, Instruction::RETURN_VOID}, kIPutChar},
803 {{Instruction::IPUT_SHORT, Instruction::RETURN_VOID}, kIPutShort},
804 {{Instruction::IPUT_WIDE, Instruction::RETURN_VOID}, kIPutWide},
805 {{Instruction::RETURN}, kIdentity},
806 {{Instruction::RETURN_OBJECT}, kIdentity},
807 {{Instruction::RETURN_WIDE}, kIdentity},
buzbee16da88c2012-03-20 10:38:17 -0700808};
buzbee5de34942012-03-01 14:51:57 -0800809
buzbee5abfa3e2012-01-31 17:01:43 -0800810BasicBlock* oatNewBB(CompilationUnit* cUnit, BBType blockType, int blockId);
buzbee67bf8852011-08-17 17:51:35 -0700811
812void oatAppendMIR(BasicBlock* bb, MIR* mir);
813
814void oatPrependMIR(BasicBlock* bb, MIR* mir);
815
816void oatInsertMIRAfter(BasicBlock* bb, MIR* currentMIR, MIR* newMIR);
817
818void oatAppendLIR(CompilationUnit* cUnit, LIR* lir);
819
820void oatInsertLIRBefore(LIR* currentLIR, LIR* newLIR);
821
822void oatInsertLIRAfter(LIR* currentLIR, LIR* newLIR);
823
buzbee15bf9802012-06-12 17:49:27 -0700824MIR* oatFindMoveResult(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir);
buzbee67bf8852011-08-17 17:51:35 -0700825/* Debug Utilities */
826void oatDumpCompilationUnit(CompilationUnit* cUnit);
827
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800828} // namespace art
829
buzbee67bf8852011-08-17 17:51:35 -0700830#endif // ART_SRC_COMPILER_COMPILER_IR_H_