• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
GetInfo(IntrinsicId id)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 
GetName(IntrinsicId id)117   static const char* GetName(IntrinsicId id) {
118     return (id <= MaxIntrinsicId) ? GetInfo(id).name_ : "InvalidIntrinsic";
119   }
120 
GetAttr(IntrinsicId id)121   static unsigned GetAttr(IntrinsicId id) {
122     return GetInfo(id).attr_;
123   }
124 
125  public:
126   IntrinsicHelper(::llvm::LLVMContext& context, ::llvm::Module& module);
127 
GetIntrinsicFunction(IntrinsicId id)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 
GetIntrinsicId(const::llvm::Function * func)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