blob: 4fa019fbc82cd227a4e7816efc3495eea452c3dc [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;
buzbee52a77fc2012-11-20 19:50:46 -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
buzbee1bc37c62012-11-20 13:35:41 -0800165#define isPseudoOpcode(opcode) (static_cast<int>(opcode) < 0)
166
Elliott Hughes719ace42012-03-09 18:06:03 -0800167struct LIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700168 int offset; // Offset of this instruction
169 int dalvikOffset; // Offset of Dalvik opcode
170 LIR* next;
171 LIR* prev;
172 LIR* target;
173 int opcode;
174 int operands[5]; // [0..4] = [dest, src1, src2, extra, extra2]
175 struct {
176 bool isNop:1; // LIR is optimized away
177 bool pcRelFixup:1; // May need pc-relative fixup
Bill Buzbeea114add2012-05-03 15:00:40 -0700178 unsigned int size:5; // in bytes
buzbeef5f5a122012-09-21 13:57:36 -0700179 unsigned int unused:25;
Bill Buzbeea114add2012-05-03 15:00:40 -0700180 } flags;
181 int aliasInfo; // For Dalvik register & litpool disambiguation
buzbeeeaf09bc2012-11-15 14:51:41 -0800182 uint64_t useMask; // Resource mask for use
183 uint64_t defMask; // Resource mask for def
Elliott Hughes719ace42012-03-09 18:06:03 -0800184};
buzbee67bf8852011-08-17 17:51:35 -0700185
buzbeecbd6d442012-11-17 14:11:25 -0800186extern const char* extendedMIROpNames[kMirOpLast - kMirOpFirst];
buzbee67bf8852011-08-17 17:51:35 -0700187
188struct SSARepresentation;
189
buzbee67bf8852011-08-17 17:51:35 -0700190#define MIR_IGNORE_NULL_CHECK (1 << kMIRIgnoreNullCheck)
191#define MIR_NULL_CHECK_ONLY (1 << kMIRNullCheckOnly)
192#define MIR_IGNORE_RANGE_CHECK (1 << kMIRIgnoreRangeCheck)
193#define MIR_RANGE_CHECK_ONLY (1 << kMIRRangeCheckOnly)
194#define MIR_INLINED (1 << kMIRInlined)
195#define MIR_INLINED_PRED (1 << kMIRInlinedPred)
196#define MIR_CALLEE (1 << kMIRCallee)
buzbeec1f45042011-09-21 16:03:19 -0700197#define MIR_IGNORE_SUSPEND_CHECK (1 << kMIRIgnoreSuspendCheck)
buzbeee1965672012-03-11 18:39:19 -0700198#define MIR_DUP (1 << kMIRDup)
buzbee239c4e72012-03-16 08:42:29 -0700199#define MIR_MARK (1 << kMIRMark)
buzbee67bf8852011-08-17 17:51:35 -0700200
buzbeed1643e42012-09-05 14:06:51 -0700201struct Checkstats {
202 int nullChecks;
203 int nullChecksEliminated;
204 int rangeChecks;
205 int rangeChecksEliminated;
206};
207
Elliott Hughes719ace42012-03-09 18:06:03 -0800208struct MIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700209 DecodedInstruction dalvikInsn;
210 unsigned int width;
211 unsigned int offset;
212 MIR* prev;
213 MIR* next;
214 SSARepresentation* ssaRep;
215 int optimizationFlags;
Bill Buzbeea114add2012-05-03 15:00:40 -0700216 union {
Bill Buzbeea114add2012-05-03 15:00:40 -0700217 // Used to quickly locate all Phi opcodes
218 MIR* phiNext;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700219 // Establish link between two halves of throwing instructions
220 MIR* throwInsn;
Bill Buzbeea114add2012-05-03 15:00:40 -0700221 } meta;
Elliott Hughes719ace42012-03-09 18:06:03 -0800222};
buzbee67bf8852011-08-17 17:51:35 -0700223
224struct BasicBlockDataFlow;
225
Elliott Hughes719ace42012-03-09 18:06:03 -0800226struct BasicBlock {
Bill Buzbeea114add2012-05-03 15:00:40 -0700227 int id;
228 int dfsId;
229 bool visited;
230 bool hidden;
231 bool catchEntry;
buzbee0967a252012-09-14 10:43:54 -0700232 bool explicitThrow;
233 bool conditionalBranch;
buzbee2cfc6392012-05-07 14:51:40 -0700234 bool hasReturn;
Bill Buzbeea114add2012-05-03 15:00:40 -0700235 uint16_t startOffset;
236 uint16_t nestingDepth;
Bill Buzbeea114add2012-05-03 15:00:40 -0700237 BBType blockType;
Bill Buzbeea114add2012-05-03 15:00:40 -0700238 MIR* firstMIRInsn;
239 MIR* lastMIRInsn;
240 BasicBlock* fallThrough;
241 BasicBlock* taken;
242 BasicBlock* iDom; // Immediate dominator
243 BasicBlockDataFlow* dataFlowInfo;
244 GrowableList* predecessors;
245 ArenaBitVector* dominators;
246 ArenaBitVector* iDominated; // Set nodes being immediately dominated
247 ArenaBitVector* domFrontier; // Dominance frontier
248 struct { // For one-to-many successors like
249 BlockListType blockListType; // switch and exception handling
250 GrowableList blocks;
251 } successorBlockList;
Elliott Hughes719ace42012-03-09 18:06:03 -0800252};
buzbee67bf8852011-08-17 17:51:35 -0700253
254/*
255 * The "blocks" field in "successorBlockList" points to an array of
256 * elements with the type "SuccessorBlockInfo".
257 * For catch blocks, key is type index for the exception.
258 * For swtich blocks, key is the case value.
259 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800260struct SuccessorBlockInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700261 BasicBlock* block;
262 int key;
Elliott Hughes719ace42012-03-09 18:06:03 -0800263};
buzbee67bf8852011-08-17 17:51:35 -0700264
265struct LoopAnalysis;
266struct RegisterPool;
buzbeeba938cb2012-02-03 14:47:55 -0800267struct ArenaMemBlock;
268struct Memstats;
buzbee67bf8852011-08-17 17:51:35 -0700269
buzbee5b537102012-01-17 17:33:47 -0800270#define NOTVISITED (-1)
271
Elliott Hughes719ace42012-03-09 18:06:03 -0800272struct CompilationUnit {
Elliott Hughese52e49b2012-04-02 16:05:44 -0700273 CompilationUnit()
Bill Buzbeea114add2012-05-03 15:00:40 -0700274 : numBlocks(0),
275 compiler(NULL),
276 class_linker(NULL),
277 dex_file(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700278 class_loader(NULL),
279 method_idx(0),
280 code_item(NULL),
281 access_flags(0),
Ian Rogers08f753d2012-08-24 14:35:25 -0700282 invoke_type(kDirect),
Bill Buzbeea114add2012-05-03 15:00:40 -0700283 shorty(NULL),
284 firstLIRInsn(NULL),
285 lastLIRInsn(NULL),
286 literalList(NULL),
287 methodLiteralList(NULL),
288 codeLiteralList(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700289 disableOpt(0),
290 enableDebug(0),
Bill Buzbeea114add2012-05-03 15:00:40 -0700291 dataOffset(0),
292 totalSize(0),
293 assemblerStatus(kSuccess),
294 assemblerRetries(0),
Bill Buzbeea114add2012-05-03 15:00:40 -0700295 printMe(false),
Bill Buzbeea114add2012-05-03 15:00:40 -0700296 hasLoop(false),
297 hasInvoke(false),
Bill Buzbeea114add2012-05-03 15:00:40 -0700298 qdMode(false),
Bill Buzbeea114add2012-05-03 15:00:40 -0700299 regPool(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700300 instructionSet(kNone),
301 numSSARegs(0),
302 ssaBaseVRegs(NULL),
303 ssaSubscripts(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700304 ssaStrings(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700305 vRegToSSAMap(NULL),
306 SSALastDefs(NULL),
307 isConstantV(NULL),
308 constantValues(NULL),
309 phiAliasMap(NULL),
310 phiList(NULL),
311 regLocation(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700312 promotionMap(NULL),
313 methodSReg(0),
Bill Buzbeea114add2012-05-03 15:00:40 -0700314 numReachableBlocks(0),
315 numDalvikRegisters(0),
316 entryBlock(NULL),
317 exitBlock(NULL),
318 curBlock(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700319 iDomList(NULL),
320 tryBlockAddr(NULL),
321 defBlockMatrix(NULL),
322 tempBlockV(NULL),
323 tempDalvikRegisterV(NULL),
324 tempSSARegisterV(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700325 tempSSABlockIdV(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700326 blockLabelList(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700327 numIns(0),
328 numOuts(0),
329 numRegs(0),
330 numCoreSpills(0),
331 numFPSpills(0),
332 numCompilerTemps(0),
333 frameSize(0),
334 coreSpillMask(0U),
335 fpSpillMask(0U),
336 attrs(0U),
337 currentDalvikOffset(0),
338 insns(NULL),
339 insnsSize(0U),
340 disableDataflow(false),
341 defCount(0),
342 compilerFlipMatch(false),
343 arenaHead(NULL),
344 currentArena(NULL),
345 numArenaBlocks(0),
346 mstats(NULL),
buzbeed1643e42012-09-05 14:06:51 -0700347 checkstats(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700348 genBitcode(false),
349 context(NULL),
350 module(NULL),
351 func(NULL),
352 intrinsic_helper(NULL),
353 irb(NULL),
354 placeholderBB(NULL),
355 entryBB(NULL),
buzbee4be777b2012-07-12 14:38:18 -0700356 entryTargetBB(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700357 tempName(0),
buzbeeb03f4872012-06-11 15:22:11 -0700358 numShadowFrameEntries(0),
359 shadowMap(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700360#ifndef NDEBUG
361 liveSReg(0),
362#endif
363 opcodeCount(NULL) {}
Elliott Hughese52e49b2012-04-02 16:05:44 -0700364
Bill Buzbeea114add2012-05-03 15:00:40 -0700365 int numBlocks;
366 GrowableList blockList;
367 Compiler* compiler; // Compiler driving this compiler
368 ClassLinker* class_linker; // Linker to resolve fields and methods
369 const DexFile* dex_file; // DexFile containing the method being compiled
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700370 jobject class_loader; // compiling method's class loader
Bill Buzbeea114add2012-05-03 15:00:40 -0700371 uint32_t method_idx; // compiling method's index into method_ids of DexFile
372 const DexFile::CodeItem* code_item; // compiling method's DexFile code_item
373 uint32_t access_flags; // compiling method's access flags
Ian Rogers08f753d2012-08-24 14:35:25 -0700374 InvokeType invoke_type; // compiling method's invocation type
Bill Buzbeea114add2012-05-03 15:00:40 -0700375 const char* shorty; // compiling method's shorty
376 LIR* firstLIRInsn;
377 LIR* lastLIRInsn;
378 LIR* literalList; // Constants
379 LIR* methodLiteralList; // Method literals requiring patching
380 LIR* codeLiteralList; // Code literals requiring patching
Bill Buzbeea114add2012-05-03 15:00:40 -0700381 uint32_t disableOpt; // optControlVector flags
382 uint32_t enableDebug; // debugControlVector flags
Bill Buzbeea114add2012-05-03 15:00:40 -0700383 int dataOffset; // starting offset of literal pool
384 int totalSize; // header + code size
385 AssemblerStatus assemblerStatus; // Success or fix and retry
386 int assemblerRetries;
387 std::vector<uint8_t> codeBuffer;
Bill Buzbeea5b30242012-09-28 07:19:44 -0700388 /*
389 * Holds mapping from native PC to dex PC for safepoints where we may deoptimize.
390 * Native PC is on the return address of the safepointed operation. Dex PC is for
391 * the instruction being executed at the safepoint.
392 */
393 std::vector<uint32_t> pc2dexMappingTable;
394 /*
395 * Holds mapping from Dex PC to native PC for catch entry points. Native PC and Dex PC
396 * immediately preceed the instruction.
397 */
398 std::vector<uint32_t> dex2pcMappingTable;
399 std::vector<uint32_t> combinedMappingTable;
buzbeeca7a5e42012-08-20 11:12:18 -0700400 std::vector<uint32_t> coreVmapTable;
401 std::vector<uint32_t> fpVmapTable;
Ian Rogers0c7abda2012-09-19 13:33:42 -0700402 std::vector<uint8_t> nativeGcMap;
Bill Buzbeea114add2012-05-03 15:00:40 -0700403 bool printMe;
Bill Buzbeea114add2012-05-03 15:00:40 -0700404 bool hasLoop; // Contains a loop
405 bool hasInvoke; // Contains an invoke instruction
Bill Buzbeea114add2012-05-03 15:00:40 -0700406 bool qdMode; // Compile for code size/compile time
Bill Buzbeea114add2012-05-03 15:00:40 -0700407 RegisterPool* regPool;
Bill Buzbeea114add2012-05-03 15:00:40 -0700408 InstructionSet instructionSet;
409 /* Number of total regs used in the whole cUnit after SSA transformation */
410 int numSSARegs;
411 /* Map SSA reg i to the base virtual register/subscript */
412 GrowableList* ssaBaseVRegs;
413 GrowableList* ssaSubscripts;
buzbee2cfc6392012-05-07 14:51:40 -0700414 GrowableList* ssaStrings;
buzbee67bf8852011-08-17 17:51:35 -0700415
Bill Buzbeea114add2012-05-03 15:00:40 -0700416 /* The following are new data structures to support SSA representations */
417 /* Map original Dalvik virtual reg i to the current SSA name */
418 int* vRegToSSAMap; // length == method->registersSize
419 int* SSALastDefs; // length == method->registersSize
420 ArenaBitVector* isConstantV; // length == numSSAReg
421 int* constantValues; // length == numSSAReg
422 int* phiAliasMap; // length == numSSAReg
423 MIR* phiList;
buzbee67bf8852011-08-17 17:51:35 -0700424
Bill Buzbeea114add2012-05-03 15:00:40 -0700425 /* Use counts of ssa names */
426 GrowableList useCounts; // Weighted by nesting depth
427 GrowableList rawUseCounts; // Not weighted
buzbee239c4e72012-03-16 08:42:29 -0700428
Bill Buzbeea114add2012-05-03 15:00:40 -0700429 /* Optimization support */
430 GrowableList loopHeaders;
buzbee239c4e72012-03-16 08:42:29 -0700431
Bill Buzbeea114add2012-05-03 15:00:40 -0700432 /* Map SSA names to location */
433 RegLocation* regLocation;
buzbee67bf8852011-08-17 17:51:35 -0700434
Bill Buzbeea114add2012-05-03 15:00:40 -0700435 /* Keep track of Dalvik vReg to physical register mappings */
436 PromotionMap* promotionMap;
buzbee67bc2362011-10-11 18:08:40 -0700437
Bill Buzbeea114add2012-05-03 15:00:40 -0700438 /* SSA name for Method* */
439 int methodSReg;
buzbeead8f15e2012-06-18 14:49:45 -0700440 RegLocation methodLoc; // Describes location of method*
buzbeee1965672012-03-11 18:39:19 -0700441
Bill Buzbeea114add2012-05-03 15:00:40 -0700442 int numReachableBlocks;
443 int numDalvikRegisters; // method->registersSize
444 BasicBlock* entryBlock;
445 BasicBlock* exitBlock;
446 BasicBlock* curBlock;
Bill Buzbeea114add2012-05-03 15:00:40 -0700447 GrowableList dfsOrder;
448 GrowableList dfsPostOrder;
449 GrowableList domPostOrderTraversal;
450 GrowableList throwLaunchpads;
451 GrowableList suspendLaunchpads;
452 GrowableList intrinsicLaunchpads;
453 GrowableList compilerTemps;
454 int* iDomList;
455 ArenaBitVector* tryBlockAddr;
456 ArenaBitVector** defBlockMatrix; // numDalvikRegister x numBlocks
457 ArenaBitVector* tempBlockV;
458 ArenaBitVector* tempDalvikRegisterV;
459 ArenaBitVector* tempSSARegisterV; // numSSARegs
buzbee2cfc6392012-05-07 14:51:40 -0700460 int* tempSSABlockIdV; // working storage for Phi labels
buzbeea1da8a52012-07-09 14:00:21 -0700461 LIR* blockLabelList;
Bill Buzbeea114add2012-05-03 15:00:40 -0700462 /*
463 * Frame layout details.
464 * NOTE: for debug support it will be necessary to add a structure
465 * to map the Dalvik virtual registers to the promoted registers.
466 * NOTE: "num" fields are in 4-byte words, "Size" and "Offset" in bytes.
467 */
468 int numIns;
469 int numOuts;
470 int numRegs; // Unlike numDalvikRegisters, does not include ins
471 int numCoreSpills;
472 int numFPSpills;
473 int numCompilerTemps;
474 int frameSize;
475 unsigned int coreSpillMask;
476 unsigned int fpSpillMask;
477 unsigned int attrs;
478 /*
479 * CLEANUP/RESTRUCTURE: The code generation utilities don't have a built-in
480 * mechanism to propagate the original Dalvik opcode address to the
481 * associated generated instructions. For the trace compiler, this wasn't
482 * necessary because the interpreter handled all throws and debugging
483 * requests. For now we'll handle this by placing the Dalvik offset
484 * in the CompilationUnit struct before codegen for each instruction.
485 * The low-level LIR creation utilites will pull it from here. Should
486 * be rewritten.
487 */
488 int currentDalvikOffset;
489 GrowableList switchTables;
490 GrowableList fillArrayData;
buzbeeeaf09bc2012-11-15 14:51:41 -0800491 const uint16_t* insns;
492 uint32_t insnsSize;
Bill Buzbeea114add2012-05-03 15:00:40 -0700493 bool disableDataflow; // Skip dataflow analysis if possible
buzbee52a77fc2012-11-20 19:50:46 -0800494 SafeMap<unsigned int, BasicBlock*> blockMap; // FindBlock lookup cache
buzbeed1643e42012-09-05 14:06:51 -0700495 SafeMap<unsigned int, unsigned int> blockIdMap; // Block collapse lookup cache
Bill Buzbeea114add2012-05-03 15:00:40 -0700496 SafeMap<unsigned int, LIR*> boundaryMap; // boundary lookup cache
497 int defCount; // Used to estimate number of SSA names
Elliott Hughese52e49b2012-04-02 16:05:44 -0700498
Bill Buzbeea114add2012-05-03 15:00:40 -0700499 // If non-empty, apply optimizer/debug flags only to matching methods.
500 std::string compilerMethodMatch;
501 // Flips sense of compilerMethodMatch - apply flags if doesn't match.
502 bool compilerFlipMatch;
503 ArenaMemBlock* arenaHead;
504 ArenaMemBlock* currentArena;
505 int numArenaBlocks;
506 Memstats* mstats;
buzbeed1643e42012-09-05 14:06:51 -0700507 Checkstats* checkstats;
buzbee2cfc6392012-05-07 14:51:40 -0700508 bool genBitcode;
buzbee4df2bbd2012-10-11 14:46:06 -0700509 LLVMInfo* llvm_info;
buzbee2cfc6392012-05-07 14:51:40 -0700510 llvm::LLVMContext* context;
511 llvm::Module* module;
512 llvm::Function* func;
513 greenland::IntrinsicHelper* intrinsic_helper;
514 greenland::IRBuilder* irb;
515 llvm::BasicBlock* placeholderBB;
516 llvm::BasicBlock* entryBB;
buzbee4be777b2012-07-12 14:38:18 -0700517 llvm::BasicBlock* entryTargetBB;
buzbee2cfc6392012-05-07 14:51:40 -0700518 std::string bitcode_filename;
519 GrowableList llvmValues;
520 int32_t tempName;
521 SafeMap<llvm::BasicBlock*, LIR*> blockToLabelMap; // llvm bb -> LIR label
522 SafeMap<int32_t, llvm::BasicBlock*> idToBlockMap; // block id -> llvm bb
523 SafeMap<llvm::Value*, RegLocation> locMap; // llvm Value to loc rec
buzbeeb03f4872012-06-11 15:22:11 -0700524 int numShadowFrameEntries;
525 int* shadowMap;
buzbee0967a252012-09-14 10:43:54 -0700526 std::set<llvm::BasicBlock*> llvmBlocks;
buzbee3d661942012-03-14 17:37:27 -0700527#ifndef NDEBUG
Bill Buzbeea114add2012-05-03 15:00:40 -0700528 /*
529 * Sanity checking for the register temp tracking. The same ssa
530 * name should never be associated with one temp register per
531 * instruction compilation.
532 */
533 int liveSReg;
buzbee3d661942012-03-14 17:37:27 -0700534#endif
buzbee6459e7c2012-10-02 14:42:41 -0700535 std::set<uint32_t> catches;
buzbee2cfc6392012-05-07 14:51:40 -0700536 int* opcodeCount; // Count Dalvik opcodes for tuning
Elliott Hughes719ace42012-03-09 18:06:03 -0800537};
buzbee67bf8852011-08-17 17:51:35 -0700538
Elliott Hughes719ace42012-03-09 18:06:03 -0800539struct SwitchTable {
Bill Buzbeea114add2012-05-03 15:00:40 -0700540 int offset;
buzbeeeaf09bc2012-11-15 14:51:41 -0800541 const uint16_t* table; // Original dex table
Bill Buzbeea114add2012-05-03 15:00:40 -0700542 int vaddr; // Dalvik offset of switch opcode
543 LIR* anchor; // Reference instruction for relative offsets
544 LIR** targets; // Array of case targets
Elliott Hughes719ace42012-03-09 18:06:03 -0800545};
buzbee5de34942012-03-01 14:51:57 -0800546
Elliott Hughes719ace42012-03-09 18:06:03 -0800547struct FillArrayData {
Bill Buzbeea114add2012-05-03 15:00:40 -0700548 int offset;
buzbeeeaf09bc2012-11-15 14:51:41 -0800549 const uint16_t* table; // Original dex table
Bill Buzbeea114add2012-05-03 15:00:40 -0700550 int size;
551 int vaddr; // Dalvik offset of FILL_ARRAY_DATA opcode
Elliott Hughes719ace42012-03-09 18:06:03 -0800552};
buzbee5de34942012-03-01 14:51:57 -0800553
buzbee16da88c2012-03-20 10:38:17 -0700554#define MAX_PATTERN_LEN 5
555
buzbee16da88c2012-03-20 10:38:17 -0700556struct CodePattern {
Bill Buzbeea114add2012-05-03 15:00:40 -0700557 const Instruction::Code opcodes[MAX_PATTERN_LEN];
558 const SpecialCaseHandler handlerCode;
buzbee16da88c2012-03-20 10:38:17 -0700559};
560
561static const CodePattern specialPatterns[] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700562 {{Instruction::RETURN_VOID}, kNullMethod},
563 {{Instruction::CONST, Instruction::RETURN}, kConstFunction},
564 {{Instruction::CONST_4, Instruction::RETURN}, kConstFunction},
565 {{Instruction::CONST_4, Instruction::RETURN_OBJECT}, kConstFunction},
566 {{Instruction::CONST_16, Instruction::RETURN}, kConstFunction},
567 {{Instruction::IGET, Instruction:: RETURN}, kIGet},
568 {{Instruction::IGET_BOOLEAN, Instruction::RETURN}, kIGetBoolean},
569 {{Instruction::IGET_OBJECT, Instruction::RETURN_OBJECT}, kIGetObject},
570 {{Instruction::IGET_BYTE, Instruction::RETURN}, kIGetByte},
571 {{Instruction::IGET_CHAR, Instruction::RETURN}, kIGetChar},
572 {{Instruction::IGET_SHORT, Instruction::RETURN}, kIGetShort},
573 {{Instruction::IGET_WIDE, Instruction::RETURN_WIDE}, kIGetWide},
574 {{Instruction::IPUT, Instruction::RETURN_VOID}, kIPut},
575 {{Instruction::IPUT_BOOLEAN, Instruction::RETURN_VOID}, kIPutBoolean},
576 {{Instruction::IPUT_OBJECT, Instruction::RETURN_VOID}, kIPutObject},
577 {{Instruction::IPUT_BYTE, Instruction::RETURN_VOID}, kIPutByte},
578 {{Instruction::IPUT_CHAR, Instruction::RETURN_VOID}, kIPutChar},
579 {{Instruction::IPUT_SHORT, Instruction::RETURN_VOID}, kIPutShort},
580 {{Instruction::IPUT_WIDE, Instruction::RETURN_VOID}, kIPutWide},
581 {{Instruction::RETURN}, kIdentity},
582 {{Instruction::RETURN_OBJECT}, kIdentity},
583 {{Instruction::RETURN_WIDE}, kIdentity},
buzbee16da88c2012-03-20 10:38:17 -0700584};
buzbee5de34942012-03-01 14:51:57 -0800585
buzbee52a77fc2012-11-20 19:50:46 -0800586BasicBlock* NewMemBB(CompilationUnit* cUnit, BBType blockType, int blockId);
buzbee67bf8852011-08-17 17:51:35 -0700587
buzbee52a77fc2012-11-20 19:50:46 -0800588void AppendMIR(BasicBlock* bb, MIR* mir);
buzbee67bf8852011-08-17 17:51:35 -0700589
buzbee52a77fc2012-11-20 19:50:46 -0800590void PrependMIR(BasicBlock* bb, MIR* mir);
buzbee67bf8852011-08-17 17:51:35 -0700591
buzbee52a77fc2012-11-20 19:50:46 -0800592void InsertMIRAfter(BasicBlock* bb, MIR* currentMIR, MIR* newMIR);
buzbee67bf8852011-08-17 17:51:35 -0700593
buzbee52a77fc2012-11-20 19:50:46 -0800594void AppendLIR(CompilationUnit* cUnit, LIR* lir);
buzbee67bf8852011-08-17 17:51:35 -0700595
buzbee52a77fc2012-11-20 19:50:46 -0800596void InsertLIRBefore(LIR* currentLIR, LIR* newLIR);
buzbee67bf8852011-08-17 17:51:35 -0700597
buzbee52a77fc2012-11-20 19:50:46 -0800598void InsertLIRAfter(LIR* currentLIR, LIR* newLIR);
buzbee67bf8852011-08-17 17:51:35 -0700599
buzbee52a77fc2012-11-20 19:50:46 -0800600MIR* FindMoveResult(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir);
buzbee67bf8852011-08-17 17:51:35 -0700601/* Debug Utilities */
buzbee52a77fc2012-11-20 19:50:46 -0800602void DumpCompilationUnit(CompilationUnit* cUnit);
buzbee67bf8852011-08-17 17:51:35 -0700603
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800604} // namespace art
605
buzbee67bf8852011-08-17 17:51:35 -0700606#endif // ART_SRC_COMPILER_COMPILER_IR_H_