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