blob: c6d14c3de341b1156fab17bb667544b5f0c11340 [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
20#include "codegen/Optimizer.h"
Ian Rogers1bddec32012-02-04 12:27:34 -080021#include "CompilerUtility.h"
buzbeec143c552011-08-20 17:38:58 -070022#include <vector>
buzbee31a4a6f2012-02-28 15:36:15 -080023#include "oat_compilation_unit.h"
buzbee67bf8852011-08-17 17:51:35 -070024
Elliott Hughes11d1b0c2012-01-23 16:57:47 -080025namespace art {
26
buzbee31a4a6f2012-02-28 15:36:15 -080027#define SLOW_FIELD_PATH (cUnit->enableDebug & (1 << kDebugSlowFieldPath))
28#define SLOW_INVOKE_PATH (cUnit->enableDebug & (1 << kDebugSlowInvokePath))
29#define SLOW_STRING_PATH (cUnit->enableDebug & (1 << kDebugSlowStringPath))
30#define SLOW_TYPE_PATH (cUnit->enableDebug & (1 << kDebugSlowTypePath))
31#define EXERCISE_SLOWEST_FIELD_PATH (cUnit->enableDebug & \
32 (1 << kDebugSlowestFieldPath))
33#define EXERCISE_SLOWEST_STRING_PATH (cUnit->enableDebug & \
34 (1 << kDebugSlowestStringPath))
35#define EXERCISE_RESOLVE_METHOD (cUnit->enableDebug & \
36 (1 << kDebugExerciseResolveMethod))
37
Elliott Hughes719ace42012-03-09 18:06:03 -080038enum RegisterClass {
buzbee67bf8852011-08-17 17:51:35 -070039 kCoreReg,
40 kFPReg,
41 kAnyReg,
Elliott Hughes719ace42012-03-09 18:06:03 -080042};
buzbee67bf8852011-08-17 17:51:35 -070043
Elliott Hughes719ace42012-03-09 18:06:03 -080044enum RegLocationType {
buzbee67bf8852011-08-17 17:51:35 -070045 kLocDalvikFrame = 0, // Normal Dalvik register
46 kLocPhysReg,
47 kLocSpill,
Elliott Hughes719ace42012-03-09 18:06:03 -080048};
buzbee67bf8852011-08-17 17:51:35 -070049
Elliott Hughes719ace42012-03-09 18:06:03 -080050struct PromotionMap {
buzbee67bc2362011-10-11 18:08:40 -070051 RegLocationType coreLocation:3;
52 u1 coreReg;
53 RegLocationType fpLocation:3;
54 u1 fpReg;
55 bool firstInPair;
Elliott Hughes719ace42012-03-09 18:06:03 -080056};
buzbee67bc2362011-10-11 18:08:40 -070057
Elliott Hughes719ace42012-03-09 18:06:03 -080058struct RegLocation {
buzbee67bc2362011-10-11 18:08:40 -070059 RegLocationType location:3;
buzbee67bf8852011-08-17 17:51:35 -070060 unsigned wide:1;
buzbee67bc2362011-10-11 18:08:40 -070061 unsigned defined:1; // Do we know the type?
62 unsigned fp:1; // Floating point?
63 unsigned core:1; // Non-floating point?
64 unsigned highWord:1; // High word of pair?
65 unsigned home:1; // Does this represent the home location?
66 u1 lowReg; // First physical register
67 u1 highReg; // 2nd physical register (if wide)
68 s2 sRegLow; // SSA name for low Dalvik word
Elliott Hughes719ace42012-03-09 18:06:03 -080069};
buzbee67bf8852011-08-17 17:51:35 -070070
buzbeee3acd072012-02-25 17:03:10 -080071 /*
72 * Data structure tracking the mapping between a Dalvik register (pair) and a
73 * native register (pair). The idea is to reuse the previously loaded value
74 * if possible, otherwise to keep the value in a native register as long as
75 * possible.
76 */
Elliott Hughes719ace42012-03-09 18:06:03 -080077struct RegisterInfo {
buzbeee3acd072012-02-25 17:03:10 -080078 int reg; // Reg number
79 bool inUse; // Has it been allocated?
80 bool isTemp; // Can allocate as temp?
81 bool pair; // Part of a register pair?
82 int partner; // If pair, other reg of pair
83 bool live; // Is there an associated SSA name?
84 bool dirty; // If live, is it dirty?
85 int sReg; // Name of live value
86 struct LIR *defStart; // Starting inst in last def sequence
87 struct LIR *defEnd; // Ending inst in last def sequence
Elliott Hughes719ace42012-03-09 18:06:03 -080088};
buzbeee3acd072012-02-25 17:03:10 -080089
Elliott Hughes719ace42012-03-09 18:06:03 -080090struct RegisterPool {
buzbeee3acd072012-02-25 17:03:10 -080091 int numCoreRegs;
92 RegisterInfo *coreRegs;
93 int nextCoreReg;
94 int numFPRegs;
95 RegisterInfo *FPRegs;
96 int nextFPReg;
Elliott Hughes719ace42012-03-09 18:06:03 -080097};
buzbeee3acd072012-02-25 17:03:10 -080098
buzbee67bf8852011-08-17 17:51:35 -070099#define INVALID_SREG (-1)
buzbee3ddc0d12011-10-05 10:36:21 -0700100#define INVALID_VREG (0xFFFFU)
buzbee67bc2362011-10-11 18:08:40 -0700101#define INVALID_REG (0xFF)
buzbee67bf8852011-08-17 17:51:35 -0700102#define INVALID_OFFSET (-1)
103
buzbee99ba9642012-01-25 14:23:14 -0800104/*
105 * Some code patterns cause the generation of excessively large
106 * methods - in particular initialization sequences. There isn't much
107 * benefit in optimizing these methods, and the cost can be very high.
108 * We attempt to identify these cases, and avoid performing most dataflow
109 * analysis. Two thresholds are used - one for known initializers and one
buzbee5abfa3e2012-01-31 17:01:43 -0800110 * for everything else.
buzbee99ba9642012-01-25 14:23:14 -0800111 */
buzbee5abfa3e2012-01-31 17:01:43 -0800112#define MANY_BLOCKS_INITIALIZER 1000 /* Threshold for switching dataflow off */
113#define MANY_BLOCKS 4000 /* Non-initializer threshold */
buzbee99ba9642012-01-25 14:23:14 -0800114
Elliott Hughes719ace42012-03-09 18:06:03 -0800115enum BBType {
buzbee67bf8852011-08-17 17:51:35 -0700116 kEntryBlock,
117 kDalvikByteCode,
118 kExitBlock,
119 kExceptionHandling,
120 kCatchEntry,
Elliott Hughes719ace42012-03-09 18:06:03 -0800121};
buzbee67bf8852011-08-17 17:51:35 -0700122
buzbee31a4a6f2012-02-28 15:36:15 -0800123/* Utility macros to traverse the LIR list */
124#define NEXT_LIR(lir) (lir->next)
125#define PREV_LIR(lir) (lir->prev)
126
127#define NEXT_LIR_LVALUE(lir) (lir)->next
128#define PREV_LIR_LVALUE(lir) (lir)->prev
129
Elliott Hughes719ace42012-03-09 18:06:03 -0800130struct LIR {
buzbee67bf8852011-08-17 17:51:35 -0700131 int offset; // Offset of this instruction
132 int dalvikOffset; // Offset of Dalvik opcode
133 struct LIR* next;
134 struct LIR* prev;
135 struct LIR* target;
buzbee31a4a6f2012-02-28 15:36:15 -0800136 int opcode;
137 int operands[4]; // [0..3] = [dest, src1, src2, extra]
138 struct {
139 bool isNop:1; // LIR is optimized away
140 bool pcRelFixup:1; // May need pc-relative fixup
141 unsigned int age:4; // default is 0, set lazily by the optimizer
buzbee71ac9942012-03-01 17:23:10 -0800142 unsigned int size:5; // in bytes
143 unsigned int unused:21;
buzbee31a4a6f2012-02-28 15:36:15 -0800144 } flags;
145 int aliasInfo; // For Dalvik register & litpool disambiguation
146 u8 useMask; // Resource mask for use
147 u8 defMask; // Resource mask for def
Elliott Hughes719ace42012-03-09 18:06:03 -0800148};
buzbee67bf8852011-08-17 17:51:35 -0700149
150enum ExtendedMIROpcode {
151 kMirOpFirst = kNumPackedOpcodes,
152 kMirOpPhi = kMirOpFirst,
153 kMirOpNullNRangeUpCheck,
154 kMirOpNullNRangeDownCheck,
155 kMirOpLowerBound,
156 kMirOpPunt,
157 kMirOpCheckInlinePrediction, // Gen checks for predicted inlining
158 kMirOpLast,
159};
160
161struct SSARepresentation;
162
Elliott Hughes719ace42012-03-09 18:06:03 -0800163enum MIROptimizationFlagPositons {
buzbee67bf8852011-08-17 17:51:35 -0700164 kMIRIgnoreNullCheck = 0,
165 kMIRNullCheckOnly,
166 kMIRIgnoreRangeCheck,
167 kMIRRangeCheckOnly,
168 kMIRInlined, // Invoke is inlined (ie dead)
169 kMIRInlinedPred, // Invoke is inlined via prediction
170 kMIRCallee, // Instruction is inlined from callee
buzbeec1f45042011-09-21 16:03:19 -0700171 kMIRIgnoreSuspendCheck,
Elliott Hughes719ace42012-03-09 18:06:03 -0800172};
buzbee67bf8852011-08-17 17:51:35 -0700173
174#define MIR_IGNORE_NULL_CHECK (1 << kMIRIgnoreNullCheck)
175#define MIR_NULL_CHECK_ONLY (1 << kMIRNullCheckOnly)
176#define MIR_IGNORE_RANGE_CHECK (1 << kMIRIgnoreRangeCheck)
177#define MIR_RANGE_CHECK_ONLY (1 << kMIRRangeCheckOnly)
178#define MIR_INLINED (1 << kMIRInlined)
179#define MIR_INLINED_PRED (1 << kMIRInlinedPred)
180#define MIR_CALLEE (1 << kMIRCallee)
buzbeec1f45042011-09-21 16:03:19 -0700181#define MIR_IGNORE_SUSPEND_CHECK (1 << kMIRIgnoreSuspendCheck)
buzbee67bf8852011-08-17 17:51:35 -0700182
Elliott Hughes719ace42012-03-09 18:06:03 -0800183struct CallsiteInfo {
buzbee67bf8852011-08-17 17:51:35 -0700184 const char* classDescriptor;
185 Object* classLoader;
186 const Method* method;
187 LIR* misPredBranchOver;
Elliott Hughes719ace42012-03-09 18:06:03 -0800188};
buzbee67bf8852011-08-17 17:51:35 -0700189
Elliott Hughes719ace42012-03-09 18:06:03 -0800190struct MIR {
buzbee67bf8852011-08-17 17:51:35 -0700191 DecodedInstruction dalvikInsn;
192 unsigned int width;
193 unsigned int offset;
194 struct MIR* prev;
195 struct MIR* next;
196 struct SSARepresentation* ssaRep;
buzbee43a36422011-09-14 14:00:13 -0700197 int optimizationFlags;
buzbee67bf8852011-08-17 17:51:35 -0700198 int seqNum;
199 union {
200 // Used by the inlined insn from the callee to find the mother method
201 const Method* calleeMethod;
202 // Used by the inlined invoke to find the class and method pointers
203 CallsiteInfo* callsiteInfo;
buzbeec0ecd652011-09-25 18:11:54 -0700204 // Used to quickly locate all Phi opcodes
205 struct MIR* phiNext;
buzbee67bf8852011-08-17 17:51:35 -0700206 } meta;
Elliott Hughes719ace42012-03-09 18:06:03 -0800207};
buzbee67bf8852011-08-17 17:51:35 -0700208
209struct BasicBlockDataFlow;
210
211/* For successorBlockList */
Elliott Hughes719ace42012-03-09 18:06:03 -0800212enum BlockListType {
buzbee67bf8852011-08-17 17:51:35 -0700213 kNotUsed = 0,
214 kCatch,
215 kPackedSwitch,
216 kSparseSwitch,
Elliott Hughes719ace42012-03-09 18:06:03 -0800217};
buzbee67bf8852011-08-17 17:51:35 -0700218
Elliott Hughes719ace42012-03-09 18:06:03 -0800219struct BasicBlock {
buzbee67bf8852011-08-17 17:51:35 -0700220 int id;
buzbee5b537102012-01-17 17:33:47 -0800221 int dfsId;
buzbee67bf8852011-08-17 17:51:35 -0700222 bool visited;
223 bool hidden;
buzbee43a36422011-09-14 14:00:13 -0700224 bool catchEntry;
buzbee67bf8852011-08-17 17:51:35 -0700225 unsigned int startOffset;
226 const Method* containingMethod; // For blocks from the callee
227 BBType blockType;
228 bool needFallThroughBranch; // For blocks ended due to length limit
229 bool isFallThroughFromInvoke; // True means the block needs alignment
230 MIR* firstMIRInsn;
231 MIR* lastMIRInsn;
232 struct BasicBlock* fallThrough;
233 struct BasicBlock* taken;
234 struct BasicBlock* iDom; // Immediate dominator
235 struct BasicBlockDataFlow* dataFlowInfo;
buzbee5abfa3e2012-01-31 17:01:43 -0800236 GrowableList* predecessors;
buzbee67bf8852011-08-17 17:51:35 -0700237 ArenaBitVector* dominators;
238 ArenaBitVector* iDominated; // Set nodes being immediately dominated
239 ArenaBitVector* domFrontier; // Dominance frontier
240 struct { // For one-to-many successors like
241 BlockListType blockListType; // switch and exception handling
242 GrowableList blocks;
243 } successorBlockList;
Elliott Hughes719ace42012-03-09 18:06:03 -0800244};
buzbee67bf8852011-08-17 17:51:35 -0700245
246/*
247 * The "blocks" field in "successorBlockList" points to an array of
248 * elements with the type "SuccessorBlockInfo".
249 * For catch blocks, key is type index for the exception.
250 * For swtich blocks, key is the case value.
251 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800252struct SuccessorBlockInfo {
buzbee67bf8852011-08-17 17:51:35 -0700253 BasicBlock* block;
254 int key;
Elliott Hughes719ace42012-03-09 18:06:03 -0800255};
buzbee67bf8852011-08-17 17:51:35 -0700256
257struct LoopAnalysis;
258struct RegisterPool;
buzbeeba938cb2012-02-03 14:47:55 -0800259struct ArenaMemBlock;
260struct Memstats;
buzbee67bf8852011-08-17 17:51:35 -0700261
Elliott Hughes719ace42012-03-09 18:06:03 -0800262enum AssemblerStatus {
buzbee67bf8852011-08-17 17:51:35 -0700263 kSuccess,
264 kRetryAll,
265 kRetryHalve
Elliott Hughes719ace42012-03-09 18:06:03 -0800266};
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 {
buzbee67bf8852011-08-17 17:51:35 -0700271 int numInsts;
272 int numBlocks;
273 GrowableList blockList;
Ian Rogers996cc582012-02-14 22:23:29 -0800274 Compiler* compiler; // Compiler driving this compiler
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800275 ClassLinker* class_linker; // Linker to resolve fields and methods
276 const DexFile* dex_file; // DexFile containing the method being compiled
277 DexCache* dex_cache; // DexFile's corresponding cache
278 const ClassLoader* class_loader; // compiling method's class loader
Ian Rogersa3760aa2011-11-14 14:32:37 -0800279 uint32_t method_idx; // compiling method's index into method_ids of DexFile
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800280 const DexFile::CodeItem* code_item; // compiling method's DexFile code_item
Ian Rogersa3760aa2011-11-14 14:32:37 -0800281 uint32_t access_flags; // compiling method's access flags
282 const char* shorty; // compiling method's shorty
buzbee67bf8852011-08-17 17:51:35 -0700283 LIR* firstLIRInsn;
284 LIR* lastLIRInsn;
285 LIR* literalList; // Constants
286 LIR* classPointerList; // Relocatable
287 int numClassPointers;
288 LIR* chainCellOffsetLIR;
buzbeece302932011-10-04 14:32:18 -0700289 uint32_t disableOpt; // optControlVector flags
290 uint32_t enableDebug; // debugControlVector flags
buzbee67bf8852011-08-17 17:51:35 -0700291 int headerSize; // bytes before the first code ptr
292 int dataOffset; // starting offset of literal pool
293 int totalSize; // header + code size
294 AssemblerStatus assemblerStatus; // Success or fix and retry
295 int assemblerRetries;
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800296 std::vector<uint16_t> codeBuffer;
buzbee4ef76522011-09-08 10:00:32 -0700297 std::vector<uint32_t> mappingTable;
buzbee3ddc0d12011-10-05 10:36:21 -0700298 std::vector<uint16_t> coreVmapTable;
299 std::vector<uint16_t> fpVmapTable;
buzbee44b412b2012-02-04 08:50:53 -0800300 bool genDebugger; // Generate code for debugger
buzbee67bf8852011-08-17 17:51:35 -0700301 bool printMe;
buzbee67bf8852011-08-17 17:51:35 -0700302 bool hasClassLiterals; // Contains class ptrs used as literals
303 bool hasLoop; // Contains a loop
304 bool hasInvoke; // Contains an invoke instruction
305 bool heapMemOp; // Mark mem ops for self verification
306 bool usesLinkRegister; // For self-verification only
307 bool methodTraceSupport; // For TraceView profiling
308 struct RegisterPool* regPool;
309 int optRound; // round number to tell an LIR's age
Elliott Hughesb3bd5f02012-03-08 21:05:27 -0800310 InstructionSet instructionSet;
buzbee67bf8852011-08-17 17:51:35 -0700311 /* Number of total regs used in the whole cUnit after SSA transformation */
312 int numSSARegs;
313 /* Map SSA reg i to the Dalvik[15..0]/Sub[31..16] pair. */
314 GrowableList* ssaToDalvikMap;
315
316 /* The following are new data structures to support SSA representations */
317 /* Map original Dalvik reg i to the SSA[15..0]/Sub[31..16] pair */
318 int* dalvikToSSAMap; // length == method->registersSize
buzbeef0cde542011-09-13 14:55:02 -0700319 int* SSALastDefs; // length == method->registersSize
buzbee67bf8852011-08-17 17:51:35 -0700320 ArenaBitVector* isConstantV; // length == numSSAReg
321 int* constantValues; // length == numSSAReg
buzbeec0ecd652011-09-25 18:11:54 -0700322 int* phiAliasMap; // length == numSSAReg
323 MIR* phiList;
buzbee67bf8852011-08-17 17:51:35 -0700324
325 /* Map SSA names to location */
326 RegLocation* regLocation;
327 int sequenceNumber;
328
buzbee67bc2362011-10-11 18:08:40 -0700329 /* Keep track of Dalvik vReg to physical register mappings */
330 PromotionMap* promotionMap;
331
buzbee67bf8852011-08-17 17:51:35 -0700332 /*
333 * Set to the Dalvik PC of the switch instruction if it has more than
334 * MAX_CHAINED_SWITCH_CASES cases.
335 */
336 const u2* switchOverflowPad;
337
338 int numReachableBlocks;
339 int numDalvikRegisters; // method->registersSize + inlined
340 BasicBlock* entryBlock;
341 BasicBlock* exitBlock;
342 BasicBlock* curBlock;
343 BasicBlock* nextCodegenBlock; // for extended trace codegen
344 GrowableList dfsOrder;
buzbee5b537102012-01-17 17:33:47 -0800345 GrowableList dfsPostOrder;
buzbee67bf8852011-08-17 17:51:35 -0700346 GrowableList domPostOrderTraversal;
buzbee5ade1d22011-09-09 14:44:52 -0700347 GrowableList throwLaunchpads;
buzbeec1f45042011-09-21 16:03:19 -0700348 GrowableList suspendLaunchpads;
buzbee5b537102012-01-17 17:33:47 -0800349 int* iDomList;
buzbee67bf8852011-08-17 17:51:35 -0700350 ArenaBitVector* tryBlockAddr;
351 ArenaBitVector** defBlockMatrix; // numDalvikRegister x numBlocks
352 ArenaBitVector* tempBlockV;
353 ArenaBitVector* tempDalvikRegisterV;
354 ArenaBitVector* tempSSARegisterV; // numSSARegs
355 bool printSSANames;
356 void* blockLabelList;
357 bool quitLoopMode; // cold path/complex bytecode
358 int preservedRegsUsed; // How many callee save regs used
359 /*
buzbee5ade1d22011-09-09 14:44:52 -0700360 * Frame layout details.
361 * NOTE: for debug support it will be necessary to add a structure
362 * to map the Dalvik virtual registers to the promoted registers.
363 * NOTE: "num" fields are in 4-byte words, "Size" and "Offset" in bytes.
buzbee67bf8852011-08-17 17:51:35 -0700364 */
365 int numIns;
366 int numOuts;
Ian Rogersa3760aa2011-11-14 14:32:37 -0800367 int numRegs; // Unlike numDalvikRegisters, does not include ins
buzbeebbaf8942011-10-02 13:08:29 -0700368 int numCoreSpills;
buzbee67bf8852011-08-17 17:51:35 -0700369 int numFPSpills;
370 int numPadding; // # of 4-byte padding cells
371 int regsOffset; // sp-relative offset to beginning of Dalvik regs
372 int insOffset; // sp-relative offset to beginning of Dalvik ins
373 int frameSize;
374 unsigned int coreSpillMask;
375 unsigned int fpSpillMask;
buzbeecefd1872011-09-09 09:59:52 -0700376 unsigned int attrs;
buzbee67bf8852011-08-17 17:51:35 -0700377 /*
378 * CLEANUP/RESTRUCTURE: The code generation utilities don't have a built-in
buzbee03fa2632011-09-20 17:10:57 -0700379 * mechanism to propagate the original Dalvik opcode address to the
buzbee67bf8852011-08-17 17:51:35 -0700380 * associated generated instructions. For the trace compiler, this wasn't
381 * necessary because the interpreter handled all throws and debugging
382 * requests. For now we'll handle this by placing the Dalvik offset
383 * in the CompilationUnit struct before codegen for each instruction.
384 * The low-level LIR creation utilites will pull it from here. Should
385 * be rewritten.
386 */
387 int currentDalvikOffset;
388 GrowableList switchTables;
buzbee67bf8852011-08-17 17:51:35 -0700389 GrowableList fillArrayData;
390 const u2* insns;
391 u4 insnsSize;
buzbee99ba9642012-01-25 14:23:14 -0800392 bool disableDataflow; // Skip dataflow analysis if possible
buzbee5b537102012-01-17 17:33:47 -0800393 std::map<unsigned int, BasicBlock*> blockMap; // findBlock lookup cache
buzbee85d8c1e2012-01-27 15:52:35 -0800394 std::map<unsigned int, LIR*> boundaryMap; // boundary lookup cache
buzbee5abfa3e2012-01-31 17:01:43 -0800395 int defCount; // Used to estimate number of SSA names
buzbeeba938cb2012-02-03 14:47:55 -0800396 std::string* compilerMethodMatch;
397 bool compilerFlipMatch;
398 struct ArenaMemBlock* arenaHead;
399 struct ArenaMemBlock* currentArena;
400 int numArenaBlocks;
401 struct Memstats* mstats;
Elliott Hughes719ace42012-03-09 18:06:03 -0800402};
buzbee67bf8852011-08-17 17:51:35 -0700403
Elliott Hughes719ace42012-03-09 18:06:03 -0800404enum OpSize {
buzbeee3acd072012-02-25 17:03:10 -0800405 kWord,
406 kLong,
407 kSingle,
408 kDouble,
409 kUnsignedHalf,
410 kSignedHalf,
411 kUnsignedByte,
412 kSignedByte,
Elliott Hughes719ace42012-03-09 18:06:03 -0800413};
buzbeee3acd072012-02-25 17:03:10 -0800414
Elliott Hughes719ace42012-03-09 18:06:03 -0800415enum OpKind {
buzbee31a4a6f2012-02-28 15:36:15 -0800416 kOpMov,
417 kOpMvn,
418 kOpCmp,
419 kOpLsl,
420 kOpLsr,
421 kOpAsr,
422 kOpRor,
423 kOpNot,
424 kOpAnd,
425 kOpOr,
426 kOpXor,
427 kOpNeg,
428 kOpAdd,
429 kOpAdc,
430 kOpSub,
431 kOpSbc,
432 kOpRsub,
433 kOpMul,
434 kOpDiv,
435 kOpRem,
436 kOpBic,
437 kOpCmn,
438 kOpTst,
439 kOpBkpt,
440 kOpBlx,
441 kOpPush,
442 kOpPop,
443 kOp2Char,
444 kOp2Short,
445 kOp2Byte,
446 kOpCondBr,
447 kOpUncondBr,
buzbee5de34942012-03-01 14:51:57 -0800448 kOpBx,
buzbee31a4a6f2012-02-28 15:36:15 -0800449 kOpInvalid,
Elliott Hughes719ace42012-03-09 18:06:03 -0800450};
buzbee31a4a6f2012-02-28 15:36:15 -0800451
Ian Rogers680b1bd2012-03-07 20:18:49 -0800452std::ostream& operator<<(std::ostream& os, const OpKind& kind);
453
Elliott Hughes719ace42012-03-09 18:06:03 -0800454enum ConditionCode {
buzbee31a4a6f2012-02-28 15:36:15 -0800455 kCondEq,
456 kCondNe,
457 kCondCs,
458 kCondCc,
459 kCondMi,
460 kCondPl,
461 kCondVs,
462 kCondVc,
463 kCondHi,
464 kCondLs,
465 kCondGe,
466 kCondLt,
467 kCondGt,
468 kCondLe,
469 kCondAl,
470 kCondNv,
Elliott Hughes719ace42012-03-09 18:06:03 -0800471};
buzbee31a4a6f2012-02-28 15:36:15 -0800472
Elliott Hughes719ace42012-03-09 18:06:03 -0800473enum ThrowKind {
buzbee31a4a6f2012-02-28 15:36:15 -0800474 kThrowNullPointer,
475 kThrowDivZero,
476 kThrowArrayBounds,
477 kThrowVerificationError,
478 kThrowNegArraySize,
479 kThrowNoSuchMethod,
480 kThrowStackOverflow,
Elliott Hughes719ace42012-03-09 18:06:03 -0800481};
buzbee31a4a6f2012-02-28 15:36:15 -0800482
Elliott Hughes719ace42012-03-09 18:06:03 -0800483struct SwitchTable {
buzbee5de34942012-03-01 14:51:57 -0800484 int offset;
485 const u2* table; // Original dex table
486 int vaddr; // Dalvik offset of switch opcode
buzbeec5159d52012-03-03 11:48:39 -0800487 LIR* anchor; // Reference instruction for relative offsets
buzbee5de34942012-03-01 14:51:57 -0800488 LIR** targets; // Array of case targets
Elliott Hughes719ace42012-03-09 18:06:03 -0800489};
buzbee5de34942012-03-01 14:51:57 -0800490
Elliott Hughes719ace42012-03-09 18:06:03 -0800491struct FillArrayData {
buzbee5de34942012-03-01 14:51:57 -0800492 int offset;
493 const u2* table; // Original dex table
494 int size;
Elliott Hughesadb8c672012-03-06 16:49:32 -0800495 int vaddr; // Dalvik offset of FILL_ARRAY_DATA opcode
Elliott Hughes719ace42012-03-09 18:06:03 -0800496};
buzbee5de34942012-03-01 14:51:57 -0800497
498
buzbee5abfa3e2012-01-31 17:01:43 -0800499BasicBlock* oatNewBB(CompilationUnit* cUnit, BBType blockType, int blockId);
buzbee67bf8852011-08-17 17:51:35 -0700500
501void oatAppendMIR(BasicBlock* bb, MIR* mir);
502
503void oatPrependMIR(BasicBlock* bb, MIR* mir);
504
505void oatInsertMIRAfter(BasicBlock* bb, MIR* currentMIR, MIR* newMIR);
506
507void oatAppendLIR(CompilationUnit* cUnit, LIR* lir);
508
509void oatInsertLIRBefore(LIR* currentLIR, LIR* newLIR);
510
511void oatInsertLIRAfter(LIR* currentLIR, LIR* newLIR);
512
513/* Debug Utilities */
514void oatDumpCompilationUnit(CompilationUnit* cUnit);
515
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800516} // namespace art
517
buzbee67bf8852011-08-17 17:51:35 -0700518#endif // ART_SRC_COMPILER_COMPILER_IR_H_