167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee/* 267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Copyright (C) 2011 The Android Open Source Project 367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * 467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Licensed under the Apache License, Version 2.0 (the "License"); 567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * you may not use this file except in compliance with the License. 667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * You may obtain a copy of the License at 767bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * 867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * http://www.apache.org/licenses/LICENSE-2.0 967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * 1067bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * Unless required by applicable law or agreed to in writing, software 1167bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * distributed under the License is distributed on an "AS IS" BASIS, 1267bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1367bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * See the License for the specific language governing permissions and 1467bf885d62b1473c833bece1c9e0bb624e6ba391buzbee * limitations under the License. 1567bf885d62b1473c833bece1c9e0bb624e6ba391buzbee */ 1667bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_COMPILER_DEX_PORTABLE_MIR_TO_GBC_H_ 18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_COMPILER_DEX_PORTABLE_MIR_TO_GBC_H_ 1967bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 20b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogers#include <llvm/ADT/ArrayRef.h> 21b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogers#include <llvm/IR/BasicBlock.h> 22b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogers#include <llvm/IR/IRBuilder.h> 23b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogers#include <llvm/IR/LLVMContext.h> 24b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogers#include <llvm/IR/Module.h> 25b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogers 261fd3346740dfb7f47be9922312b68a4227fada96buzbee#include "invoke_type.h" 271fd3346740dfb7f47be9922312b68a4227fada96buzbee#include "compiled_method.h" 287940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/compiler_enums.h" 297940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/compiler_ir.h" 307940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "dex/backend.h" 31b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogers#include "llvm/intrinsic_helper.h" 327940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "llvm/llvm_compilation_unit.h" 331fd3346740dfb7f47be9922312b68a4227fada96buzbee#include "safe_map.h" 341fd3346740dfb7f47be9922312b68a4227fada96buzbee 3511d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughesnamespace art { 3611d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes 371fd3346740dfb7f47be9922312b68a4227fada96buzbeestruct BasicBlock; 381fd3346740dfb7f47be9922312b68a4227fada96buzbeestruct CallInfo; 391fd3346740dfb7f47be9922312b68a4227fada96buzbeestruct CompilationUnit; 401fd3346740dfb7f47be9922312b68a4227fada96buzbeestruct MIR; 411fd3346740dfb7f47be9922312b68a4227fada96buzbeestruct RegLocation; 421fd3346740dfb7f47be9922312b68a4227fada96buzbeestruct RegisterInfo; 431fd3346740dfb7f47be9922312b68a4227fada96buzbeeclass MIRGraph; 441fd3346740dfb7f47be9922312b68a4227fada96buzbee 451fd3346740dfb7f47be9922312b68a4227fada96buzbee// Target-specific initialization. 461fd3346740dfb7f47be9922312b68a4227fada96buzbeeBackend* PortableCodeGenerator(CompilationUnit* const cu, MIRGraph* const mir_graph, 47862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee ArenaAllocator* const arena, 481fd3346740dfb7f47be9922312b68a4227fada96buzbee llvm::LlvmCompilationUnit* const llvm_compilation_unit); 491fd3346740dfb7f47be9922312b68a4227fada96buzbee 501fd3346740dfb7f47be9922312b68a4227fada96buzbeeclass MirConverter : public Backend { 511fd3346740dfb7f47be9922312b68a4227fada96buzbee public: 521fd3346740dfb7f47be9922312b68a4227fada96buzbee // TODO: flesh out and integrate into new world order. 53862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee MirConverter(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena, 541fd3346740dfb7f47be9922312b68a4227fada96buzbee llvm::LlvmCompilationUnit* llvm_compilation_unit) 556282dc12440a2072dc06a616160027ff21bd895eIan Rogers : Backend(arena), 566282dc12440a2072dc06a616160027ff21bd895eIan Rogers cu_(cu), 571fd3346740dfb7f47be9922312b68a4227fada96buzbee mir_graph_(mir_graph), 581fd3346740dfb7f47be9922312b68a4227fada96buzbee llvm_compilation_unit_(llvm_compilation_unit), 591fd3346740dfb7f47be9922312b68a4227fada96buzbee llvm_info_(llvm_compilation_unit->GetQuickContext()), 601fd3346740dfb7f47be9922312b68a4227fada96buzbee symbol_(llvm_compilation_unit->GetDexCompilationUnit()->GetSymbol()), 611fd3346740dfb7f47be9922312b68a4227fada96buzbee context_(NULL), 621fd3346740dfb7f47be9922312b68a4227fada96buzbee module_(NULL), 631fd3346740dfb7f47be9922312b68a4227fada96buzbee func_(NULL), 641fd3346740dfb7f47be9922312b68a4227fada96buzbee intrinsic_helper_(NULL), 651fd3346740dfb7f47be9922312b68a4227fada96buzbee irb_(NULL), 661fd3346740dfb7f47be9922312b68a4227fada96buzbee placeholder_bb_(NULL), 671fd3346740dfb7f47be9922312b68a4227fada96buzbee entry_bb_(NULL), 681fd3346740dfb7f47be9922312b68a4227fada96buzbee entry_target_bb_(NULL), 69862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee llvm_values_(arena, mir_graph->GetNumSSARegs()), 701fd3346740dfb7f47be9922312b68a4227fada96buzbee temp_name_(0), 711fd3346740dfb7f47be9922312b68a4227fada96buzbee current_dalvik_offset_(0) { 721fd3346740dfb7f47be9922312b68a4227fada96buzbee if (kIsDebugBuild) { 731fd3346740dfb7f47be9922312b68a4227fada96buzbee cu->enable_debug |= (1 << kDebugVerifyBitcode); 741fd3346740dfb7f47be9922312b68a4227fada96buzbee } 751fd3346740dfb7f47be9922312b68a4227fada96buzbee } 761fd3346740dfb7f47be9922312b68a4227fada96buzbee 771fd3346740dfb7f47be9922312b68a4227fada96buzbee void Materialize() { 781fd3346740dfb7f47be9922312b68a4227fada96buzbee MethodMIR2Bitcode(); 791fd3346740dfb7f47be9922312b68a4227fada96buzbee } 801fd3346740dfb7f47be9922312b68a4227fada96buzbee 811fd3346740dfb7f47be9922312b68a4227fada96buzbee CompiledMethod* GetCompiledMethod() { 821fd3346740dfb7f47be9922312b68a4227fada96buzbee return NULL; 831fd3346740dfb7f47be9922312b68a4227fada96buzbee } 841fd3346740dfb7f47be9922312b68a4227fada96buzbee 851fd3346740dfb7f47be9922312b68a4227fada96buzbee private: 861fd3346740dfb7f47be9922312b68a4227fada96buzbee ::llvm::BasicBlock* GetLLVMBlock(int id); 871fd3346740dfb7f47be9922312b68a4227fada96buzbee ::llvm::Value* GetLLVMValue(int s_reg); 881fd3346740dfb7f47be9922312b68a4227fada96buzbee void SetVregOnValue(::llvm::Value* val, int s_reg); 891fd3346740dfb7f47be9922312b68a4227fada96buzbee void DefineValueOnly(::llvm::Value* val, int s_reg); 901fd3346740dfb7f47be9922312b68a4227fada96buzbee void DefineValue(::llvm::Value* val, int s_reg); 911fd3346740dfb7f47be9922312b68a4227fada96buzbee ::llvm::Type* LlvmTypeFromLocRec(RegLocation loc); 921fd3346740dfb7f47be9922312b68a4227fada96buzbee void InitIR(); 931fd3346740dfb7f47be9922312b68a4227fada96buzbee ::llvm::BasicBlock* FindCaseTarget(uint32_t vaddr); 941fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertPackedSwitch(BasicBlock* bb, int32_t table_offset, 951fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation rl_src); 961fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertSparseSwitch(BasicBlock* bb, int32_t table_offset, 971fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation rl_src); 981fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertSget(int32_t field_index, 991fd3346740dfb7f47be9922312b68a4227fada96buzbee art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest); 1001fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertSput(int32_t field_index, 1011fd3346740dfb7f47be9922312b68a4227fada96buzbee art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_src); 1021fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertFillArrayData(int32_t offset, RegLocation rl_array); 1031fd3346740dfb7f47be9922312b68a4227fada96buzbee ::llvm::Value* EmitConst(::llvm::ArrayRef< ::llvm::Value*> src, 1041fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation loc); 1051fd3346740dfb7f47be9922312b68a4227fada96buzbee void EmitPopShadowFrame(); 1061fd3346740dfb7f47be9922312b68a4227fada96buzbee ::llvm::Value* EmitCopy(::llvm::ArrayRef< ::llvm::Value*> src, 1071fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation loc); 1081fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertMoveException(RegLocation rl_dest); 1091fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertThrow(RegLocation rl_src); 1101fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertMonitorEnterExit(int opt_flags, 1111fd3346740dfb7f47be9922312b68a4227fada96buzbee art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_src); 1121fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertArrayLength(int opt_flags, RegLocation rl_dest, 1131fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation rl_src); 1141fd3346740dfb7f47be9922312b68a4227fada96buzbee void EmitSuspendCheck(); 1151fd3346740dfb7f47be9922312b68a4227fada96buzbee ::llvm::Value* ConvertCompare(ConditionCode cc, 1161fd3346740dfb7f47be9922312b68a4227fada96buzbee ::llvm::Value* src1, ::llvm::Value* src2); 1171fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertCompareAndBranch(BasicBlock* bb, MIR* mir, ConditionCode cc, 1181fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation rl_src1, RegLocation rl_src2); 1191fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertCompareZeroAndBranch(BasicBlock* bb, MIR* mir, ConditionCode cc, 1201fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation rl_src1); 1211fd3346740dfb7f47be9922312b68a4227fada96buzbee ::llvm::Value* GenDivModOp(bool is_div, bool is_long, ::llvm::Value* src1, 1221fd3346740dfb7f47be9922312b68a4227fada96buzbee ::llvm::Value* src2); 1231fd3346740dfb7f47be9922312b68a4227fada96buzbee ::llvm::Value* GenArithOp(OpKind op, bool is_long, ::llvm::Value* src1, 1241fd3346740dfb7f47be9922312b68a4227fada96buzbee ::llvm::Value* src2); 1251fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertFPArithOp(OpKind op, RegLocation rl_dest, RegLocation rl_src1, 1261fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation rl_src2); 1271fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertShift(art::llvm::IntrinsicHelper::IntrinsicId id, 1281fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); 1291fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertShiftLit(art::llvm::IntrinsicHelper::IntrinsicId id, 1301fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation rl_dest, RegLocation rl_src, int shift_amount); 1311fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertArithOp(OpKind op, RegLocation rl_dest, RegLocation rl_src1, 1321fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation rl_src2); 1331fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertArithOpLit(OpKind op, RegLocation rl_dest, RegLocation rl_src1, 1341fd3346740dfb7f47be9922312b68a4227fada96buzbee int32_t imm); 1351fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertInvoke(BasicBlock* bb, MIR* mir, InvokeType invoke_type, 1361fd3346740dfb7f47be9922312b68a4227fada96buzbee bool is_range, bool is_filled_new_array); 1371fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertConstObject(uint32_t idx, 1381fd3346740dfb7f47be9922312b68a4227fada96buzbee art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest); 1391fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertCheckCast(uint32_t type_idx, RegLocation rl_src); 1401fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertNewInstance(uint32_t type_idx, RegLocation rl_dest); 1411fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertNewArray(uint32_t type_idx, RegLocation rl_dest, 1421fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation rl_src); 1431fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertAget(int opt_flags, art::llvm::IntrinsicHelper::IntrinsicId id, 1441fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation rl_dest, RegLocation rl_array, RegLocation rl_index); 1451fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertAput(int opt_flags, art::llvm::IntrinsicHelper::IntrinsicId id, 1461fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation rl_src, RegLocation rl_array, RegLocation rl_index); 1471fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertIget(int opt_flags, art::llvm::IntrinsicHelper::IntrinsicId id, 1481fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation rl_dest, RegLocation rl_obj, int field_index); 1491fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertIput(int opt_flags, art::llvm::IntrinsicHelper::IntrinsicId id, 1501fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation rl_src, RegLocation rl_obj, int field_index); 1511fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertInstanceOf(uint32_t type_idx, RegLocation rl_dest, 1521fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation rl_src); 1531fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertIntToLong(RegLocation rl_dest, RegLocation rl_src); 1541fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertLongToInt(RegLocation rl_dest, RegLocation rl_src); 1551fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertFloatToDouble(RegLocation rl_dest, RegLocation rl_src); 1561fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertDoubleToFloat(RegLocation rl_dest, RegLocation rl_src); 1571fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertWideComparison(art::llvm::IntrinsicHelper::IntrinsicId id, 1581fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2); 1591fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertIntNarrowing(RegLocation rl_dest, RegLocation rl_src, 1601fd3346740dfb7f47be9922312b68a4227fada96buzbee art::llvm::IntrinsicHelper::IntrinsicId id); 1611fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertNeg(RegLocation rl_dest, RegLocation rl_src); 1621fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertIntToFP(::llvm::Type* ty, RegLocation rl_dest, RegLocation rl_src); 1631fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertFPToInt(art::llvm::IntrinsicHelper::IntrinsicId id, 1641fd3346740dfb7f47be9922312b68a4227fada96buzbee RegLocation rl_dest, RegLocation rl_src); 1651fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertNegFP(RegLocation rl_dest, RegLocation rl_src); 1661fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertNot(RegLocation rl_dest, RegLocation rl_src); 1671fd3346740dfb7f47be9922312b68a4227fada96buzbee void EmitConstructorBarrier(); 1681fd3346740dfb7f47be9922312b68a4227fada96buzbee bool ConvertMIRNode(MIR* mir, BasicBlock* bb, ::llvm::BasicBlock* llvm_bb); 1691fd3346740dfb7f47be9922312b68a4227fada96buzbee void SetDexOffset(int32_t offset); 1701fd3346740dfb7f47be9922312b68a4227fada96buzbee void SetMethodInfo(); 1711fd3346740dfb7f47be9922312b68a4227fada96buzbee void HandlePhiNodes(BasicBlock* bb, ::llvm::BasicBlock* llvm_bb); 1721fd3346740dfb7f47be9922312b68a4227fada96buzbee void ConvertExtendedMIR(BasicBlock* bb, MIR* mir, ::llvm::BasicBlock* llvm_bb); 1731fd3346740dfb7f47be9922312b68a4227fada96buzbee bool BlockBitcodeConversion(BasicBlock* bb); 1741fd3346740dfb7f47be9922312b68a4227fada96buzbee ::llvm::FunctionType* GetFunctionType(); 1751fd3346740dfb7f47be9922312b68a4227fada96buzbee bool CreateFunction(); 1761fd3346740dfb7f47be9922312b68a4227fada96buzbee bool CreateLLVMBasicBlock(BasicBlock* bb); 1771fd3346740dfb7f47be9922312b68a4227fada96buzbee void MethodMIR2Bitcode(); 1781fd3346740dfb7f47be9922312b68a4227fada96buzbee 1791fd3346740dfb7f47be9922312b68a4227fada96buzbee CompilationUnit* cu_; 1801fd3346740dfb7f47be9922312b68a4227fada96buzbee MIRGraph* mir_graph_; 1811fd3346740dfb7f47be9922312b68a4227fada96buzbee llvm::LlvmCompilationUnit* const llvm_compilation_unit_; 1821fd3346740dfb7f47be9922312b68a4227fada96buzbee LLVMInfo* llvm_info_; 1831fd3346740dfb7f47be9922312b68a4227fada96buzbee std::string symbol_; 1841fd3346740dfb7f47be9922312b68a4227fada96buzbee ::llvm::LLVMContext* context_; 1851fd3346740dfb7f47be9922312b68a4227fada96buzbee ::llvm::Module* module_; 1861fd3346740dfb7f47be9922312b68a4227fada96buzbee ::llvm::Function* func_; 1871fd3346740dfb7f47be9922312b68a4227fada96buzbee art::llvm::IntrinsicHelper* intrinsic_helper_; 1881fd3346740dfb7f47be9922312b68a4227fada96buzbee art::llvm::IRBuilder* irb_; 1891fd3346740dfb7f47be9922312b68a4227fada96buzbee ::llvm::BasicBlock* placeholder_bb_; 1901fd3346740dfb7f47be9922312b68a4227fada96buzbee ::llvm::BasicBlock* entry_bb_; 1911fd3346740dfb7f47be9922312b68a4227fada96buzbee ::llvm::BasicBlock* entry_target_bb_; 1921fd3346740dfb7f47be9922312b68a4227fada96buzbee std::string bitcode_filename_; 193862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee GrowableArray< ::llvm::Value*> llvm_values_; 1941fd3346740dfb7f47be9922312b68a4227fada96buzbee int32_t temp_name_; 1951fd3346740dfb7f47be9922312b68a4227fada96buzbee SafeMap<int32_t, ::llvm::BasicBlock*> id_to_block_map_; // block id -> llvm bb. 1961fd3346740dfb7f47be9922312b68a4227fada96buzbee int current_dalvik_offset_; 1971fd3346740dfb7f47be9922312b68a4227fada96buzbee}; // Class MirConverter 19867bf885d62b1473c833bece1c9e0bb624e6ba391buzbee 19911d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes} // namespace art 20011d1b0c31ddd710d26068da8e0e4621002205b4bElliott Hughes 201fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_COMPILER_DEX_PORTABLE_MIR_TO_GBC_H_ 202