| OLD | NEW |
| 1 //===- subzero/src/IceIntrinsics.cpp - Functions related to intrinsics ----===// | 1 //===- subzero/src/IceIntrinsics.cpp - Functions related to intrinsics ----===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 /// | 9 /// |
| 10 /// \file | 10 /// \file |
| 11 /// \brief Implements the Intrinsics utilities for matching and then dispatching | 11 /// \brief Implements the Intrinsics utilities for matching and then dispatching |
| 12 /// by name. | 12 /// by name. |
| 13 /// | 13 /// |
| 14 //===----------------------------------------------------------------------===// | 14 //===----------------------------------------------------------------------===// |
| 15 | 15 |
| 16 #include "IceIntrinsics.h" | 16 #include "IceIntrinsics.h" |
| 17 | 17 |
| 18 #include "IceCfg.h" | 18 #include "IceCfg.h" |
| 19 #include "IceCfgNode.h" | 19 #include "IceCfgNode.h" |
| 20 #include "IceInst.h" | 20 #include "IceInst.h" |
| 21 #include "IceLiveness.h" | 21 #include "IceLiveness.h" |
| 22 #include "IceOperand.h" | 22 #include "IceOperand.h" |
| 23 #include "IceStringPool.h" |
| 23 | 24 |
| 24 #include <utility> | 25 #include <utility> |
| 25 | 26 |
| 26 namespace Ice { | 27 namespace Ice { |
| 27 | 28 |
| 28 static_assert(sizeof(Intrinsics::IntrinsicInfo) == 4, | 29 static_assert(sizeof(Intrinsics::IntrinsicInfo) == 4, |
| 29 "Unexpected sizeof(IntrinsicInfo)"); | 30 "Unexpected sizeof(IntrinsicInfo)"); |
| 30 | 31 |
| 31 namespace { | 32 namespace { |
| 32 | 33 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 44 { \ | 45 { \ |
| 45 { \ | 46 { \ |
| 46 INTRIN(AtomicCmpxchg, SideEffects_T, ReturnsTwice_F), {Overload, \ | 47 INTRIN(AtomicCmpxchg, SideEffects_T, ReturnsTwice_F), {Overload, \ |
| 47 IceType_i32, \ | 48 IceType_i32, \ |
| 48 Overload, \ | 49 Overload, \ |
| 49 Overload, \ | 50 Overload, \ |
| 50 IceType_i32, \ | 51 IceType_i32, \ |
| 51 IceType_i32}, \ | 52 IceType_i32}, \ |
| 52 6 \ | 53 6 \ |
| 53 } \ | 54 } \ |
| 54 , "nacl.atomic.cmpxchg." NameSuffix \ | 55 , "llvm.nacl.atomic.cmpxchg." NameSuffix \ |
| 55 } | 56 } |
| 56 AtomicCmpxchgInit(IceType_i8, "i8"), | 57 AtomicCmpxchgInit(IceType_i8, "i8"), |
| 57 AtomicCmpxchgInit(IceType_i16, "i16"), | 58 AtomicCmpxchgInit(IceType_i16, "i16"), |
| 58 AtomicCmpxchgInit(IceType_i32, "i32"), | 59 AtomicCmpxchgInit(IceType_i32, "i32"), |
| 59 AtomicCmpxchgInit(IceType_i64, "i64"), | 60 AtomicCmpxchgInit(IceType_i64, "i64"), |
| 60 #undef AtomicCmpxchgInit | 61 #undef AtomicCmpxchgInit |
| 61 | 62 |
| 62 {{INTRIN(AtomicFence, SideEffects_T, ReturnsTwice_F), | 63 {{INTRIN(AtomicFence, SideEffects_T, ReturnsTwice_F), |
| 63 {IceType_void, IceType_i32}, | 64 {IceType_void, IceType_i32}, |
| 64 2}, | 65 2}, |
| 65 "nacl.atomic.fence"}, | 66 "llvm.nacl.atomic.fence"}, |
| 66 {{INTRIN(AtomicFenceAll, SideEffects_T, ReturnsTwice_F), {IceType_void}, 1}, | 67 {{INTRIN(AtomicFenceAll, SideEffects_T, ReturnsTwice_F), {IceType_void}, 1}, |
| 67 "nacl.atomic.fence.all"}, | 68 "llvm.nacl.atomic.fence.all"}, |
| 68 {{INTRIN(AtomicIsLockFree, SideEffects_F, ReturnsTwice_F), | 69 {{INTRIN(AtomicIsLockFree, SideEffects_F, ReturnsTwice_F), |
| 69 {IceType_i1, IceType_i32, IceType_i32}, | 70 {IceType_i1, IceType_i32, IceType_i32}, |
| 70 3}, | 71 3}, |
| 71 "nacl.atomic.is.lock.free"}, | 72 "llvm.nacl.atomic.is.lock.free"}, |
| 72 | 73 |
| 73 #define AtomicLoadInit(Overload, NameSuffix) \ | 74 #define AtomicLoadInit(Overload, NameSuffix) \ |
| 74 { \ | 75 { \ |
| 75 { \ | 76 { \ |
| 76 INTRIN(AtomicLoad, SideEffects_T, ReturnsTwice_F), \ | 77 INTRIN(AtomicLoad, SideEffects_T, ReturnsTwice_F), \ |
| 77 {Overload, IceType_i32, IceType_i32}, 3 \ | 78 {Overload, IceType_i32, IceType_i32}, 3 \ |
| 78 } \ | 79 } \ |
| 79 , "nacl.atomic.load." NameSuffix \ | 80 , "llvm.nacl.atomic.load." NameSuffix \ |
| 80 } | 81 } |
| 81 AtomicLoadInit(IceType_i8, "i8"), | 82 AtomicLoadInit(IceType_i8, "i8"), |
| 82 AtomicLoadInit(IceType_i16, "i16"), | 83 AtomicLoadInit(IceType_i16, "i16"), |
| 83 AtomicLoadInit(IceType_i32, "i32"), | 84 AtomicLoadInit(IceType_i32, "i32"), |
| 84 AtomicLoadInit(IceType_i64, "i64"), | 85 AtomicLoadInit(IceType_i64, "i64"), |
| 85 #undef AtomicLoadInit | 86 #undef AtomicLoadInit |
| 86 | 87 |
| 87 #define AtomicRMWInit(Overload, NameSuffix) \ | 88 #define AtomicRMWInit(Overload, NameSuffix) \ |
| 88 { \ | 89 { \ |
| 89 { \ | 90 { \ |
| 90 INTRIN(AtomicRMW, SideEffects_T, ReturnsTwice_F) \ | 91 INTRIN(AtomicRMW, SideEffects_T, ReturnsTwice_F) \ |
| 91 , {Overload, IceType_i32, IceType_i32, Overload, IceType_i32}, 5 \ | 92 , {Overload, IceType_i32, IceType_i32, Overload, IceType_i32}, 5 \ |
| 92 } \ | 93 } \ |
| 93 , "nacl.atomic.rmw." NameSuffix \ | 94 , "llvm.nacl.atomic.rmw." NameSuffix \ |
| 94 } | 95 } |
| 95 AtomicRMWInit(IceType_i8, "i8"), | 96 AtomicRMWInit(IceType_i8, "i8"), |
| 96 AtomicRMWInit(IceType_i16, "i16"), | 97 AtomicRMWInit(IceType_i16, "i16"), |
| 97 AtomicRMWInit(IceType_i32, "i32"), | 98 AtomicRMWInit(IceType_i32, "i32"), |
| 98 AtomicRMWInit(IceType_i64, "i64"), | 99 AtomicRMWInit(IceType_i64, "i64"), |
| 99 #undef AtomicRMWInit | 100 #undef AtomicRMWInit |
| 100 | 101 |
| 101 #define AtomicStoreInit(Overload, NameSuffix) \ | 102 #define AtomicStoreInit(Overload, NameSuffix) \ |
| 102 { \ | 103 { \ |
| 103 { \ | 104 { \ |
| 104 INTRIN(AtomicStore, SideEffects_T, ReturnsTwice_F) \ | 105 INTRIN(AtomicStore, SideEffects_T, ReturnsTwice_F) \ |
| 105 , {IceType_void, Overload, IceType_i32, IceType_i32}, 4 \ | 106 , {IceType_void, Overload, IceType_i32, IceType_i32}, 4 \ |
| 106 } \ | 107 } \ |
| 107 , "nacl.atomic.store." NameSuffix \ | 108 , "llvm.nacl.atomic.store." NameSuffix \ |
| 108 } | 109 } |
| 109 AtomicStoreInit(IceType_i8, "i8"), | 110 AtomicStoreInit(IceType_i8, "i8"), |
| 110 AtomicStoreInit(IceType_i16, "i16"), | 111 AtomicStoreInit(IceType_i16, "i16"), |
| 111 AtomicStoreInit(IceType_i32, "i32"), | 112 AtomicStoreInit(IceType_i32, "i32"), |
| 112 AtomicStoreInit(IceType_i64, "i64"), | 113 AtomicStoreInit(IceType_i64, "i64"), |
| 113 #undef AtomicStoreInit | 114 #undef AtomicStoreInit |
| 114 | 115 |
| 115 #define BswapInit(Overload, NameSuffix) \ | 116 #define BswapInit(Overload, NameSuffix) \ |
| 116 { \ | 117 { \ |
| 117 { \ | 118 { \ |
| 118 INTRIN(Bswap, SideEffects_F, ReturnsTwice_F) \ | 119 INTRIN(Bswap, SideEffects_F, ReturnsTwice_F) \ |
| 119 , {Overload, Overload}, 2 \ | 120 , {Overload, Overload}, 2 \ |
| 120 } \ | 121 } \ |
| 121 , "bswap." NameSuffix \ | 122 , "llvm.bswap." NameSuffix \ |
| 122 } | 123 } |
| 123 BswapInit(IceType_i16, "i16"), | 124 BswapInit(IceType_i16, "i16"), |
| 124 BswapInit(IceType_i32, "i32"), | 125 BswapInit(IceType_i32, "i32"), |
| 125 BswapInit(IceType_i64, "i64"), | 126 BswapInit(IceType_i64, "i64"), |
| 126 #undef BswapInit | 127 #undef BswapInit |
| 127 | 128 |
| 128 #define CtlzInit(Overload, NameSuffix) \ | 129 #define CtlzInit(Overload, NameSuffix) \ |
| 129 { \ | 130 { \ |
| 130 { \ | 131 { \ |
| 131 INTRIN(Ctlz, SideEffects_F, ReturnsTwice_F) \ | 132 INTRIN(Ctlz, SideEffects_F, ReturnsTwice_F) \ |
| 132 , {Overload, Overload, IceType_i1}, 3 \ | 133 , {Overload, Overload, IceType_i1}, 3 \ |
| 133 } \ | 134 } \ |
| 134 , "ctlz." NameSuffix \ | 135 , "llvm.ctlz." NameSuffix \ |
| 135 } | 136 } |
| 136 CtlzInit(IceType_i32, "i32"), | 137 CtlzInit(IceType_i32, "i32"), |
| 137 CtlzInit(IceType_i64, "i64"), | 138 CtlzInit(IceType_i64, "i64"), |
| 138 #undef CtlzInit | 139 #undef CtlzInit |
| 139 | 140 |
| 140 #define CtpopInit(Overload, NameSuffix) \ | 141 #define CtpopInit(Overload, NameSuffix) \ |
| 141 { \ | 142 { \ |
| 142 { \ | 143 { \ |
| 143 INTRIN(Ctpop, SideEffects_F, ReturnsTwice_F) \ | 144 INTRIN(Ctpop, SideEffects_F, ReturnsTwice_F) \ |
| 144 , {Overload, Overload}, 2 \ | 145 , {Overload, Overload}, 2 \ |
| 145 } \ | 146 } \ |
| 146 , "ctpop." NameSuffix \ | 147 , "llvm.ctpop." NameSuffix \ |
| 147 } | 148 } |
| 148 CtpopInit(IceType_i32, "i32"), | 149 CtpopInit(IceType_i32, "i32"), |
| 149 CtpopInit(IceType_i64, "i64"), | 150 CtpopInit(IceType_i64, "i64"), |
| 150 #undef CtpopInit | 151 #undef CtpopInit |
| 151 | 152 |
| 152 #define CttzInit(Overload, NameSuffix) \ | 153 #define CttzInit(Overload, NameSuffix) \ |
| 153 { \ | 154 { \ |
| 154 { \ | 155 { \ |
| 155 INTRIN(Cttz, SideEffects_F, ReturnsTwice_F) \ | 156 INTRIN(Cttz, SideEffects_F, ReturnsTwice_F) \ |
| 156 , {Overload, Overload, IceType_i1}, 3 \ | 157 , {Overload, Overload, IceType_i1}, 3 \ |
| 157 } \ | 158 } \ |
| 158 , "cttz." NameSuffix \ | 159 , "llvm.cttz." NameSuffix \ |
| 159 } | 160 } |
| 160 CttzInit(IceType_i32, "i32"), | 161 CttzInit(IceType_i32, "i32"), |
| 161 CttzInit(IceType_i64, "i64"), | 162 CttzInit(IceType_i64, "i64"), |
| 162 #undef CttzInit | 163 #undef CttzInit |
| 163 | 164 |
| 164 #define FabsInit(Overload, NameSuffix) \ | 165 #define FabsInit(Overload, NameSuffix) \ |
| 165 { \ | 166 { \ |
| 166 { INTRIN(Fabs, SideEffects_F, ReturnsTwice_F), {Overload, Overload}, 2 } \ | 167 { INTRIN(Fabs, SideEffects_F, ReturnsTwice_F), {Overload, Overload}, 2 } \ |
| 167 , "fabs." NameSuffix \ | 168 , "llvm.fabs." NameSuffix \ |
| 168 } | 169 } |
| 169 FabsInit(IceType_f32, "f32"), | 170 FabsInit(IceType_f32, "f32"), |
| 170 FabsInit(IceType_f64, "f64"), | 171 FabsInit(IceType_f64, "f64"), |
| 171 FabsInit(IceType_v4f32, "v4f32"), | 172 FabsInit(IceType_v4f32, "v4f32"), |
| 172 #undef FabsInit | 173 #undef FabsInit |
| 173 | 174 |
| 174 {{INTRIN(Longjmp, SideEffects_T, ReturnsTwice_F), | 175 {{INTRIN(Longjmp, SideEffects_T, ReturnsTwice_F), |
| 175 {IceType_void, IceType_i32, IceType_i32}, | 176 {IceType_void, IceType_i32, IceType_i32}, |
| 176 3}, | 177 3}, |
| 177 "nacl.longjmp"}, | 178 "llvm.nacl.longjmp"}, |
| 178 {{INTRIN(Memcpy, SideEffects_T, ReturnsTwice_F), | 179 {{INTRIN(Memcpy, SideEffects_T, ReturnsTwice_F), |
| 179 {IceType_void, IceType_i32, IceType_i32, IceType_i32, IceType_i32, | 180 {IceType_void, IceType_i32, IceType_i32, IceType_i32, IceType_i32, |
| 180 IceType_i1}, | 181 IceType_i1}, |
| 181 6}, | 182 6}, |
| 182 "memcpy.p0i8.p0i8.i32"}, | 183 "llvm.memcpy.p0i8.p0i8.i32"}, |
| 183 {{INTRIN(Memmove, SideEffects_T, ReturnsTwice_F), | 184 {{INTRIN(Memmove, SideEffects_T, ReturnsTwice_F), |
| 184 {IceType_void, IceType_i32, IceType_i32, IceType_i32, IceType_i32, | 185 {IceType_void, IceType_i32, IceType_i32, IceType_i32, IceType_i32, |
| 185 IceType_i1}, | 186 IceType_i1}, |
| 186 6}, | 187 6}, |
| 187 "memmove.p0i8.p0i8.i32"}, | 188 "llvm.memmove.p0i8.p0i8.i32"}, |
| 188 {{INTRIN(Memset, SideEffects_T, ReturnsTwice_F), | 189 {{INTRIN(Memset, SideEffects_T, ReturnsTwice_F), |
| 189 {IceType_void, IceType_i32, IceType_i8, IceType_i32, IceType_i32, | 190 {IceType_void, IceType_i32, IceType_i8, IceType_i32, IceType_i32, |
| 190 IceType_i1}, | 191 IceType_i1}, |
| 191 6}, | 192 6}, |
| 192 "memset.p0i8.i32"}, | 193 "llvm.memset.p0i8.i32"}, |
| 193 {{INTRIN(NaClReadTP, SideEffects_F, ReturnsTwice_F), {IceType_i32}, 1}, | 194 {{INTRIN(NaClReadTP, SideEffects_F, ReturnsTwice_F), {IceType_i32}, 1}, |
| 194 "nacl.read.tp"}, | 195 "llvm.nacl.read.tp"}, |
| 195 {{INTRIN(Setjmp, SideEffects_T, ReturnsTwice_T), | 196 {{INTRIN(Setjmp, SideEffects_T, ReturnsTwice_T), |
| 196 {IceType_i32, IceType_i32}, | 197 {IceType_i32, IceType_i32}, |
| 197 2}, | 198 2}, |
| 198 "nacl.setjmp"}, | 199 "llvm.nacl.setjmp"}, |
| 199 | 200 |
| 200 #define SqrtInit(Overload, NameSuffix) \ | 201 #define SqrtInit(Overload, NameSuffix) \ |
| 201 { \ | 202 { \ |
| 202 { INTRIN(Sqrt, SideEffects_F, ReturnsTwice_F), {Overload, Overload}, 2 } \ | 203 { INTRIN(Sqrt, SideEffects_F, ReturnsTwice_F), {Overload, Overload}, 2 } \ |
| 203 , "sqrt." NameSuffix \ | 204 , "llvm.sqrt." NameSuffix \ |
| 204 } | 205 } |
| 205 SqrtInit(IceType_f32, "f32"), | 206 SqrtInit(IceType_f32, "f32"), |
| 206 SqrtInit(IceType_f64, "f64"), | 207 SqrtInit(IceType_f64, "f64"), |
| 207 #undef SqrtInit | 208 #undef SqrtInit |
| 208 | 209 |
| 209 {{INTRIN(Stacksave, SideEffects_T, ReturnsTwice_F), {IceType_i32}, 1}, | 210 {{INTRIN(Stacksave, SideEffects_T, ReturnsTwice_F), {IceType_i32}, 1}, |
| 210 "stacksave"}, | 211 "llvm.stacksave"}, |
| 211 {{INTRIN(Stackrestore, SideEffects_T, ReturnsTwice_F), | 212 {{INTRIN(Stackrestore, SideEffects_T, ReturnsTwice_F), |
| 212 {IceType_void, IceType_i32}, | 213 {IceType_void, IceType_i32}, |
| 213 2}, | 214 2}, |
| 214 "stackrestore"}, | 215 "llvm.stackrestore"}, |
| 215 {{INTRIN(Trap, SideEffects_T, ReturnsTwice_F), {IceType_void}, 1}, "trap"}}; | 216 {{INTRIN(Trap, SideEffects_T, ReturnsTwice_F), {IceType_void}, 1}, |
| 217 "llvm.trap"}}; |
| 216 const size_t IceIntrinsicsTableSize = llvm::array_lengthof(IceIntrinsicsTable); | 218 const size_t IceIntrinsicsTableSize = llvm::array_lengthof(IceIntrinsicsTable); |
| 217 | 219 |
| 218 #undef INTRIN | 220 #undef INTRIN |
| 219 | 221 |
| 220 } // end of anonymous namespace | 222 } // end of anonymous namespace |
| 221 | 223 |
| 222 Intrinsics::Intrinsics() { | 224 Intrinsics::Intrinsics(GlobalContext *Ctx) { |
| 223 for (size_t I = 0; I < IceIntrinsicsTableSize; ++I) { | 225 for (size_t I = 0; I < IceIntrinsicsTableSize; ++I) { |
| 224 const struct IceIntrinsicsEntry_ &Entry = IceIntrinsicsTable[I]; | 226 const struct IceIntrinsicsEntry_ &Entry = IceIntrinsicsTable[I]; |
| 225 assert(Entry.Info.NumTypes <= kMaxIntrinsicParameters); | 227 assert(Entry.Info.NumTypes <= kMaxIntrinsicParameters); |
| 226 Map.insert(std::make_pair(IceString(Entry.IntrinsicName), Entry.Info)); | 228 Map.insert( |
| 229 std::make_pair(Ctx->getGlobalString(Entry.IntrinsicName), Entry.Info)); |
| 227 } | 230 } |
| 228 } | 231 } |
| 229 | 232 |
| 230 Intrinsics::~Intrinsics() = default; | 233 const Intrinsics::FullIntrinsicInfo *Intrinsics::find(GlobalString Name, |
| 231 | |
| 232 const Intrinsics::FullIntrinsicInfo *Intrinsics::find(const IceString &Name, | |
| 233 bool &Error) const { | 234 bool &Error) const { |
| 234 static const char LLVMPrefix[] = "llvm."; | 235 static constexpr char LLVMPrefix[] = "llvm."; |
| 235 const size_t LLVMPrefixLen = strlen(LLVMPrefix); | 236 constexpr size_t LLVMPrefixLen = llvm::array_lengthof(LLVMPrefix) - 1; |
| 236 Error = false; | 237 Error = false; |
| 237 if (Name.substr(0, LLVMPrefixLen) != LLVMPrefix) | 238 if (Name.toString().substr(0, LLVMPrefixLen) != LLVMPrefix) |
| 238 return nullptr; | 239 return nullptr; |
| 239 const IceString NameSuffix = Name.substr(LLVMPrefixLen); | 240 auto Iter = Map.find(Name); |
| 240 auto it = Map.find(NameSuffix); | 241 if (Iter == Map.end()) { |
| 241 if (it == Map.end()) { | |
| 242 Error = true; | 242 Error = true; |
| 243 return nullptr; | 243 return nullptr; |
| 244 } | 244 } |
| 245 return &it->second; | 245 return &Iter->second; |
| 246 } | 246 } |
| 247 | 247 |
| 248 namespace { | 248 namespace { |
| 249 | 249 |
| 250 // Returns whether PNaCl allows the given memory ordering in general. | 250 // Returns whether PNaCl allows the given memory ordering in general. |
| 251 bool isMemoryOrderValidPNaCl(uint64_t Order) { | 251 bool isMemoryOrderValidPNaCl(uint64_t Order) { |
| 252 switch (Order) { | 252 switch (Order) { |
| 253 case Intrinsics::MemoryOrderAcquire: | 253 case Intrinsics::MemoryOrderAcquire: |
| 254 case Intrinsics::MemoryOrderRelease: | 254 case Intrinsics::MemoryOrderRelease: |
| 255 case Intrinsics::MemoryOrderAcquireRelease: | 255 case Intrinsics::MemoryOrderAcquireRelease: |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 return Intrinsics::IsValidCall; | 337 return Intrinsics::IsValidCall; |
| 338 } | 338 } |
| 339 | 339 |
| 340 Type Intrinsics::FullIntrinsicInfo::getArgType(SizeT Index) const { | 340 Type Intrinsics::FullIntrinsicInfo::getArgType(SizeT Index) const { |
| 341 assert(NumTypes > 1); | 341 assert(NumTypes > 1); |
| 342 assert(Index + 1 < NumTypes); | 342 assert(Index + 1 < NumTypes); |
| 343 return Signature[Index + 1]; | 343 return Signature[Index + 1]; |
| 344 } | 344 } |
| 345 | 345 |
| 346 } // end of namespace Ice | 346 } // end of namespace Ice |
| OLD | NEW |