blob: 657db402fadca39270711147427dbfb5d2ea32c8 [file] [log] [blame]
Shih-wei Liaoe94d9b22012-05-22 09:01:24 -07001/*
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
Brian Carlstromfc0e3212013-07-17 14:40:12 -070017#ifndef ART_COMPILER_LLVM_INTRINSIC_HELPER_H_
18#define ART_COMPILER_LLVM_INTRINSIC_HELPER_H_
Shih-wei Liaoe94d9b22012-05-22 09:01:24 -070019
Elliott Hughes07ed66b2012-12-12 18:34:25 -080020#include "base/logging.h"
Shih-wei Liaoe94d9b22012-05-22 09:01:24 -070021
22#include <llvm/ADT/DenseMap.h>
23
24namespace llvm {
25 class Function;
26 class FunctionType;
27 class LLVMContext;
28 class Module;
Ian Rogers4c1c2832013-03-04 18:30:13 -080029} // namespace llvm
Shih-wei Liaoe94d9b22012-05-22 09:01:24 -070030
31namespace art {
Ian Rogers4c1c2832013-03-04 18:30:13 -080032namespace llvm {
Shih-wei Liaoe94d9b22012-05-22 09:01:24 -070033
34class IRBuilder;
35
36class 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
Shih-wei Liao21d28f52012-06-12 05:55:00 -070050 // 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
Shih-wei Liaoe94d9b22012-05-22 09:01:24 -070061
62 // Intrinsic that never generates exception
Shih-wei Liao21d28f52012-06-12 05:55:00 -070063 kAttrNoThrow = 1 << 2,
64 // Intrinsic that always generate exception
65 kAttrDoThrow = 1 << 3,
Shih-wei Liaoe94d9b22012-05-22 09:01:24 -070066 };
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,
Shih-wei Liao21d28f52012-06-12 05:55:00 -070082 kFloatTy,
83 kDoubleTy,
Shih-wei Liaoe94d9b22012-05-22 09:01:24 -070084
85 kInt1ConstantTy,
86 kInt8ConstantTy,
87 kInt16ConstantTy,
88 kInt32ConstantTy,
89 kInt64ConstantTy,
Shih-wei Liao21d28f52012-06-12 05:55:00 -070090 kFloatConstantTy,
91 kDoubleConstantTy,
buzbee2cfc6392012-05-07 14:51:40 -070092
Shih-wei Liaoe94d9b22012-05-22 09:01:24 -070093 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:
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700108 static const IntrinsicInfo Info[];
Shih-wei Liaoe94d9b22012-05-22 09:01:24 -0700109
110 public:
111 static const IntrinsicInfo& GetInfo(IntrinsicId id) {
Ian Rogers76ae4fe2013-02-27 16:03:41 -0800112 DCHECK(id >= 0 && id < MaxIntrinsicId) << "Unknown ART intrinsics ID: "
Shih-wei Liaoe94d9b22012-05-22 09:01:24 -0700113 << id;
114 return Info[id];
115 }
116
117 static const char* GetName(IntrinsicId id) {
buzbee2cfc6392012-05-07 14:51:40 -0700118 return (id <= MaxIntrinsicId) ? GetInfo(id).name_ : "InvalidIntrinsic";
Shih-wei Liaoe94d9b22012-05-22 09:01:24 -0700119 }
120
121 static unsigned GetAttr(IntrinsicId id) {
122 return GetInfo(id).attr_;
123 }
124
125 public:
Ian Rogers4c1c2832013-03-04 18:30:13 -0800126 IntrinsicHelper(::llvm::LLVMContext& context, ::llvm::Module& module);
Shih-wei Liaoe94d9b22012-05-22 09:01:24 -0700127
Ian Rogers4c1c2832013-03-04 18:30:13 -0800128 ::llvm::Function* GetIntrinsicFunction(IntrinsicId id) {
Ian Rogers76ae4fe2013-02-27 16:03:41 -0800129 DCHECK(id >= 0 && id < MaxIntrinsicId) << "Unknown ART intrinsics ID: "
Shih-wei Liaoe94d9b22012-05-22 09:01:24 -0700130 << id;
131 return intrinsic_funcs_[id];
132 }
133
Ian Rogers4c1c2832013-03-04 18:30:13 -0800134 IntrinsicId GetIntrinsicId(const ::llvm::Function* func) const {
135 ::llvm::DenseMap<const ::llvm::Function*, IntrinsicId>::const_iterator
Shih-wei Liaoe94d9b22012-05-22 09:01:24 -0700136 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:
Shih-wei Liao21d28f52012-06-12 05:55:00 -0700145 // 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)
Ian Rogers4c1c2832013-03-04 18:30:13 -0800148 ::llvm::Function* intrinsic_funcs_[MaxIntrinsicId + 1];
Shih-wei Liaoe94d9b22012-05-22 09:01:24 -0700149
150 // Map a llvm::Function to its intrinsic id
Ian Rogers4c1c2832013-03-04 18:30:13 -0800151 ::llvm::DenseMap<const ::llvm::Function*, IntrinsicId> intrinsic_funcs_map_;
Shih-wei Liaoe94d9b22012-05-22 09:01:24 -0700152};
153
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700154} // namespace llvm
155} // namespace art
Shih-wei Liaoe94d9b22012-05-22 09:01:24 -0700156
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700157#endif // ART_COMPILER_LLVM_INTRINSIC_HELPER_H_