1 /* 2 * Copyright (C) 2012 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_LLVM_INTRINSIC_HELPER_H_ 18 #define ART_COMPILER_LLVM_INTRINSIC_HELPER_H_ 19 20 #include "base/logging.h" 21 22 #include <llvm/ADT/DenseMap.h> 23 24 namespace llvm { 25 class Function; 26 class FunctionType; 27 class LLVMContext; 28 class Module; 29 } // namespace llvm 30 31 namespace art { 32 namespace llvm { 33 34 class IRBuilder; 35 36 class IntrinsicHelper { 37 public: 38 enum IntrinsicId { 39 #define DEF_INTRINSICS_FUNC(ID, ...) ID, 40 #include "intrinsic_func_list.def" 41 MaxIntrinsicId, 42 43 // Pseudo-intrinsics Id 44 UnknownId 45 }; 46 47 enum IntrinsicAttribute { 48 kAttrNone = 0, 49 50 // Intrinsic that neither modified the memory state nor refer to the global 51 // state 52 kAttrReadNone = 1 << 0, 53 54 // Intrinsic that doesn't modify the memory state. Note that one should set 55 // this flag carefully when the intrinsic may throw exception. Since the 56 // thread state is implicitly modified when an exception is thrown. 57 kAttrReadOnly = 1 << 1, 58 59 // Note that intrinsic without kAttrNoThrow and kAttrDoThrow set means that 60 // intrinsic generates exception in some cases 61 62 // Intrinsic that never generates exception 63 kAttrNoThrow = 1 << 2, 64 // Intrinsic that always generate exception 65 kAttrDoThrow = 1 << 3, 66 }; 67 68 enum IntrinsicValType { 69 kNone, 70 71 kVoidTy, 72 73 kJavaObjectTy, 74 kJavaMethodTy, 75 kJavaThreadTy, 76 77 kInt1Ty, 78 kInt8Ty, 79 kInt16Ty, 80 kInt32Ty, 81 kInt64Ty, 82 kFloatTy, 83 kDoubleTy, 84 85 kInt1ConstantTy, 86 kInt8ConstantTy, 87 kInt16ConstantTy, 88 kInt32ConstantTy, 89 kInt64ConstantTy, 90 kFloatConstantTy, 91 kDoubleConstantTy, 92 93 kVarArgTy, 94 }; 95 96 enum { 97 kIntrinsicMaxArgc = 5 98 }; 99 100 typedef struct IntrinsicInfo { 101 const char* name_; 102 unsigned attr_; 103 IntrinsicValType ret_val_type_; 104 IntrinsicValType arg_type_[kIntrinsicMaxArgc]; 105 } IntrinsicInfo; 106 107 private: 108 static const IntrinsicInfo Info[]; 109 110 public: 111 static const IntrinsicInfo& GetInfo(IntrinsicId id) { 112 DCHECK(id >= 0 && id < MaxIntrinsicId) << "Unknown ART intrinsics ID: " 113 << id; 114 return Info[id]; 115 } 116 117 static const char* GetName(IntrinsicId id) { 118 return (id <= MaxIntrinsicId) ? GetInfo(id).name_ : "InvalidIntrinsic"; 119 } 120 121 static unsigned GetAttr(IntrinsicId id) { 122 return GetInfo(id).attr_; 123 } 124 125 public: 126 IntrinsicHelper(::llvm::LLVMContext& context, ::llvm::Module& module); 127 128 ::llvm::Function* GetIntrinsicFunction(IntrinsicId id) { 129 DCHECK(id >= 0 && id < MaxIntrinsicId) << "Unknown ART intrinsics ID: " 130 << id; 131 return intrinsic_funcs_[id]; 132 } 133 134 IntrinsicId GetIntrinsicId(const ::llvm::Function* func) const { 135 ::llvm::DenseMap<const ::llvm::Function*, IntrinsicId>::const_iterator 136 i = intrinsic_funcs_map_.find(func); 137 if (i == intrinsic_funcs_map_.end()) { 138 return UnknownId; 139 } else { 140 return i->second; 141 } 142 } 143 144 private: 145 // FIXME: "+1" is to workaround the GCC bugs: 146 // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43949 147 // Remove this when uses newer GCC (> 4.4.3) 148 ::llvm::Function* intrinsic_funcs_[MaxIntrinsicId + 1]; 149 150 // Map a llvm::Function to its intrinsic id 151 ::llvm::DenseMap<const ::llvm::Function*, IntrinsicId> intrinsic_funcs_map_; 152 }; 153 154 } // namespace llvm 155 } // namespace art 156 157 #endif // ART_COMPILER_LLVM_INTRINSIC_HELPER_H_ 158