blob: f73fe92467ac7fc407439f9877302f4c25d95f8a [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"
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
buzbeeeaf09bc2012-11-15 14:51:41 -080041struct ArenaBitVector;
42struct LIR;
43class LLVMInfo;
44
Elliott Hughes719ace42012-03-09 18:06:03 -080045enum RegisterClass {
Bill Buzbeea114add2012-05-03 15:00:40 -070046 kCoreReg,
47 kFPReg,
48 kAnyReg,
Elliott Hughes719ace42012-03-09 18:06:03 -080049};
buzbee67bf8852011-08-17 17:51:35 -070050
buzbeef0504cd2012-11-13 16:31:10 -080051enum SpecialTargetRegister {
52 kSelf, // Thread
53 kSuspend, // Used to reduce suspend checks
54 kLr,
55 kPc,
56 kSp,
57 kArg0,
58 kArg1,
59 kArg2,
60 kArg3,
61 kFArg0,
62 kFArg1,
63 kFArg2,
64 kFArg3,
65 kRet0,
66 kRet1,
67 kInvokeTgt,
68 kCount
69};
70
Elliott Hughes719ace42012-03-09 18:06:03 -080071enum RegLocationType {
Bill Buzbeea114add2012-05-03 15:00:40 -070072 kLocDalvikFrame = 0, // Normal Dalvik register
73 kLocPhysReg,
74 kLocCompilerTemp,
75 kLocInvalid
Elliott Hughes719ace42012-03-09 18:06:03 -080076};
buzbee67bf8852011-08-17 17:51:35 -070077
Elliott Hughes719ace42012-03-09 18:06:03 -080078struct PromotionMap {
Bill Buzbeea114add2012-05-03 15:00:40 -070079 RegLocationType coreLocation:3;
buzbeeeaf09bc2012-11-15 14:51:41 -080080 uint8_t coreReg;
Bill Buzbeea114add2012-05-03 15:00:40 -070081 RegLocationType fpLocation:3;
buzbeeeaf09bc2012-11-15 14:51:41 -080082 uint8_t fpReg;
Bill Buzbeea114add2012-05-03 15:00:40 -070083 bool firstInPair;
Elliott Hughes719ace42012-03-09 18:06:03 -080084};
buzbee67bc2362011-10-11 18:08:40 -070085
Elliott Hughes719ace42012-03-09 18:06:03 -080086struct RegLocation {
Bill Buzbeea114add2012-05-03 15:00:40 -070087 RegLocationType location:3;
88 unsigned wide:1;
89 unsigned defined:1; // Do we know the type?
buzbee2cfc6392012-05-07 14:51:40 -070090 unsigned isConst:1; // Constant, value in cUnit->constantValues[]
Bill Buzbeea114add2012-05-03 15:00:40 -070091 unsigned fp:1; // Floating point?
92 unsigned core:1; // Non-floating point?
buzbeebff24652012-05-06 16:22:05 -070093 unsigned ref:1; // Something GC cares about
Bill Buzbeea114add2012-05-03 15:00:40 -070094 unsigned highWord:1; // High word of pair?
95 unsigned home:1; // Does this represent the home location?
buzbeeeaf09bc2012-11-15 14:51:41 -080096 uint8_t lowReg; // First physical register
97 uint8_t highReg; // 2nd physical register (if wide)
Bill Buzbeea114add2012-05-03 15:00:40 -070098 int32_t sRegLow; // SSA name for low Dalvik word
buzbee2cfc6392012-05-07 14:51:40 -070099 int32_t origSReg; // TODO: remove after Bitcode gen complete
100 // and consolodate usage w/ sRegLow
buzbeee1965672012-03-11 18:39:19 -0700101};
102
103struct CompilerTemp {
Bill Buzbeea114add2012-05-03 15:00:40 -0700104 int sReg;
105 ArenaBitVector* bv;
Elliott Hughes719ace42012-03-09 18:06:03 -0800106};
buzbee67bf8852011-08-17 17:51:35 -0700107
buzbee3b3dbdd2012-06-13 13:39:34 -0700108struct CallInfo {
buzbee15bf9802012-06-12 17:49:27 -0700109 int numArgWords; // Note: word count, not arg count
110 RegLocation* args; // One for each word of arguments
111 RegLocation result; // Eventual target of MOVE_RESULT
112 int optFlags;
113 InvokeType type;
114 uint32_t dexIdx;
buzbee3b3dbdd2012-06-13 13:39:34 -0700115 uint32_t index; // Method idx for invokes, type idx for FilledNewArray
buzbee15bf9802012-06-12 17:49:27 -0700116 uintptr_t directCode;
117 uintptr_t directMethod;
118 RegLocation target; // Target of following move_result
119 bool skipThis;
120 bool isRange;
121 int offset; // Dalvik offset
122};
123
buzbeee3acd072012-02-25 17:03:10 -0800124 /*
125 * Data structure tracking the mapping between a Dalvik register (pair) and a
126 * native register (pair). The idea is to reuse the previously loaded value
127 * if possible, otherwise to keep the value in a native register as long as
128 * possible.
129 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800130struct RegisterInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700131 int reg; // Reg number
132 bool inUse; // Has it been allocated?
133 bool isTemp; // Can allocate as temp?
134 bool pair; // Part of a register pair?
135 int partner; // If pair, other reg of pair
136 bool live; // Is there an associated SSA name?
137 bool dirty; // If live, is it dirty?
138 int sReg; // Name of live value
139 LIR *defStart; // Starting inst in last def sequence
140 LIR *defEnd; // Ending inst in last def sequence
Elliott Hughes719ace42012-03-09 18:06:03 -0800141};
buzbeee3acd072012-02-25 17:03:10 -0800142
Elliott Hughes719ace42012-03-09 18:06:03 -0800143struct RegisterPool {
Bill Buzbeea114add2012-05-03 15:00:40 -0700144 int numCoreRegs;
145 RegisterInfo *coreRegs;
146 int nextCoreReg;
147 int numFPRegs;
148 RegisterInfo *FPRegs;
149 int nextFPReg;
Elliott Hughes719ace42012-03-09 18:06:03 -0800150};
buzbeee3acd072012-02-25 17:03:10 -0800151
buzbee67bf8852011-08-17 17:51:35 -0700152#define INVALID_SREG (-1)
buzbee3ddc0d12011-10-05 10:36:21 -0700153#define INVALID_VREG (0xFFFFU)
buzbee67bc2362011-10-11 18:08:40 -0700154#define INVALID_REG (0xFF)
buzbeeb046e162012-10-30 15:48:42 -0700155#define INVALID_OFFSET (0xDEADF00FU)
buzbee67bf8852011-08-17 17:51:35 -0700156
buzbeee1965672012-03-11 18:39:19 -0700157/* SSA encodings for special registers */
buzbee9c044ce2012-03-18 13:24:07 -0700158#define SSA_METHOD_BASEREG (-2)
buzbeee1965672012-03-11 18:39:19 -0700159/* First compiler temp basereg, grows smaller */
buzbee9c044ce2012-03-18 13:24:07 -0700160#define SSA_CTEMP_BASEREG (SSA_METHOD_BASEREG - 1)
buzbeee1965672012-03-11 18:39:19 -0700161
buzbee99ba9642012-01-25 14:23:14 -0800162/*
163 * Some code patterns cause the generation of excessively large
164 * methods - in particular initialization sequences. There isn't much
165 * benefit in optimizing these methods, and the cost can be very high.
166 * We attempt to identify these cases, and avoid performing most dataflow
167 * analysis. Two thresholds are used - one for known initializers and one
buzbee5abfa3e2012-01-31 17:01:43 -0800168 * for everything else.
buzbee99ba9642012-01-25 14:23:14 -0800169 */
buzbee5abfa3e2012-01-31 17:01:43 -0800170#define MANY_BLOCKS_INITIALIZER 1000 /* Threshold for switching dataflow off */
171#define MANY_BLOCKS 4000 /* Non-initializer threshold */
buzbee99ba9642012-01-25 14:23:14 -0800172
Elliott Hughes719ace42012-03-09 18:06:03 -0800173enum BBType {
Bill Buzbeea114add2012-05-03 15:00:40 -0700174 kEntryBlock,
175 kDalvikByteCode,
176 kExitBlock,
177 kExceptionHandling,
buzbeed1643e42012-09-05 14:06:51 -0700178 kDead,
Elliott Hughes719ace42012-03-09 18:06:03 -0800179};
buzbee67bf8852011-08-17 17:51:35 -0700180
buzbee31a4a6f2012-02-28 15:36:15 -0800181/* Utility macros to traverse the LIR list */
182#define NEXT_LIR(lir) (lir->next)
183#define PREV_LIR(lir) (lir->prev)
184
buzbeeec137432012-11-13 12:13:16 -0800185/* Defines for aliasInfo (tracks Dalvik register references) */
186#define DECODE_ALIAS_INFO_REG(X) (X & 0xffff)
187#define DECODE_ALIAS_INFO_WIDE_FLAG (0x80000000)
188#define DECODE_ALIAS_INFO_WIDE(X) ((X & DECODE_ALIAS_INFO_WIDE_FLAG) ? 1 : 0)
189#define ENCODE_ALIAS_INFO(REG, ISWIDE) (REG | (ISWIDE ? DECODE_ALIAS_INFO_WIDE_FLAG : 0))
190
191/*
192 * Def/Use encoding in 64-bit useMask/defMask. Low positions used for target-specific
193 * registers (and typically use the register number as the position). High positions
194 * reserved for common and abstract resources.
195 */
196
197enum ResourceEncodingPos {
198 kMustNotAlias = 63,
199 kHeapRef = 62, // Default memory reference type
200 kLiteral = 61, // Literal pool memory reference
201 kDalvikReg = 60, // Dalvik vReg memory reference
202 kFPStatus = 59,
203 kCCode = 58,
204 kLowestCommonResource = kCCode
205};
206
207/* Common resource macros */
208#define ENCODE_CCODE (1ULL << kCCode)
209#define ENCODE_FP_STATUS (1ULL << kFPStatus)
210
211/* Abstract memory locations */
212#define ENCODE_DALVIK_REG (1ULL << kDalvikReg)
213#define ENCODE_LITERAL (1ULL << kLiteral)
214#define ENCODE_HEAP_REF (1ULL << kHeapRef)
215#define ENCODE_MUST_NOT_ALIAS (1ULL << kMustNotAlias)
216
217#define ENCODE_ALL (~0ULL)
218#define ENCODE_MEM (ENCODE_DALVIK_REG | ENCODE_LITERAL | \
219 ENCODE_HEAP_REF | ENCODE_MUST_NOT_ALIAS)
220
Elliott Hughes719ace42012-03-09 18:06:03 -0800221struct LIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700222 int offset; // Offset of this instruction
223 int dalvikOffset; // Offset of Dalvik opcode
224 LIR* next;
225 LIR* prev;
226 LIR* target;
227 int opcode;
228 int operands[5]; // [0..4] = [dest, src1, src2, extra, extra2]
229 struct {
230 bool isNop:1; // LIR is optimized away
231 bool pcRelFixup:1; // May need pc-relative fixup
Bill Buzbeea114add2012-05-03 15:00:40 -0700232 unsigned int size:5; // in bytes
buzbeef5f5a122012-09-21 13:57:36 -0700233 unsigned int unused:25;
Bill Buzbeea114add2012-05-03 15:00:40 -0700234 } flags;
235 int aliasInfo; // For Dalvik register & litpool disambiguation
buzbeeeaf09bc2012-11-15 14:51:41 -0800236 uint64_t useMask; // Resource mask for use
237 uint64_t defMask; // Resource mask for def
Elliott Hughes719ace42012-03-09 18:06:03 -0800238};
buzbee67bf8852011-08-17 17:51:35 -0700239
buzbeeb046e162012-10-30 15:48:42 -0700240/* Shared pseudo opcodes - must be < 0 */
241enum LIRPseudoOpcode {
242 kPseudoExportedPC = -18,
243 kPseudoSafepointPC = -17,
244 kPseudoIntrinsicRetry = -16,
245 kPseudoSuspendTarget = -15,
246 kPseudoThrowTarget = -14,
247 kPseudoCaseLabel = -13,
248 kPseudoMethodEntry = -12,
249 kPseudoMethodExit = -11,
250 kPseudoBarrier = -10,
251 kPseudoExtended = -9,
252 kPseudoSSARep = -8,
253 kPseudoEntryBlock = -7,
254 kPseudoExitBlock = -6,
255 kPseudoTargetLabel = -5,
256 kPseudoDalvikByteCodeBoundary = -4,
257 kPseudoPseudoAlign4 = -3,
258 kPseudoEHBlockLabel = -2,
259 kPseudoNormalBlockLabel = -1,
260};
261
buzbee67bf8852011-08-17 17:51:35 -0700262enum ExtendedMIROpcode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700263 kMirOpFirst = kNumPackedOpcodes,
264 kMirOpPhi = kMirOpFirst,
265 kMirOpCopy,
266 kMirOpFusedCmplFloat,
267 kMirOpFusedCmpgFloat,
268 kMirOpFusedCmplDouble,
269 kMirOpFusedCmpgDouble,
270 kMirOpFusedCmpLong,
271 kMirOpNop,
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700272 kMirOpNullCheck,
273 kMirOpRangeCheck,
274 kMirOpDivZeroCheck,
275 kMirOpCheck,
Bill Buzbeea114add2012-05-03 15:00:40 -0700276 kMirOpLast,
buzbee67bf8852011-08-17 17:51:35 -0700277};
278
279struct SSARepresentation;
280
Elliott Hughes719ace42012-03-09 18:06:03 -0800281enum MIROptimizationFlagPositons {
Bill Buzbeea114add2012-05-03 15:00:40 -0700282 kMIRIgnoreNullCheck = 0,
283 kMIRNullCheckOnly,
284 kMIRIgnoreRangeCheck,
285 kMIRRangeCheckOnly,
286 kMIRInlined, // Invoke is inlined (ie dead)
287 kMIRInlinedPred, // Invoke is inlined via prediction
288 kMIRCallee, // Instruction is inlined from callee
289 kMIRIgnoreSuspendCheck,
290 kMIRDup,
291 kMIRMark, // Temporary node mark
Elliott Hughes719ace42012-03-09 18:06:03 -0800292};
buzbee67bf8852011-08-17 17:51:35 -0700293
294#define MIR_IGNORE_NULL_CHECK (1 << kMIRIgnoreNullCheck)
295#define MIR_NULL_CHECK_ONLY (1 << kMIRNullCheckOnly)
296#define MIR_IGNORE_RANGE_CHECK (1 << kMIRIgnoreRangeCheck)
297#define MIR_RANGE_CHECK_ONLY (1 << kMIRRangeCheckOnly)
298#define MIR_INLINED (1 << kMIRInlined)
299#define MIR_INLINED_PRED (1 << kMIRInlinedPred)
300#define MIR_CALLEE (1 << kMIRCallee)
buzbeec1f45042011-09-21 16:03:19 -0700301#define MIR_IGNORE_SUSPEND_CHECK (1 << kMIRIgnoreSuspendCheck)
buzbeee1965672012-03-11 18:39:19 -0700302#define MIR_DUP (1 << kMIRDup)
buzbee239c4e72012-03-16 08:42:29 -0700303#define MIR_MARK (1 << kMIRMark)
buzbee67bf8852011-08-17 17:51:35 -0700304
buzbeed1643e42012-09-05 14:06:51 -0700305struct Checkstats {
306 int nullChecks;
307 int nullChecksEliminated;
308 int rangeChecks;
309 int rangeChecksEliminated;
310};
311
Elliott Hughes719ace42012-03-09 18:06:03 -0800312struct MIR {
Bill Buzbeea114add2012-05-03 15:00:40 -0700313 DecodedInstruction dalvikInsn;
314 unsigned int width;
315 unsigned int offset;
316 MIR* prev;
317 MIR* next;
318 SSARepresentation* ssaRep;
319 int optimizationFlags;
Bill Buzbeea114add2012-05-03 15:00:40 -0700320 union {
Bill Buzbeea114add2012-05-03 15:00:40 -0700321 // Used to quickly locate all Phi opcodes
322 MIR* phiNext;
Bill Buzbeec9f40dd2012-08-15 11:35:25 -0700323 // Establish link between two halves of throwing instructions
324 MIR* throwInsn;
Bill Buzbeea114add2012-05-03 15:00:40 -0700325 } meta;
Elliott Hughes719ace42012-03-09 18:06:03 -0800326};
buzbee67bf8852011-08-17 17:51:35 -0700327
328struct BasicBlockDataFlow;
329
330/* For successorBlockList */
Elliott Hughes719ace42012-03-09 18:06:03 -0800331enum BlockListType {
Bill Buzbeea114add2012-05-03 15:00:40 -0700332 kNotUsed = 0,
333 kCatch,
334 kPackedSwitch,
335 kSparseSwitch,
Elliott Hughes719ace42012-03-09 18:06:03 -0800336};
buzbee67bf8852011-08-17 17:51:35 -0700337
Elliott Hughes719ace42012-03-09 18:06:03 -0800338struct BasicBlock {
Bill Buzbeea114add2012-05-03 15:00:40 -0700339 int id;
340 int dfsId;
341 bool visited;
342 bool hidden;
343 bool catchEntry;
buzbee0967a252012-09-14 10:43:54 -0700344 bool explicitThrow;
345 bool conditionalBranch;
buzbee2cfc6392012-05-07 14:51:40 -0700346 bool hasReturn;
Bill Buzbeea114add2012-05-03 15:00:40 -0700347 uint16_t startOffset;
348 uint16_t nestingDepth;
Bill Buzbeea114add2012-05-03 15:00:40 -0700349 BBType blockType;
Bill Buzbeea114add2012-05-03 15:00:40 -0700350 MIR* firstMIRInsn;
351 MIR* lastMIRInsn;
352 BasicBlock* fallThrough;
353 BasicBlock* taken;
354 BasicBlock* iDom; // Immediate dominator
355 BasicBlockDataFlow* dataFlowInfo;
356 GrowableList* predecessors;
357 ArenaBitVector* dominators;
358 ArenaBitVector* iDominated; // Set nodes being immediately dominated
359 ArenaBitVector* domFrontier; // Dominance frontier
360 struct { // For one-to-many successors like
361 BlockListType blockListType; // switch and exception handling
362 GrowableList blocks;
363 } successorBlockList;
Elliott Hughes719ace42012-03-09 18:06:03 -0800364};
buzbee67bf8852011-08-17 17:51:35 -0700365
366/*
367 * The "blocks" field in "successorBlockList" points to an array of
368 * elements with the type "SuccessorBlockInfo".
369 * For catch blocks, key is type index for the exception.
370 * For swtich blocks, key is the case value.
371 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800372struct SuccessorBlockInfo {
Bill Buzbeea114add2012-05-03 15:00:40 -0700373 BasicBlock* block;
374 int key;
Elliott Hughes719ace42012-03-09 18:06:03 -0800375};
buzbee67bf8852011-08-17 17:51:35 -0700376
377struct LoopAnalysis;
378struct RegisterPool;
buzbeeba938cb2012-02-03 14:47:55 -0800379struct ArenaMemBlock;
380struct Memstats;
buzbee67bf8852011-08-17 17:51:35 -0700381
Elliott Hughes719ace42012-03-09 18:06:03 -0800382enum AssemblerStatus {
Bill Buzbeea114add2012-05-03 15:00:40 -0700383 kSuccess,
384 kRetryAll,
Elliott Hughes719ace42012-03-09 18:06:03 -0800385};
buzbee67bf8852011-08-17 17:51:35 -0700386
buzbee5b537102012-01-17 17:33:47 -0800387#define NOTVISITED (-1)
388
Elliott Hughes719ace42012-03-09 18:06:03 -0800389struct CompilationUnit {
Elliott Hughese52e49b2012-04-02 16:05:44 -0700390 CompilationUnit()
Bill Buzbeea114add2012-05-03 15:00:40 -0700391 : numBlocks(0),
392 compiler(NULL),
393 class_linker(NULL),
394 dex_file(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700395 class_loader(NULL),
396 method_idx(0),
397 code_item(NULL),
398 access_flags(0),
Ian Rogers08f753d2012-08-24 14:35:25 -0700399 invoke_type(kDirect),
Bill Buzbeea114add2012-05-03 15:00:40 -0700400 shorty(NULL),
401 firstLIRInsn(NULL),
402 lastLIRInsn(NULL),
403 literalList(NULL),
404 methodLiteralList(NULL),
405 codeLiteralList(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700406 disableOpt(0),
407 enableDebug(0),
Bill Buzbeea114add2012-05-03 15:00:40 -0700408 dataOffset(0),
409 totalSize(0),
410 assemblerStatus(kSuccess),
411 assemblerRetries(0),
Bill Buzbeea114add2012-05-03 15:00:40 -0700412 printMe(false),
Bill Buzbeea114add2012-05-03 15:00:40 -0700413 hasLoop(false),
414 hasInvoke(false),
Bill Buzbeea114add2012-05-03 15:00:40 -0700415 qdMode(false),
Bill Buzbeea114add2012-05-03 15:00:40 -0700416 regPool(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700417 instructionSet(kNone),
418 numSSARegs(0),
419 ssaBaseVRegs(NULL),
420 ssaSubscripts(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700421 ssaStrings(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700422 vRegToSSAMap(NULL),
423 SSALastDefs(NULL),
424 isConstantV(NULL),
425 constantValues(NULL),
426 phiAliasMap(NULL),
427 phiList(NULL),
428 regLocation(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700429 promotionMap(NULL),
430 methodSReg(0),
Bill Buzbeea114add2012-05-03 15:00:40 -0700431 numReachableBlocks(0),
432 numDalvikRegisters(0),
433 entryBlock(NULL),
434 exitBlock(NULL),
435 curBlock(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700436 iDomList(NULL),
437 tryBlockAddr(NULL),
438 defBlockMatrix(NULL),
439 tempBlockV(NULL),
440 tempDalvikRegisterV(NULL),
441 tempSSARegisterV(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700442 tempSSABlockIdV(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700443 blockLabelList(NULL),
Bill Buzbeea114add2012-05-03 15:00:40 -0700444 numIns(0),
445 numOuts(0),
446 numRegs(0),
447 numCoreSpills(0),
448 numFPSpills(0),
449 numCompilerTemps(0),
450 frameSize(0),
451 coreSpillMask(0U),
452 fpSpillMask(0U),
453 attrs(0U),
454 currentDalvikOffset(0),
455 insns(NULL),
456 insnsSize(0U),
457 disableDataflow(false),
458 defCount(0),
459 compilerFlipMatch(false),
460 arenaHead(NULL),
461 currentArena(NULL),
462 numArenaBlocks(0),
463 mstats(NULL),
buzbeed1643e42012-09-05 14:06:51 -0700464 checkstats(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700465 genBitcode(false),
466 context(NULL),
467 module(NULL),
468 func(NULL),
469 intrinsic_helper(NULL),
470 irb(NULL),
471 placeholderBB(NULL),
472 entryBB(NULL),
buzbee4be777b2012-07-12 14:38:18 -0700473 entryTargetBB(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700474 tempName(0),
buzbeeb03f4872012-06-11 15:22:11 -0700475 numShadowFrameEntries(0),
476 shadowMap(NULL),
buzbee2cfc6392012-05-07 14:51:40 -0700477#ifndef NDEBUG
478 liveSReg(0),
479#endif
480 opcodeCount(NULL) {}
Elliott Hughese52e49b2012-04-02 16:05:44 -0700481
Bill Buzbeea114add2012-05-03 15:00:40 -0700482 int numBlocks;
483 GrowableList blockList;
484 Compiler* compiler; // Compiler driving this compiler
485 ClassLinker* class_linker; // Linker to resolve fields and methods
486 const DexFile* dex_file; // DexFile containing the method being compiled
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700487 jobject class_loader; // compiling method's class loader
Bill Buzbeea114add2012-05-03 15:00:40 -0700488 uint32_t method_idx; // compiling method's index into method_ids of DexFile
489 const DexFile::CodeItem* code_item; // compiling method's DexFile code_item
490 uint32_t access_flags; // compiling method's access flags
Ian Rogers08f753d2012-08-24 14:35:25 -0700491 InvokeType invoke_type; // compiling method's invocation type
Bill Buzbeea114add2012-05-03 15:00:40 -0700492 const char* shorty; // compiling method's shorty
493 LIR* firstLIRInsn;
494 LIR* lastLIRInsn;
495 LIR* literalList; // Constants
496 LIR* methodLiteralList; // Method literals requiring patching
497 LIR* codeLiteralList; // Code literals requiring patching
Bill Buzbeea114add2012-05-03 15:00:40 -0700498 uint32_t disableOpt; // optControlVector flags
499 uint32_t enableDebug; // debugControlVector flags
Bill Buzbeea114add2012-05-03 15:00:40 -0700500 int dataOffset; // starting offset of literal pool
501 int totalSize; // header + code size
502 AssemblerStatus assemblerStatus; // Success or fix and retry
503 int assemblerRetries;
504 std::vector<uint8_t> codeBuffer;
Bill Buzbeea5b30242012-09-28 07:19:44 -0700505 /*
506 * Holds mapping from native PC to dex PC for safepoints where we may deoptimize.
507 * Native PC is on the return address of the safepointed operation. Dex PC is for
508 * the instruction being executed at the safepoint.
509 */
510 std::vector<uint32_t> pc2dexMappingTable;
511 /*
512 * Holds mapping from Dex PC to native PC for catch entry points. Native PC and Dex PC
513 * immediately preceed the instruction.
514 */
515 std::vector<uint32_t> dex2pcMappingTable;
516 std::vector<uint32_t> combinedMappingTable;
buzbeeca7a5e42012-08-20 11:12:18 -0700517 std::vector<uint32_t> coreVmapTable;
518 std::vector<uint32_t> fpVmapTable;
Ian Rogers0c7abda2012-09-19 13:33:42 -0700519 std::vector<uint8_t> nativeGcMap;
Bill Buzbeea114add2012-05-03 15:00:40 -0700520 bool printMe;
Bill Buzbeea114add2012-05-03 15:00:40 -0700521 bool hasLoop; // Contains a loop
522 bool hasInvoke; // Contains an invoke instruction
Bill Buzbeea114add2012-05-03 15:00:40 -0700523 bool qdMode; // Compile for code size/compile time
Bill Buzbeea114add2012-05-03 15:00:40 -0700524 RegisterPool* regPool;
Bill Buzbeea114add2012-05-03 15:00:40 -0700525 InstructionSet instructionSet;
526 /* Number of total regs used in the whole cUnit after SSA transformation */
527 int numSSARegs;
528 /* Map SSA reg i to the base virtual register/subscript */
529 GrowableList* ssaBaseVRegs;
530 GrowableList* ssaSubscripts;
buzbee2cfc6392012-05-07 14:51:40 -0700531 GrowableList* ssaStrings;
buzbee67bf8852011-08-17 17:51:35 -0700532
Bill Buzbeea114add2012-05-03 15:00:40 -0700533 /* The following are new data structures to support SSA representations */
534 /* Map original Dalvik virtual reg i to the current SSA name */
535 int* vRegToSSAMap; // length == method->registersSize
536 int* SSALastDefs; // length == method->registersSize
537 ArenaBitVector* isConstantV; // length == numSSAReg
538 int* constantValues; // length == numSSAReg
539 int* phiAliasMap; // length == numSSAReg
540 MIR* phiList;
buzbee67bf8852011-08-17 17:51:35 -0700541
Bill Buzbeea114add2012-05-03 15:00:40 -0700542 /* Use counts of ssa names */
543 GrowableList useCounts; // Weighted by nesting depth
544 GrowableList rawUseCounts; // Not weighted
buzbee239c4e72012-03-16 08:42:29 -0700545
Bill Buzbeea114add2012-05-03 15:00:40 -0700546 /* Optimization support */
547 GrowableList loopHeaders;
buzbee239c4e72012-03-16 08:42:29 -0700548
Bill Buzbeea114add2012-05-03 15:00:40 -0700549 /* Map SSA names to location */
550 RegLocation* regLocation;
buzbee67bf8852011-08-17 17:51:35 -0700551
Bill Buzbeea114add2012-05-03 15:00:40 -0700552 /* Keep track of Dalvik vReg to physical register mappings */
553 PromotionMap* promotionMap;
buzbee67bc2362011-10-11 18:08:40 -0700554
Bill Buzbeea114add2012-05-03 15:00:40 -0700555 /* SSA name for Method* */
556 int methodSReg;
buzbeead8f15e2012-06-18 14:49:45 -0700557 RegLocation methodLoc; // Describes location of method*
buzbeee1965672012-03-11 18:39:19 -0700558
Bill Buzbeea114add2012-05-03 15:00:40 -0700559 int numReachableBlocks;
560 int numDalvikRegisters; // method->registersSize
561 BasicBlock* entryBlock;
562 BasicBlock* exitBlock;
563 BasicBlock* curBlock;
Bill Buzbeea114add2012-05-03 15:00:40 -0700564 GrowableList dfsOrder;
565 GrowableList dfsPostOrder;
566 GrowableList domPostOrderTraversal;
567 GrowableList throwLaunchpads;
568 GrowableList suspendLaunchpads;
569 GrowableList intrinsicLaunchpads;
570 GrowableList compilerTemps;
571 int* iDomList;
572 ArenaBitVector* tryBlockAddr;
573 ArenaBitVector** defBlockMatrix; // numDalvikRegister x numBlocks
574 ArenaBitVector* tempBlockV;
575 ArenaBitVector* tempDalvikRegisterV;
576 ArenaBitVector* tempSSARegisterV; // numSSARegs
buzbee2cfc6392012-05-07 14:51:40 -0700577 int* tempSSABlockIdV; // working storage for Phi labels
buzbeea1da8a52012-07-09 14:00:21 -0700578 LIR* blockLabelList;
Bill Buzbeea114add2012-05-03 15:00:40 -0700579 /*
580 * Frame layout details.
581 * NOTE: for debug support it will be necessary to add a structure
582 * to map the Dalvik virtual registers to the promoted registers.
583 * NOTE: "num" fields are in 4-byte words, "Size" and "Offset" in bytes.
584 */
585 int numIns;
586 int numOuts;
587 int numRegs; // Unlike numDalvikRegisters, does not include ins
588 int numCoreSpills;
589 int numFPSpills;
590 int numCompilerTemps;
591 int frameSize;
592 unsigned int coreSpillMask;
593 unsigned int fpSpillMask;
594 unsigned int attrs;
595 /*
596 * CLEANUP/RESTRUCTURE: The code generation utilities don't have a built-in
597 * mechanism to propagate the original Dalvik opcode address to the
598 * associated generated instructions. For the trace compiler, this wasn't
599 * necessary because the interpreter handled all throws and debugging
600 * requests. For now we'll handle this by placing the Dalvik offset
601 * in the CompilationUnit struct before codegen for each instruction.
602 * The low-level LIR creation utilites will pull it from here. Should
603 * be rewritten.
604 */
605 int currentDalvikOffset;
606 GrowableList switchTables;
607 GrowableList fillArrayData;
buzbeeeaf09bc2012-11-15 14:51:41 -0800608 const uint16_t* insns;
609 uint32_t insnsSize;
Bill Buzbeea114add2012-05-03 15:00:40 -0700610 bool disableDataflow; // Skip dataflow analysis if possible
611 SafeMap<unsigned int, BasicBlock*> blockMap; // findBlock lookup cache
buzbeed1643e42012-09-05 14:06:51 -0700612 SafeMap<unsigned int, unsigned int> blockIdMap; // Block collapse lookup cache
Bill Buzbeea114add2012-05-03 15:00:40 -0700613 SafeMap<unsigned int, LIR*> boundaryMap; // boundary lookup cache
614 int defCount; // Used to estimate number of SSA names
Elliott Hughese52e49b2012-04-02 16:05:44 -0700615
Bill Buzbeea114add2012-05-03 15:00:40 -0700616 // If non-empty, apply optimizer/debug flags only to matching methods.
617 std::string compilerMethodMatch;
618 // Flips sense of compilerMethodMatch - apply flags if doesn't match.
619 bool compilerFlipMatch;
620 ArenaMemBlock* arenaHead;
621 ArenaMemBlock* currentArena;
622 int numArenaBlocks;
623 Memstats* mstats;
buzbeed1643e42012-09-05 14:06:51 -0700624 Checkstats* checkstats;
buzbee2cfc6392012-05-07 14:51:40 -0700625 bool genBitcode;
buzbee4df2bbd2012-10-11 14:46:06 -0700626 LLVMInfo* llvm_info;
buzbee2cfc6392012-05-07 14:51:40 -0700627 llvm::LLVMContext* context;
628 llvm::Module* module;
629 llvm::Function* func;
630 greenland::IntrinsicHelper* intrinsic_helper;
631 greenland::IRBuilder* irb;
632 llvm::BasicBlock* placeholderBB;
633 llvm::BasicBlock* entryBB;
buzbee4be777b2012-07-12 14:38:18 -0700634 llvm::BasicBlock* entryTargetBB;
buzbee2cfc6392012-05-07 14:51:40 -0700635 std::string bitcode_filename;
636 GrowableList llvmValues;
637 int32_t tempName;
638 SafeMap<llvm::BasicBlock*, LIR*> blockToLabelMap; // llvm bb -> LIR label
639 SafeMap<int32_t, llvm::BasicBlock*> idToBlockMap; // block id -> llvm bb
640 SafeMap<llvm::Value*, RegLocation> locMap; // llvm Value to loc rec
buzbeeb03f4872012-06-11 15:22:11 -0700641 int numShadowFrameEntries;
642 int* shadowMap;
buzbee0967a252012-09-14 10:43:54 -0700643 std::set<llvm::BasicBlock*> llvmBlocks;
buzbee3d661942012-03-14 17:37:27 -0700644#ifndef NDEBUG
Bill Buzbeea114add2012-05-03 15:00:40 -0700645 /*
646 * Sanity checking for the register temp tracking. The same ssa
647 * name should never be associated with one temp register per
648 * instruction compilation.
649 */
650 int liveSReg;
buzbee3d661942012-03-14 17:37:27 -0700651#endif
buzbee6459e7c2012-10-02 14:42:41 -0700652 std::set<uint32_t> catches;
buzbee2cfc6392012-05-07 14:51:40 -0700653 int* opcodeCount; // Count Dalvik opcodes for tuning
Elliott Hughes719ace42012-03-09 18:06:03 -0800654};
buzbee67bf8852011-08-17 17:51:35 -0700655
Elliott Hughes719ace42012-03-09 18:06:03 -0800656enum OpSize {
Bill Buzbeea114add2012-05-03 15:00:40 -0700657 kWord,
658 kLong,
659 kSingle,
660 kDouble,
661 kUnsignedHalf,
662 kSignedHalf,
663 kUnsignedByte,
664 kSignedByte,
Elliott Hughes719ace42012-03-09 18:06:03 -0800665};
buzbeee3acd072012-02-25 17:03:10 -0800666
Elliott Hughes719ace42012-03-09 18:06:03 -0800667enum OpKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700668 kOpMov,
669 kOpMvn,
670 kOpCmp,
671 kOpLsl,
672 kOpLsr,
673 kOpAsr,
674 kOpRor,
675 kOpNot,
676 kOpAnd,
677 kOpOr,
678 kOpXor,
679 kOpNeg,
680 kOpAdd,
681 kOpAdc,
682 kOpSub,
683 kOpSbc,
684 kOpRsub,
685 kOpMul,
686 kOpDiv,
687 kOpRem,
688 kOpBic,
689 kOpCmn,
690 kOpTst,
691 kOpBkpt,
692 kOpBlx,
693 kOpPush,
694 kOpPop,
695 kOp2Char,
696 kOp2Short,
697 kOp2Byte,
698 kOpCondBr,
699 kOpUncondBr,
700 kOpBx,
701 kOpInvalid,
Elliott Hughes719ace42012-03-09 18:06:03 -0800702};
buzbee31a4a6f2012-02-28 15:36:15 -0800703
Ian Rogers680b1bd2012-03-07 20:18:49 -0800704std::ostream& operator<<(std::ostream& os, const OpKind& kind);
705
Elliott Hughes719ace42012-03-09 18:06:03 -0800706enum ConditionCode {
Bill Buzbeea114add2012-05-03 15:00:40 -0700707 kCondEq, // equal
708 kCondNe, // not equal
709 kCondCs, // carry set (unsigned less than)
710 kCondUlt = kCondCs,
711 kCondCc, // carry clear (unsigned greater than or same)
712 kCondUge = kCondCc,
713 kCondMi, // minus
714 kCondPl, // plus, positive or zero
715 kCondVs, // overflow
716 kCondVc, // no overflow
717 kCondHi, // unsigned greater than
718 kCondLs, // unsigned lower or same
719 kCondGe, // signed greater than or equal
720 kCondLt, // signed less than
721 kCondGt, // signed greater than
722 kCondLe, // signed less than or equal
723 kCondAl, // always
724 kCondNv, // never
Elliott Hughes719ace42012-03-09 18:06:03 -0800725};
buzbee31a4a6f2012-02-28 15:36:15 -0800726
buzbeeb046e162012-10-30 15:48:42 -0700727// Target specific condition encodings
728enum ArmConditionCode {
729 kArmCondEq = 0x0, /* 0000 */
730 kArmCondNe = 0x1, /* 0001 */
731 kArmCondCs = 0x2, /* 0010 */
732 kArmCondCc = 0x3, /* 0011 */
733 kArmCondMi = 0x4, /* 0100 */
734 kArmCondPl = 0x5, /* 0101 */
735 kArmCondVs = 0x6, /* 0110 */
736 kArmCondVc = 0x7, /* 0111 */
737 kArmCondHi = 0x8, /* 1000 */
738 kArmCondLs = 0x9, /* 1001 */
739 kArmCondGe = 0xa, /* 1010 */
740 kArmCondLt = 0xb, /* 1011 */
741 kArmCondGt = 0xc, /* 1100 */
742 kArmCondLe = 0xd, /* 1101 */
743 kArmCondAl = 0xe, /* 1110 */
744 kArmCondNv = 0xf, /* 1111 */
745};
746
747enum X86ConditionCode {
748 kX86CondO = 0x0, // overflow
749 kX86CondNo = 0x1, // not overflow
750
751 kX86CondB = 0x2, // below
752 kX86CondNae = kX86CondB, // not-above-equal
753 kX86CondC = kX86CondB, // carry
754
755 kX86CondNb = 0x3, // not-below
756 kX86CondAe = kX86CondNb, // above-equal
757 kX86CondNc = kX86CondNb, // not-carry
758
759 kX86CondZ = 0x4, // zero
760 kX86CondEq = kX86CondZ, // equal
761
762 kX86CondNz = 0x5, // not-zero
763 kX86CondNe = kX86CondNz, // not-equal
764
765 kX86CondBe = 0x6, // below-equal
766 kX86CondNa = kX86CondBe, // not-above
767
768 kX86CondNbe = 0x7, // not-below-equal
769 kX86CondA = kX86CondNbe,// above
770
771 kX86CondS = 0x8, // sign
772 kX86CondNs = 0x9, // not-sign
773
774 kX86CondP = 0xA, // 8-bit parity even
775 kX86CondPE = kX86CondP,
776
777 kX86CondNp = 0xB, // 8-bit parity odd
778 kX86CondPo = kX86CondNp,
779
780 kX86CondL = 0xC, // less-than
781 kX86CondNge = kX86CondL, // not-greater-equal
782
783 kX86CondNl = 0xD, // not-less-than
784 kX86CondGe = kX86CondNl, // not-greater-equal
785
786 kX86CondLe = 0xE, // less-than-equal
787 kX86CondNg = kX86CondLe, // not-greater
788
789 kX86CondNle = 0xF, // not-less-than
790 kX86CondG = kX86CondNle,// greater
791};
792
793
Elliott Hughes719ace42012-03-09 18:06:03 -0800794enum ThrowKind {
Bill Buzbeea114add2012-05-03 15:00:40 -0700795 kThrowNullPointer,
796 kThrowDivZero,
797 kThrowArrayBounds,
Bill Buzbeea114add2012-05-03 15:00:40 -0700798 kThrowNoSuchMethod,
799 kThrowStackOverflow,
Elliott Hughes719ace42012-03-09 18:06:03 -0800800};
buzbee31a4a6f2012-02-28 15:36:15 -0800801
Elliott Hughes719ace42012-03-09 18:06:03 -0800802struct SwitchTable {
Bill Buzbeea114add2012-05-03 15:00:40 -0700803 int offset;
buzbeeeaf09bc2012-11-15 14:51:41 -0800804 const uint16_t* table; // Original dex table
Bill Buzbeea114add2012-05-03 15:00:40 -0700805 int vaddr; // Dalvik offset of switch opcode
806 LIR* anchor; // Reference instruction for relative offsets
807 LIR** targets; // Array of case targets
Elliott Hughes719ace42012-03-09 18:06:03 -0800808};
buzbee5de34942012-03-01 14:51:57 -0800809
Elliott Hughes719ace42012-03-09 18:06:03 -0800810struct FillArrayData {
Bill Buzbeea114add2012-05-03 15:00:40 -0700811 int offset;
buzbeeeaf09bc2012-11-15 14:51:41 -0800812 const uint16_t* table; // Original dex table
Bill Buzbeea114add2012-05-03 15:00:40 -0700813 int size;
814 int vaddr; // Dalvik offset of FILL_ARRAY_DATA opcode
Elliott Hughes719ace42012-03-09 18:06:03 -0800815};
buzbee5de34942012-03-01 14:51:57 -0800816
buzbee16da88c2012-03-20 10:38:17 -0700817#define MAX_PATTERN_LEN 5
818
819enum SpecialCaseHandler {
Bill Buzbeea114add2012-05-03 15:00:40 -0700820 kNoHandler,
821 kNullMethod,
822 kConstFunction,
823 kIGet,
824 kIGetBoolean,
825 kIGetObject,
826 kIGetByte,
827 kIGetChar,
828 kIGetShort,
829 kIGetWide,
830 kIPut,
831 kIPutBoolean,
832 kIPutObject,
833 kIPutByte,
834 kIPutChar,
835 kIPutShort,
836 kIPutWide,
837 kIdentity,
buzbee16da88c2012-03-20 10:38:17 -0700838};
839
840struct CodePattern {
Bill Buzbeea114add2012-05-03 15:00:40 -0700841 const Instruction::Code opcodes[MAX_PATTERN_LEN];
842 const SpecialCaseHandler handlerCode;
buzbee16da88c2012-03-20 10:38:17 -0700843};
844
845static const CodePattern specialPatterns[] = {
Bill Buzbeea114add2012-05-03 15:00:40 -0700846 {{Instruction::RETURN_VOID}, kNullMethod},
847 {{Instruction::CONST, Instruction::RETURN}, kConstFunction},
848 {{Instruction::CONST_4, Instruction::RETURN}, kConstFunction},
849 {{Instruction::CONST_4, Instruction::RETURN_OBJECT}, kConstFunction},
850 {{Instruction::CONST_16, Instruction::RETURN}, kConstFunction},
851 {{Instruction::IGET, Instruction:: RETURN}, kIGet},
852 {{Instruction::IGET_BOOLEAN, Instruction::RETURN}, kIGetBoolean},
853 {{Instruction::IGET_OBJECT, Instruction::RETURN_OBJECT}, kIGetObject},
854 {{Instruction::IGET_BYTE, Instruction::RETURN}, kIGetByte},
855 {{Instruction::IGET_CHAR, Instruction::RETURN}, kIGetChar},
856 {{Instruction::IGET_SHORT, Instruction::RETURN}, kIGetShort},
857 {{Instruction::IGET_WIDE, Instruction::RETURN_WIDE}, kIGetWide},
858 {{Instruction::IPUT, Instruction::RETURN_VOID}, kIPut},
859 {{Instruction::IPUT_BOOLEAN, Instruction::RETURN_VOID}, kIPutBoolean},
860 {{Instruction::IPUT_OBJECT, Instruction::RETURN_VOID}, kIPutObject},
861 {{Instruction::IPUT_BYTE, Instruction::RETURN_VOID}, kIPutByte},
862 {{Instruction::IPUT_CHAR, Instruction::RETURN_VOID}, kIPutChar},
863 {{Instruction::IPUT_SHORT, Instruction::RETURN_VOID}, kIPutShort},
864 {{Instruction::IPUT_WIDE, Instruction::RETURN_VOID}, kIPutWide},
865 {{Instruction::RETURN}, kIdentity},
866 {{Instruction::RETURN_OBJECT}, kIdentity},
867 {{Instruction::RETURN_WIDE}, kIdentity},
buzbee16da88c2012-03-20 10:38:17 -0700868};
buzbee5de34942012-03-01 14:51:57 -0800869
buzbee5abfa3e2012-01-31 17:01:43 -0800870BasicBlock* oatNewBB(CompilationUnit* cUnit, BBType blockType, int blockId);
buzbee67bf8852011-08-17 17:51:35 -0700871
872void oatAppendMIR(BasicBlock* bb, MIR* mir);
873
874void oatPrependMIR(BasicBlock* bb, MIR* mir);
875
876void oatInsertMIRAfter(BasicBlock* bb, MIR* currentMIR, MIR* newMIR);
877
878void oatAppendLIR(CompilationUnit* cUnit, LIR* lir);
879
880void oatInsertLIRBefore(LIR* currentLIR, LIR* newLIR);
881
882void oatInsertLIRAfter(LIR* currentLIR, LIR* newLIR);
883
buzbee15bf9802012-06-12 17:49:27 -0700884MIR* oatFindMoveResult(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir);
buzbee67bf8852011-08-17 17:51:35 -0700885/* Debug Utilities */
886void oatDumpCompilationUnit(CompilationUnit* cUnit);
887
Elliott Hughes11d1b0c2012-01-23 16:57:47 -0800888} // namespace art
889
buzbee67bf8852011-08-17 17:51:35 -0700890#endif // ART_SRC_COMPILER_COMPILER_IR_H_