blob: bc09a9cce20b7caf73a71fc769d6eab756544699 [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>
buzbeeeaf09bc2012-11-15 14:51:41 -080021#include "dex_instruction.h"
22#include "compiler.h"
buzbeeefc63692012-11-14 16:31:52 -080023#include "compiler_utility.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"
buzbeecbd6d442012-11-17 14:11:25 -080028#include "compiler_enums.h"
buzbee67bf8852011-08-17 17:51:35 -070029
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080030namespace art {
31
buzbee31a4a6f2012-02-28 15:36:15 -080032#define SLOW_FIELD_PATH (cUnit->enableDebug & (1 << kDebugSlowFieldPath))
33#define SLOW_INVOKE_PATH (cUnit->enableDebug & (1 << kDebugSlowInvokePath))
34#define SLOW_STRING_PATH (cUnit->enableDebug & (1 << kDebugSlowStringPath))
35#define SLOW_TYPE_PATH (cUnit->enableDebug & (1 << kDebugSlowTypePath))
buzbee31a4a6f2012-02-28 15:36:15 -080036#define EXERCISE_SLOWEST_STRING_PATH (cUnit->enableDebug & \
Bill Buzbeea114add2012-05-03 15:00:40 -070037 (1 << kDebugSlowestStringPath))
buzbee31a4a6f2012-02-28 15:36:15 -080038
buzbeeca7a5e42012-08-20 11:12:18 -070039// Minimum field size to contain Dalvik vReg number
40#define VREG_NUM_WIDTH 16
41
buzbeeeaf09bc2012-11-15 14:51:41 -080042struct ArenaBitVector;
43struct LIR;
44class LLVMInfo;
45
Elliott Hughes719ace42012-03-09 18:06:03 -080046struct PromotionMap {
Bill Buzbeea114add2012-05-03 15:00:40 -070047 RegLocationType coreLocation:3;
buzbeeeaf09bc2012-11-15 14:51:41 -080048 uint8_t coreReg;
Bill Buzbeea114add2012-05-03 15:00:40 -070049 RegLocationType fpLocation:3;
buzbeeeaf09bc2012-11-15 14:51:41 -080050 uint8_t fpReg;
Bill Buzbeea114add2012-05-03 15:00:40 -070051 bool firstInPair;
Elliott Hughes719ace42012-03-09 18:06:03 -080052};
buzbee67bc2362011-10-11 18:08:40 -070053
Elliott Hughes719ace42012-03-09 18:06:03 -080054struct RegLocation {
Bill Buzbeea114add2012-05-03 15:00:40 -070055 RegLocationType location:3;
56 unsigned wide:1;
57 unsigned defined:1; // Do we know the type?
buzbee2cfc6392012-05-07 14:51:40 -070058 unsigned isConst:1; // Constant, value in cUnit->constantValues[]
Bill Buzbeea114add2012-05-03 15:00:40 -070059 unsigned fp:1; // Floating point?
60 unsigned core:1; // Non-floating point?
buzbeebff24652012-05-06 16:22:05 -070061 unsigned ref:1; // Something GC cares about
Bill Buzbeea114add2012-05-03 15:00:40 -070062 unsigned highWord:1; // High word of pair?
63 unsigned home:1; // Does this represent the home location?
buzbeeeaf09bc2012-11-15 14:51:41 -080064 uint8_t lowReg; // First physical register
65 uint8_t highReg; // 2nd physical register (if wide)
Bill Buzbeea114add2012-05-03 15:00:40 -070066 int32_t sRegLow; // SSA name for low Dalvik word
buzbee2cfc6392012-05-07 14:51:40 -070067 int32_t origSReg; // TODO: remove after Bitcode gen complete
68 // and consolodate usage w/ sRegLow
buzbeee1965672012-03-11 18:39:19 -070069};
70
71struct CompilerTemp {
Bill Buzbeea114add2012-05-03 15:00:40 -070072 int sReg;
73 ArenaBitVector* bv;
Elliott Hughes719ace42012-03-09 18:06:03 -080074};
buzbee67bf8852011-08-17 17:51:35 -070075
buzbee3b3dbdd2012-06-13 13:39:34 -070076struct CallInfo {
buzbee15bf9802012-06-12 17:49:27 -070077 int numArgWords; // Note: word count, not arg count
78 RegLocation* args; // One for each word of arguments
79 RegLocation result; // Eventual target of MOVE_RESULT
80 int optFlags;
81 InvokeType type;
82 uint32_t dexIdx;
buzbee3b3dbdd2012-06-13 13:39:34 -070083 uint32_t index; // Method idx for invokes, type idx for FilledNewArray
buzbee15bf9802012-06-12 17:49:27 -070084 uintptr_t directCode;
85 uintptr_t directMethod;
86 RegLocation target; // Target of following move_result
87 bool skipThis;
88 bool isRange;
89 int offset; // Dalvik offset
90};
91
buzbeee3acd072012-02-25 17:03:10 -080092 /*
93 * Data structure tracking the mapping between a Dalvik register (pair) and a
94 * native register (pair). The idea is to reuse the previously loaded value
95 * if possible, otherwise to keep the value in a native register as long as
96 * possible.
97 */
Elliott Hughes719ace42012-03-09 18:06:03 -080098struct RegisterInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -070099 int reg; // Reg number
100 bool inUse; // Has it been allocated?
101 bool isTemp; // Can allocate as temp?
102 bool pair; // Part of a register pair?
103 int partner; // If pair, other reg of pair
104 bool live; // Is there an associated SSA name?
105 bool dirty; // If live, is it dirty?
106 int sReg; // Name of live value
107 LIR *defStart; // Starting inst in last def sequence
108 LIR *defEnd; // Ending inst in last def sequence
Elliott Hughes719ace42012-03-09 18:06:03 -0800109};
buzbeee3acd072012-02-25 17:03:10 -0800110
Elliott Hughes719ace42012-03-09 18:06:03 -0800111struct RegisterPool {
Bill Buzbeea114add2012-05-03 15:00:40 -0700112 int numCoreRegs;
113 RegisterInfo *coreRegs;
114 int nextCoreReg;
115 int numFPRegs;
116 RegisterInfo *FPRegs;
117 int nextFPReg;
Elliott Hughes719ace42012-03-09 18:06:03 -0800118};
buzbeee3acd072012-02-25 17:03:10 -0800119
buzbee67bf8852011-08-17 17:51:35 -0700120#define INVALID_SREG (-1)
buzbee3ddc0d12011-10-05 10:36:21 -0700121#define INVALID_VREG (0xFFFFU)
buzbee67bc2362011-10-11 18:08:40 -0700122#define INVALID_REG (0xFF)
buzbeeb046e162012-10-30 15:48:42 -0700123#define INVALID_OFFSET (0xDEADF00FU)
buzbee67bf8852011-08-17 17:51:35 -0700124
buzbeee1965672012-03-11 18:39:19 -0700125/* SSA encodings for special registers */
buzbee9c044ce2012-03-18 13:24:07 -0700126#define SSA_METHOD_BASEREG (-2)
buzbeee1965672012-03-11 18:39:19 -0700127/* First compiler temp basereg, grows smaller */
buzbee9c044ce2012-03-18 13:24:07 -0700128#define SSA_CTEMP_BASEREG (SSA_METHOD_BASEREG - 1)
buzbeee1965672012-03-11 18:39:19 -0700129
buzbee99ba9642012-01-25 14:23:14 -0800130/*
131 * Some code patterns cause the generation of excessively large
132 * methods - in particular initialization sequences. There isn't much
133 * benefit in optimizing these methods, and the cost can be very high.
134 * We attempt to identify these cases, and avoid performing most dataflow
135 * analysis. Two thresholds are used - one for known initializers and one
buzbee5abfa3e2012-01-31 17:01:43 -0800136 * for everything else.
buzbee99ba9642012-01-25 14:23:14 -0800137 */
buzbee5abfa3e2012-01-31 17:01:43 -0800138#define MANY_BLOCKS_INITIALIZER 1000 /* Threshold for switching dataflow off */
139#define MANY_BLOCKS 4000 /* Non-initializer threshold */
buzbee99ba9642012-01-25 14:23:14 -0800140
buzbee31a4a6f2012-02-28 15:36:15 -0800141/* Utility macros to traverse the LIR list */
142#define NEXT_LIR(lir) (lir->next)
143#define PREV_LIR(lir) (lir->prev)
144
buzbeeec137432012-11-13 12:13:16 -0800145/* Defines for aliasInfo (tracks Dalvik register references) */
146#define DECODE_ALIAS_INFO_REG(X) (X & 0xffff)
147#define DECODE_ALIAS_INFO_WIDE_FLAG (0x80000000)
148#define DECODE_ALIAS_INFO_WIDE(X) ((X & DECODE_ALIAS_INFO_WIDE_FLAG) ? 1 : 0)
149#define ENCODE_ALIAS_INFO(REG, ISWIDE) (REG | (ISWIDE ? DECODE_ALIAS_INFO_WIDE_FLAG : 0))
150
buzbeeec137432012-11-13 12:13:16 -0800151/* Common resource macros */
152#define ENCODE_CCODE (1ULL << kCCode)
153#define ENCODE_FP_STATUS (1ULL << kFPStatus)
154
155/* Abstract memory locations */
156#define ENCODE_DALVIK_REG (1ULL << kDalvikReg)
157#define ENCODE_LITERAL (1ULL << kLiteral)
158#define ENCODE_HEAP_REF (1ULL << kHeapRef)
159#define ENCODE_MUST_NOT_ALIAS (1ULL << kMustNotAlias)
160
161#define ENCODE_ALL (~0ULL)
162#define ENCODE_MEM (ENCODE_DALVIK_REG | ENCODE_LITERAL | \
163 ENCODE_HEAP_REF | ENCODE_MUST_NOT_ALIAS)
164
Elliott Hughes719ace42012-03-09 18:06:03 -0800165struct LIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700166 int offset; // Offset of this instruction
167 int dalvikOffset; // Offset of Dalvik opcode
168 LIR* next;
169 LIR* prev;
170 LIR* target;
171 int opcode;
172 int operands[5]; // [0..4] = [dest, src1, src2, extra, extra2]
173 struct {
174 bool isNop:1; // LIR is optimized away
175 bool pcRelFixup:1; // May need pc-relative fixup
Bill Buzbeea114add2012-05-03 15:00:40 -0700176 unsigned int size:5; // in bytes
buzbeef5f5a122012-09-21 13:57:36 -0700177 unsigned int unused:25;
Bill Buzbeea114add2012-05-03 15:00:40 -0700178 } flags;
179 int aliasInfo; // For Dalvik register & litpool disambiguation
buzbeeeaf09bc2012-11-15 14:51:41 -0800180 uint64_t useMask; // Resource mask for use
181 uint64_t defMask; // Resource mask for def
Elliott Hughes719ace42012-03-09 18:06:03 -0800182};
buzbee67bf8852011-08-17 17:51:35 -0700183
buzbeecbd6d442012-11-17 14:11:25 -0800184extern const char* extendedMIROpNames[kMirOpLast - kMirOpFirst];
buzbee67bf8852011-08-17 17:51:35 -0700185
186struct SSARepresentation;
187
buzbee67bf8852011-08-17 17:51:35 -0700188#define MIR_IGNORE_NULL_CHECK (1 << kMIRIgnoreNullCheck)
189#define MIR_NULL_CHECK_ONLY (1 << kMIRNullCheckOnly)
190#define MIR_IGNORE_RANGE_CHECK (1 << kMIRIgnoreRangeCheck)
191#define MIR_RANGE_CHECK_ONLY (1 << kMIRRangeCheckOnly)
192#define MIR_INLINED (1 << kMIRInlined)
193#define MIR_INLINED_PRED (1 << kMIRInlinedPred)
194#define MIR_CALLEE (1 << kMIRCallee)
buzbeec1f45042011-09-21 16:03:19 -0700195#define MIR_IGNORE_SUSPEND_CHECK (1 << kMIRIgnoreSuspendCheck)
buzbeee1965672012-03-11 18:39:19 -0700196#define MIR_DUP (1 << kMIRDup)
buzbee239c4e72012-03-16 08:42:29 -0700197#define MIR_MARK (1 << kMIRMark)
buzbee67bf8852011-08-17 17:51:35 -0700198
buzbeed1643e42012-09-05 14:06:51 -0700199struct Checkstats {
200 int nullChecks;
201 int nullChecksEliminated;
202 int rangeChecks;
203 int rangeChecksEliminated;
204};
205
Elliott Hughes719ace42012-03-09 18:06:03 -0800206struct MIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700207 DecodedInstruction dalvikInsn;
208 unsigned int width;
209 unsigned int offset;
210 MIR* prev;
211 MIR* next;
212 SSARepresentation* ssaRep;
213 int optimizationFlags;
Bill Buzbeea114add2012-05-03 15:00:40 -0700214 union {
Bill Buzbeea114add2012-05-03 15:00:40 -0700215 // Used to quickly locate all Phi opcodes
216 MIR* phiNext;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700217 // Establish link between two halves of throwing instructions
218 MIR* throwInsn;
Bill Buzbeea114add2012-05-03 15:00:40 -0700219 } meta;
Elliott Hughes719ace42012-03-09 18:06:03 -0800220};
buzbee67bf8852011-08-17 17:51:35 -0700221
222struct BasicBlockDataFlow;
223
Elliott Hughes719ace42012-03-09 18:06:03 -0800224struct BasicBlock {
Bill Buzbeea114add2012-05-03 15:00:40 -0700225 int id;
226 int dfsId;
227 bool visited;
228 bool hidden;
229 bool catchEntry;
buzbee0967a252012-09-14 10:43:54 -0700230 bool explicitThrow;
231 bool conditionalBranch;
buzbee2cfc6392012-05-07 14:51:40 -0700232 bool hasReturn;
Bill Buzbeea114add2012-05-03 15:00:40 -0700233 uint16_t startOffset;
234 uint16_t nestingDepth;
Bill Buzbeea114add2012-05-03 15:00:40 -0700235 BBType blockType;
Bill Buzbeea114add2012-05-03 15:00:40 -0700236 MIR* firstMIRInsn;
237 MIR* lastMIRInsn;
238 BasicBlock* fallThrough;
239 BasicBlock* taken;
240 BasicBlock* iDom; // Immediate dominator
241 BasicBlockDataFlow* dataFlowInfo;
242 GrowableList* predecessors;
243 ArenaBitVector* dominators;
244 ArenaBitVector* iDominated; // Set nodes being immediately dominated
245 ArenaBitVector* domFrontier; // Dominance frontier
246 struct { // For one-to-many successors like
247 BlockListType blockListType; // switch and exception handling
248 GrowableList blocks;
249 } successorBlockList;
Elliott Hughes719ace42012-03-09 18:06:03 -0800250};
buzbee67bf8852011-08-17 17:51:35 -0700251
252/*
253 * The "blocks" field in "successorBlockList" points to an array of
254 * elements with the type "SuccessorBlockInfo".
255 * For catch blocks, key is type index for the exception.
256 * For swtich blocks, key is the case value.
257 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800258struct SuccessorBlockInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700259 BasicBlock* block;
260 int key;
Elliott Hughes719ace42012-03-09 18:06:03 -0800261};
buzbee67bf8852011-08-17 17:51:35 -0700262
263struct LoopAnalysis;
264struct RegisterPool;
buzbeeba938cb2012-02-03 14:47:55 -0800265struct ArenaMemBlock;
266struct Memstats;
buzbee67bf8852011-08-17 17:51:35 -0700267
buzbee5b537102012-01-17 17:33:47 -0800268#define NOTVISITED (-1)
269
Elliott Hughes719ace42012-03-09 18:06:03 -0800270struct CompilationUnit {
Elliott Hughese52e49b2012-04-02 16:05:44 -0700271 CompilationUnit()
Bill Buzbeea114add2012-05-03 15:00:40 -0700272 : numBlocks(0),
273 compiler(NULL),
274 class_linker(NULL),
275 dex_file(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700276 class_loader(NULL),
277 method_idx(0),
278 code_item(NULL),
279 access_flags(0),
Ian Rogers08f753d2012-08-24 14:35:25 -0700280 invoke_type(kDirect),
Bill Buzbeea114add2012-05-03 15:00:40 -0700281 shorty(NULL),
282 firstLIRInsn(NULL),
283 lastLIRInsn(NULL),
284 literalList(NULL),
285 methodLiteralList(NULL),
286 codeLiteralList(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700287 disableOpt(0),
288 enableDebug(0),
Bill Buzbeea114add2012-05-03 15:00:40 -0700289 dataOffset(0),
290 totalSize(0),
291 assemblerStatus(kSuccess),
292 assemblerRetries(0),
Bill Buzbeea114add2012-05-03 15:00:40 -0700293 printMe(false),
Bill Buzbeea114add2012-05-03 15:00:40 -0700294 hasLoop(false),
295 hasInvoke(false),
Bill Buzbeea114add2012-05-03 15:00:40 -0700296 qdMode(false),
Bill Buzbeea114add2012-05-03 15:00:40 -0700297 regPool(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700298 instructionSet(kNone),
299 numSSARegs(0),
300 ssaBaseVRegs(NULL),
301 ssaSubscripts(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700302 ssaStrings(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700303 vRegToSSAMap(NULL),
304 SSALastDefs(NULL),
305 isConstantV(NULL),
306 constantValues(NULL),
307 phiAliasMap(NULL),
308 phiList(NULL),
309 regLocation(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700310 promotionMap(NULL),
311 methodSReg(0),
Bill Buzbeea114add2012-05-03 15:00:40 -0700312 numReachableBlocks(0),
313 numDalvikRegisters(0),
314 entryBlock(NULL),
315 exitBlock(NULL),
316 curBlock(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700317 iDomList(NULL),
318 tryBlockAddr(NULL),
319 defBlockMatrix(NULL),
320 tempBlockV(NULL),
321 tempDalvikRegisterV(NULL),
322 tempSSARegisterV(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700323 tempSSABlockIdV(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700324 blockLabelList(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700325 numIns(0),
326 numOuts(0),
327 numRegs(0),
328 numCoreSpills(0),
329 numFPSpills(0),
330 numCompilerTemps(0),
331 frameSize(0),
332 coreSpillMask(0U),
333 fpSpillMask(0U),
334 attrs(0U),
335 currentDalvikOffset(0),
336 insns(NULL),
337 insnsSize(0U),
338 disableDataflow(false),
339 defCount(0),
340 compilerFlipMatch(false),
341 arenaHead(NULL),
342 currentArena(NULL),
343 numArenaBlocks(0),
344 mstats(NULL),
buzbeed1643e42012-09-05 14:06:51 -0700345 checkstats(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700346 genBitcode(false),
347 context(NULL),
348 module(NULL),
349 func(NULL),
350 intrinsic_helper(NULL),
351 irb(NULL),
352 placeholderBB(NULL),
353 entryBB(NULL),
buzbee4be777b2012-07-12 14:38:18 -0700354 entryTargetBB(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700355 tempName(0),
buzbeeb03f4872012-06-11 15:22:11 -0700356 numShadowFrameEntries(0),
357 shadowMap(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700358#ifndef NDEBUG
359 liveSReg(0),
360#endif
361 opcodeCount(NULL) {}
Elliott Hughese52e49b2012-04-02 16:05:44 -0700362
Bill Buzbeea114add2012-05-03 15:00:40 -0700363 int numBlocks;
364 GrowableList blockList;
365 Compiler* compiler; // Compiler driving this compiler
366 ClassLinker* class_linker; // Linker to resolve fields and methods
367 const DexFile* dex_file; // DexFile containing the method being compiled
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700368 jobject class_loader; // compiling method's class loader
Bill Buzbeea114add2012-05-03 15:00:40 -0700369 uint32_t method_idx; // compiling method's index into method_ids of DexFile
370 const DexFile::CodeItem* code_item; // compiling method's DexFile code_item
371 uint32_t access_flags; // compiling method's access flags
Ian Rogers08f753d2012-08-24 14:35:25 -0700372 InvokeType invoke_type; // compiling method's invocation type
Bill Buzbeea114add2012-05-03 15:00:40 -0700373 const char* shorty; // compiling method's shorty
374 LIR* firstLIRInsn;
375 LIR* lastLIRInsn;
376 LIR* literalList; // Constants
377 LIR* methodLiteralList; // Method literals requiring patching
378 LIR* codeLiteralList; // Code literals requiring patching
Bill Buzbeea114add2012-05-03 15:00:40 -0700379 uint32_t disableOpt; // optControlVector flags
380 uint32_t enableDebug; // debugControlVector flags
Bill Buzbeea114add2012-05-03 15:00:40 -0700381 int dataOffset; // starting offset of literal pool
382 int totalSize; // header + code size
383 AssemblerStatus assemblerStatus; // Success or fix and retry
384 int assemblerRetries;
385 std::vector<uint8_t> codeBuffer;
Bill Buzbeea5b30242012-09-28 07:19:44 -0700386 /*
387 * Holds mapping from native PC to dex PC for safepoints where we may deoptimize.
388 * Native PC is on the return address of the safepointed operation. Dex PC is for
389 * the instruction being executed at the safepoint.
390 */
391 std::vector<uint32_t> pc2dexMappingTable;
392 /*
393 * Holds mapping from Dex PC to native PC for catch entry points. Native PC and Dex PC
394 * immediately preceed the instruction.
395 */
396 std::vector<uint32_t> dex2pcMappingTable;
397 std::vector<uint32_t> combinedMappingTable;
buzbeeca7a5e42012-08-20 11:12:18 -0700398 std::vector<uint32_t> coreVmapTable;
399 std::vector<uint32_t> fpVmapTable;
Ian Rogers0c7abda2012-09-19 13:33:42 -0700400 std::vector<uint8_t> nativeGcMap;
Bill Buzbeea114add2012-05-03 15:00:40 -0700401 bool printMe;
Bill Buzbeea114add2012-05-03 15:00:40 -0700402 bool hasLoop; // Contains a loop
403 bool hasInvoke; // Contains an invoke instruction
Bill Buzbeea114add2012-05-03 15:00:40 -0700404 bool qdMode; // Compile for code size/compile time
Bill Buzbeea114add2012-05-03 15:00:40 -0700405 RegisterPool* regPool;
Bill Buzbeea114add2012-05-03 15:00:40 -0700406 InstructionSet instructionSet;
407 /* Number of total regs used in the whole cUnit after SSA transformation */
408 int numSSARegs;
409 /* Map SSA reg i to the base virtual register/subscript */
410 GrowableList* ssaBaseVRegs;
411 GrowableList* ssaSubscripts;
buzbee2cfc6392012-05-07 14:51:40 -0700412 GrowableList* ssaStrings;
buzbee67bf8852011-08-17 17:51:35 -0700413
Bill Buzbeea114add2012-05-03 15:00:40 -0700414 /* The following are new data structures to support SSA representations */
415 /* Map original Dalvik virtual reg i to the current SSA name */
416 int* vRegToSSAMap; // length == method->registersSize
417 int* SSALastDefs; // length == method->registersSize
418 ArenaBitVector* isConstantV; // length == numSSAReg
419 int* constantValues; // length == numSSAReg
420 int* phiAliasMap; // length == numSSAReg
421 MIR* phiList;
buzbee67bf8852011-08-17 17:51:35 -0700422
Bill Buzbeea114add2012-05-03 15:00:40 -0700423 /* Use counts of ssa names */
424 GrowableList useCounts; // Weighted by nesting depth
425 GrowableList rawUseCounts; // Not weighted
buzbee239c4e72012-03-16 08:42:29 -0700426
Bill Buzbeea114add2012-05-03 15:00:40 -0700427 /* Optimization support */
428 GrowableList loopHeaders;
buzbee239c4e72012-03-16 08:42:29 -0700429
Bill Buzbeea114add2012-05-03 15:00:40 -0700430 /* Map SSA names to location */
431 RegLocation* regLocation;
buzbee67bf8852011-08-17 17:51:35 -0700432
Bill Buzbeea114add2012-05-03 15:00:40 -0700433 /* Keep track of Dalvik vReg to physical register mappings */
434 PromotionMap* promotionMap;
buzbee67bc2362011-10-11 18:08:40 -0700435
Bill Buzbeea114add2012-05-03 15:00:40 -0700436 /* SSA name for Method* */
437 int methodSReg;
buzbeead8f15e2012-06-18 14:49:45 -0700438 RegLocation methodLoc; // Describes location of method*
buzbeee1965672012-03-11 18:39:19 -0700439
Bill Buzbeea114add2012-05-03 15:00:40 -0700440 int numReachableBlocks;
441 int numDalvikRegisters; // method->registersSize
442 BasicBlock* entryBlock;
443 BasicBlock* exitBlock;
444 BasicBlock* curBlock;
Bill Buzbeea114add2012-05-03 15:00:40 -0700445 GrowableList dfsOrder;
446 GrowableList dfsPostOrder;
447 GrowableList domPostOrderTraversal;
448 GrowableList throwLaunchpads;
449 GrowableList suspendLaunchpads;
450 GrowableList intrinsicLaunchpads;
451 GrowableList compilerTemps;
452 int* iDomList;
453 ArenaBitVector* tryBlockAddr;
454 ArenaBitVector** defBlockMatrix; // numDalvikRegister x numBlocks
455 ArenaBitVector* tempBlockV;
456 ArenaBitVector* tempDalvikRegisterV;
457 ArenaBitVector* tempSSARegisterV; // numSSARegs
buzbee2cfc6392012-05-07 14:51:40 -0700458 int* tempSSABlockIdV; // working storage for Phi labels
buzbeea1da8a52012-07-09 14:00:21 -0700459 LIR* blockLabelList;
Bill Buzbeea114add2012-05-03 15:00:40 -0700460 /*
461 * Frame layout details.
462 * NOTE: for debug support it will be necessary to add a structure
463 * to map the Dalvik virtual registers to the promoted registers.
464 * NOTE: "num" fields are in 4-byte words, "Size" and "Offset" in bytes.
465 */
466 int numIns;
467 int numOuts;
468 int numRegs; // Unlike numDalvikRegisters, does not include ins
469 int numCoreSpills;
470 int numFPSpills;
471 int numCompilerTemps;
472 int frameSize;
473 unsigned int coreSpillMask;
474 unsigned int fpSpillMask;
475 unsigned int attrs;
476 /*
477 * CLEANUP/RESTRUCTURE: The code generation utilities don't have a built-in
478 * mechanism to propagate the original Dalvik opcode address to the
479 * associated generated instructions. For the trace compiler, this wasn't
480 * necessary because the interpreter handled all throws and debugging
481 * requests. For now we'll handle this by placing the Dalvik offset
482 * in the CompilationUnit struct before codegen for each instruction.
483 * The low-level LIR creation utilites will pull it from here. Should
484 * be rewritten.
485 */
486 int currentDalvikOffset;
487 GrowableList switchTables;
488 GrowableList fillArrayData;
buzbeeeaf09bc2012-11-15 14:51:41 -0800489 const uint16_t* insns;
490 uint32_t insnsSize;
Bill Buzbeea114add2012-05-03 15:00:40 -0700491 bool disableDataflow; // Skip dataflow analysis if possible
492 SafeMap<unsigned int, BasicBlock*> blockMap; // findBlock lookup cache
buzbeed1643e42012-09-05 14:06:51 -0700493 SafeMap<unsigned int, unsigned int> blockIdMap; // Block collapse lookup cache
Bill Buzbeea114add2012-05-03 15:00:40 -0700494 SafeMap<unsigned int, LIR*> boundaryMap; // boundary lookup cache
495 int defCount; // Used to estimate number of SSA names
Elliott Hughese52e49b2012-04-02 16:05:44 -0700496
Bill Buzbeea114add2012-05-03 15:00:40 -0700497 // If non-empty, apply optimizer/debug flags only to matching methods.
498 std::string compilerMethodMatch;
499 // Flips sense of compilerMethodMatch - apply flags if doesn't match.
500 bool compilerFlipMatch;
501 ArenaMemBlock* arenaHead;
502 ArenaMemBlock* currentArena;
503 int numArenaBlocks;
504 Memstats* mstats;
buzbeed1643e42012-09-05 14:06:51 -0700505 Checkstats* checkstats;
buzbee2cfc6392012-05-07 14:51:40 -0700506 bool genBitcode;
buzbee4df2bbd2012-10-11 14:46:06 -0700507 LLVMInfo* llvm_info;
buzbee2cfc6392012-05-07 14:51:40 -0700508 llvm::LLVMContext* context;
509 llvm::Module* module;
510 llvm::Function* func;
511 greenland::IntrinsicHelper* intrinsic_helper;
512 greenland::IRBuilder* irb;
513 llvm::BasicBlock* placeholderBB;
514 llvm::BasicBlock* entryBB;
buzbee4be777b2012-07-12 14:38:18 -0700515 llvm::BasicBlock* entryTargetBB;
buzbee2cfc6392012-05-07 14:51:40 -0700516 std::string bitcode_filename;
517 GrowableList llvmValues;
518 int32_t tempName;
519 SafeMap<llvm::BasicBlock*, LIR*> blockToLabelMap; // llvm bb -> LIR label
520 SafeMap<int32_t, llvm::BasicBlock*> idToBlockMap; // block id -> llvm bb
521 SafeMap<llvm::Value*, RegLocation> locMap; // llvm Value to loc rec
buzbeeb03f4872012-06-11 15:22:11 -0700522 int numShadowFrameEntries;
523 int* shadowMap;
buzbee0967a252012-09-14 10:43:54 -0700524 std::set<llvm::BasicBlock*> llvmBlocks;
buzbee3d661942012-03-14 17:37:27 -0700525#ifndef NDEBUG
Bill Buzbeea114add2012-05-03 15:00:40 -0700526 /*
527 * Sanity checking for the register temp tracking. The same ssa
528 * name should never be associated with one temp register per
529 * instruction compilation.
530 */
531 int liveSReg;
buzbee3d661942012-03-14 17:37:27 -0700532#endif
buzbee6459e7c2012-10-02 14:42:41 -0700533 std::set<uint32_t> catches;
buzbee2cfc6392012-05-07 14:51:40 -0700534 int* opcodeCount; // Count Dalvik opcodes for tuning
Elliott Hughes719ace42012-03-09 18:06:03 -0800535};
buzbee67bf8852011-08-17 17:51:35 -0700536
Elliott Hughes719ace42012-03-09 18:06:03 -0800537struct SwitchTable {
Bill Buzbeea114add2012-05-03 15:00:40 -0700538 int offset;
buzbeeeaf09bc2012-11-15 14:51:41 -0800539 const uint16_t* table; // Original dex table
Bill Buzbeea114add2012-05-03 15:00:40 -0700540 int vaddr; // Dalvik offset of switch opcode
541 LIR* anchor; // Reference instruction for relative offsets
542 LIR** targets; // Array of case targets
Elliott Hughes719ace42012-03-09 18:06:03 -0800543};
buzbee5de34942012-03-01 14:51:57 -0800544
Elliott Hughes719ace42012-03-09 18:06:03 -0800545struct FillArrayData {
Bill Buzbeea114add2012-05-03 15:00:40 -0700546 int offset;
buzbeeeaf09bc2012-11-15 14:51:41 -0800547 const uint16_t* table; // Original dex table
Bill Buzbeea114add2012-05-03 15:00:40 -0700548 int size;
549 int vaddr; // Dalvik offset of FILL_ARRAY_DATA opcode
Elliott Hughes719ace42012-03-09 18:06:03 -0800550};
buzbee5de34942012-03-01 14:51:57 -0800551
buzbee16da88c2012-03-20 10:38:17 -0700552#define MAX_PATTERN_LEN 5
553
buzbee16da88c2012-03-20 10:38:17 -0700554struct CodePattern {
Bill Buzbeea114add2012-05-03 15:00:40 -0700555 const Instruction::Code opcodes[MAX_PATTERN_LEN];
556 const SpecialCaseHandler handlerCode;
buzbee16da88c2012-03-20 10:38:17 -0700557};
558
559static const CodePattern specialPatterns[] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700560 {{Instruction::RETURN_VOID}, kNullMethod},
561 {{Instruction::CONST, Instruction::RETURN}, kConstFunction},
562 {{Instruction::CONST_4, Instruction::RETURN}, kConstFunction},
563 {{Instruction::CONST_4, Instruction::RETURN_OBJECT}, kConstFunction},
564 {{Instruction::CONST_16, Instruction::RETURN}, kConstFunction},
565 {{Instruction::IGET, Instruction:: RETURN}, kIGet},
566 {{Instruction::IGET_BOOLEAN, Instruction::RETURN}, kIGetBoolean},
567 {{Instruction::IGET_OBJECT, Instruction::RETURN_OBJECT}, kIGetObject},
568 {{Instruction::IGET_BYTE, Instruction::RETURN}, kIGetByte},
569 {{Instruction::IGET_CHAR, Instruction::RETURN}, kIGetChar},
570 {{Instruction::IGET_SHORT, Instruction::RETURN}, kIGetShort},
571 {{Instruction::IGET_WIDE, Instruction::RETURN_WIDE}, kIGetWide},
572 {{Instruction::IPUT, Instruction::RETURN_VOID}, kIPut},
573 {{Instruction::IPUT_BOOLEAN, Instruction::RETURN_VOID}, kIPutBoolean},
574 {{Instruction::IPUT_OBJECT, Instruction::RETURN_VOID}, kIPutObject},
575 {{Instruction::IPUT_BYTE, Instruction::RETURN_VOID}, kIPutByte},
576 {{Instruction::IPUT_CHAR, Instruction::RETURN_VOID}, kIPutChar},
577 {{Instruction::IPUT_SHORT, Instruction::RETURN_VOID}, kIPutShort},
578 {{Instruction::IPUT_WIDE, Instruction::RETURN_VOID}, kIPutWide},
579 {{Instruction::RETURN}, kIdentity},
580 {{Instruction::RETURN_OBJECT}, kIdentity},
581 {{Instruction::RETURN_WIDE}, kIdentity},
buzbee16da88c2012-03-20 10:38:17 -0700582};
buzbee5de34942012-03-01 14:51:57 -0800583
buzbee5abfa3e2012-01-31 17:01:43 -0800584BasicBlock* oatNewBB(CompilationUnit* cUnit, BBType blockType, int blockId);
buzbee67bf8852011-08-17 17:51:35 -0700585
586void oatAppendMIR(BasicBlock* bb, MIR* mir);
587
588void oatPrependMIR(BasicBlock* bb, MIR* mir);
589
590void oatInsertMIRAfter(BasicBlock* bb, MIR* currentMIR, MIR* newMIR);
591
592void oatAppendLIR(CompilationUnit* cUnit, LIR* lir);
593
594void oatInsertLIRBefore(LIR* currentLIR, LIR* newLIR);
595
596void oatInsertLIRAfter(LIR* currentLIR, LIR* newLIR);
597
buzbee15bf9802012-06-12 17:49:27 -0700598MIR* oatFindMoveResult(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir);
buzbee67bf8852011-08-17 17:51:35 -0700599/* Debug Utilities */
600void oatDumpCompilationUnit(CompilationUnit* cUnit);
601
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800602} // namespace art
603
buzbee67bf8852011-08-17 17:51:35 -0700604#endif // ART_SRC_COMPILER_COMPILER_IR_H_