1/*
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_COMPILER_DEX_PORTABLE_MIR_TO_GBC_H_
18#define ART_COMPILER_DEX_PORTABLE_MIR_TO_GBC_H_
19
20#include "invoke_type.h"
21#include "compiled_method.h"
22#include "dex/compiler_enums.h"
23#include "dex/compiler_ir.h"
24#include "dex/backend.h"
25#include "llvm/llvm_compilation_unit.h"
26#include "safe_map.h"
27
28namespace art {
29
30struct BasicBlock;
31struct CallInfo;
32struct CompilationUnit;
33struct MIR;
34struct RegLocation;
35struct RegisterInfo;
36class MIRGraph;
37
38// Target-specific initialization.
39Backend* PortableCodeGenerator(CompilationUnit* const cu, MIRGraph* const mir_graph,
40                               ArenaAllocator* const arena,
41                               llvm::LlvmCompilationUnit* const llvm_compilation_unit);
42
43class MirConverter : public Backend {
44  public:
45    // TODO: flesh out and integrate into new world order.
46    MirConverter(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena,
47                 llvm::LlvmCompilationUnit* llvm_compilation_unit)
48      : Backend(arena),
49        cu_(cu),
50        mir_graph_(mir_graph),
51        llvm_compilation_unit_(llvm_compilation_unit),
52        llvm_info_(llvm_compilation_unit->GetQuickContext()),
53        symbol_(llvm_compilation_unit->GetDexCompilationUnit()->GetSymbol()),
54        context_(NULL),
55        module_(NULL),
56        func_(NULL),
57        intrinsic_helper_(NULL),
58        irb_(NULL),
59        placeholder_bb_(NULL),
60        entry_bb_(NULL),
61        entry_target_bb_(NULL),
62        llvm_values_(arena, mir_graph->GetNumSSARegs()),
63        temp_name_(0),
64        current_dalvik_offset_(0) {
65      if (kIsDebugBuild) {
66        cu->enable_debug |= (1 << kDebugVerifyBitcode);
67      }
68    }
69
70    void Materialize() {
71      MethodMIR2Bitcode();
72    }
73
74    CompiledMethod* GetCompiledMethod() {
75      return NULL;
76    }
77
78  private:
79    ::llvm::BasicBlock* GetLLVMBlock(int id);
80    ::llvm::Value* GetLLVMValue(int s_reg);
81    void SetVregOnValue(::llvm::Value* val, int s_reg);
82    void DefineValueOnly(::llvm::Value* val, int s_reg);
83    void DefineValue(::llvm::Value* val, int s_reg);
84    ::llvm::Type* LlvmTypeFromLocRec(RegLocation loc);
85    void InitIR();
86    ::llvm::BasicBlock* FindCaseTarget(uint32_t vaddr);
87    void ConvertPackedSwitch(BasicBlock* bb, int32_t table_offset,
88                             RegLocation rl_src);
89    void ConvertSparseSwitch(BasicBlock* bb, int32_t table_offset,
90                             RegLocation rl_src);
91    void ConvertSget(int32_t field_index,
92                     art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest);
93    void ConvertSput(int32_t field_index,
94                     art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_src);
95    void ConvertFillArrayData(int32_t offset, RegLocation rl_array);
96    ::llvm::Value* EmitConst(::llvm::ArrayRef< ::llvm::Value*> src,
97                             RegLocation loc);
98    void EmitPopShadowFrame();
99    ::llvm::Value* EmitCopy(::llvm::ArrayRef< ::llvm::Value*> src,
100                            RegLocation loc);
101    void ConvertMoveException(RegLocation rl_dest);
102    void ConvertThrow(RegLocation rl_src);
103    void ConvertMonitorEnterExit(int opt_flags,
104                                 art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_src);
105    void ConvertArrayLength(int opt_flags, RegLocation rl_dest,
106                            RegLocation rl_src);
107    void EmitSuspendCheck();
108    ::llvm::Value* ConvertCompare(ConditionCode cc,
109                                  ::llvm::Value* src1, ::llvm::Value* src2);
110    void ConvertCompareAndBranch(BasicBlock* bb, MIR* mir, ConditionCode cc,
111                                 RegLocation rl_src1, RegLocation rl_src2);
112    void ConvertCompareZeroAndBranch(BasicBlock* bb, MIR* mir, ConditionCode cc,
113                                     RegLocation rl_src1);
114    ::llvm::Value* GenDivModOp(bool is_div, bool is_long, ::llvm::Value* src1,
115                               ::llvm::Value* src2);
116    ::llvm::Value* GenArithOp(OpKind op, bool is_long, ::llvm::Value* src1,
117                              ::llvm::Value* src2);
118    void ConvertFPArithOp(OpKind op, RegLocation rl_dest, RegLocation rl_src1,
119                          RegLocation rl_src2);
120    void ConvertShift(art::llvm::IntrinsicHelper::IntrinsicId id,
121                      RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2);
122    void ConvertShiftLit(art::llvm::IntrinsicHelper::IntrinsicId id,
123                         RegLocation rl_dest, RegLocation rl_src, int shift_amount);
124    void ConvertArithOp(OpKind op, RegLocation rl_dest, RegLocation rl_src1,
125                        RegLocation rl_src2);
126    void ConvertArithOpLit(OpKind op, RegLocation rl_dest, RegLocation rl_src1,
127                           int32_t imm);
128    void ConvertInvoke(BasicBlock* bb, MIR* mir, InvokeType invoke_type,
129                       bool is_range, bool is_filled_new_array);
130    void ConvertConstObject(uint32_t idx,
131                            art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest);
132    void ConvertCheckCast(uint32_t type_idx, RegLocation rl_src);
133    void ConvertNewInstance(uint32_t type_idx, RegLocation rl_dest);
134    void ConvertNewArray(uint32_t type_idx, RegLocation rl_dest,
135                         RegLocation rl_src);
136    void ConvertAget(int opt_flags, art::llvm::IntrinsicHelper::IntrinsicId id,
137                     RegLocation rl_dest, RegLocation rl_array, RegLocation rl_index);
138    void ConvertAput(int opt_flags, art::llvm::IntrinsicHelper::IntrinsicId id,
139                     RegLocation rl_src, RegLocation rl_array, RegLocation rl_index);
140    void ConvertIget(int opt_flags, art::llvm::IntrinsicHelper::IntrinsicId id,
141                     RegLocation rl_dest, RegLocation rl_obj, int field_index);
142    void ConvertIput(int opt_flags, art::llvm::IntrinsicHelper::IntrinsicId id,
143                     RegLocation rl_src, RegLocation rl_obj, int field_index);
144    void ConvertInstanceOf(uint32_t type_idx, RegLocation rl_dest,
145                           RegLocation rl_src);
146    void ConvertIntToLong(RegLocation rl_dest, RegLocation rl_src);
147    void ConvertLongToInt(RegLocation rl_dest, RegLocation rl_src);
148    void ConvertFloatToDouble(RegLocation rl_dest, RegLocation rl_src);
149    void ConvertDoubleToFloat(RegLocation rl_dest, RegLocation rl_src);
150    void ConvertWideComparison(art::llvm::IntrinsicHelper::IntrinsicId id,
151                               RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2);
152    void ConvertIntNarrowing(RegLocation rl_dest, RegLocation rl_src,
153                             art::llvm::IntrinsicHelper::IntrinsicId id);
154    void ConvertNeg(RegLocation rl_dest, RegLocation rl_src);
155    void ConvertIntToFP(::llvm::Type* ty, RegLocation rl_dest, RegLocation rl_src);
156    void ConvertFPToInt(art::llvm::IntrinsicHelper::IntrinsicId id,
157                        RegLocation rl_dest, RegLocation rl_src);
158    void ConvertNegFP(RegLocation rl_dest, RegLocation rl_src);
159    void ConvertNot(RegLocation rl_dest, RegLocation rl_src);
160    void EmitConstructorBarrier();
161    bool ConvertMIRNode(MIR* mir, BasicBlock* bb, ::llvm::BasicBlock* llvm_bb);
162    void SetDexOffset(int32_t offset);
163    void SetMethodInfo();
164    void HandlePhiNodes(BasicBlock* bb, ::llvm::BasicBlock* llvm_bb);
165    void ConvertExtendedMIR(BasicBlock* bb, MIR* mir, ::llvm::BasicBlock* llvm_bb);
166    bool BlockBitcodeConversion(BasicBlock* bb);
167    ::llvm::FunctionType* GetFunctionType();
168    bool CreateFunction();
169    bool CreateLLVMBasicBlock(BasicBlock* bb);
170    void MethodMIR2Bitcode();
171
172    CompilationUnit* cu_;
173    MIRGraph* mir_graph_;
174    llvm::LlvmCompilationUnit* const llvm_compilation_unit_;
175    LLVMInfo* llvm_info_;
176    std::string symbol_;
177    ::llvm::LLVMContext* context_;
178    ::llvm::Module* module_;
179    ::llvm::Function* func_;
180    art::llvm::IntrinsicHelper* intrinsic_helper_;
181    art::llvm::IRBuilder* irb_;
182    ::llvm::BasicBlock* placeholder_bb_;
183    ::llvm::BasicBlock* entry_bb_;
184    ::llvm::BasicBlock* entry_target_bb_;
185    std::string bitcode_filename_;
186    GrowableArray< ::llvm::Value*> llvm_values_;
187    int32_t temp_name_;
188    SafeMap<int32_t, ::llvm::BasicBlock*> id_to_block_map_;  // block id -> llvm bb.
189    int current_dalvik_offset_;
190};  // Class MirConverter
191
192}  // namespace art
193
194#endif  // ART_COMPILER_DEX_PORTABLE_MIR_TO_GBC_H_
195