Chromium Code Reviews| 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 // This file implements the Intrinsics utilities for matching and | 10 // This file implements the Intrinsics utilities for matching and |
| 11 // then dispatching by name. | 11 // then dispatching by name. |
| 12 // | 12 // |
| 13 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
| 14 | 14 |
| 15 #include "IceCfg.h" | 15 #include "IceCfg.h" |
| 16 #include "IceCfgNode.h" | 16 #include "IceCfgNode.h" |
| 17 #include "IceIntrinsics.h" | 17 #include "IceIntrinsics.h" |
| 18 #include "IceLiveness.h" | 18 #include "IceLiveness.h" |
| 19 #include "IceOperand.h" | 19 #include "IceOperand.h" |
| 20 | 20 |
| 21 #include <utility> | 21 #include <utility> |
| 22 | 22 |
| 23 namespace Ice { | 23 namespace Ice { |
| 24 | 24 |
| 25 namespace { | 25 namespace { |
| 26 | 26 |
| 27 // Build list of intrinsics with their attributes and expected prototypes. | |
| 28 // List is sorted alphabetically. | |
| 27 const struct IceIntrinsicsEntry_ { | 29 const struct IceIntrinsicsEntry_ { |
| 28 Intrinsics::FullIntrinsicInfo Info; | 30 Intrinsics::FullIntrinsicInfo Info; |
| 29 const char *IntrinsicName; | 31 const char *IntrinsicName; |
| 30 } IceIntrinsicsTable[] = { | 32 } IceIntrinsicsTable[] = { |
| 33 | |
| 31 #define AtomicCmpxchgInit(Overload, NameSuffix) \ | 34 #define AtomicCmpxchgInit(Overload, NameSuffix) \ |
| 32 { \ | 35 { \ |
| 33 { \ | 36 { \ |
| 34 { Intrinsics::AtomicCmpxchg, true }, \ | 37 { Intrinsics::AtomicCmpxchg, true, false }, \ |
|
Jim Stichnoth
2014/09/11 20:12:05
Maybe this CL isn't the right place for this, but
jvoung (off chromium)
2014/09/11 21:57:18
Nice! I was worried about losing track of the true
Jim Stichnoth
2014/09/11 22:26:26
Oh, right. I forgot to relay JF's other suggestio
jvoung (off chromium)
2014/09/11 22:58:57
I thought about using a class + ctor, but doesn't
| |
| 35 { Overload, IceType_i32, Overload, Overload, IceType_i32, IceType_i32 }, \ | 38 { Overload, IceType_i32, Overload, Overload, IceType_i32, IceType_i32 }, \ |
| 36 6 \ | 39 6 \ |
| 37 } \ | 40 } \ |
| 38 , "nacl.atomic.cmpxchg." NameSuffix \ | 41 , "nacl.atomic.cmpxchg." NameSuffix \ |
| 39 } | 42 } |
| 40 AtomicCmpxchgInit(IceType_i8, "i8"), | 43 AtomicCmpxchgInit(IceType_i8, "i8"), |
| 41 AtomicCmpxchgInit(IceType_i16, "i16"), | 44 AtomicCmpxchgInit(IceType_i16, "i16"), |
| 42 AtomicCmpxchgInit(IceType_i32, "i32"), | 45 AtomicCmpxchgInit(IceType_i32, "i32"), |
| 43 AtomicCmpxchgInit(IceType_i64, "i64"), | 46 AtomicCmpxchgInit(IceType_i64, "i64"), |
| 44 #undef AtomicCmpxchgInit | 47 #undef AtomicCmpxchgInit |
| 45 { { { Intrinsics::AtomicFence, true }, { IceType_void, IceType_i32 }, 2 }, | 48 |
| 49 { { { Intrinsics::AtomicFence, true, false }, { IceType_void, IceType_i32 }, | |
| 50 2}, | |
| 46 "nacl.atomic.fence" }, | 51 "nacl.atomic.fence" }, |
| 47 { { { Intrinsics::AtomicFenceAll, true }, { IceType_void }, 1 }, | 52 { { { Intrinsics::AtomicFenceAll, true, false }, { IceType_void }, 1 }, |
| 48 "nacl.atomic.fence.all" }, | 53 "nacl.atomic.fence.all" }, |
| 49 { { { Intrinsics::AtomicIsLockFree, false }, | 54 { { { Intrinsics::AtomicIsLockFree, false, false }, |
| 50 { IceType_i1, IceType_i32, IceType_i32 }, 3 }, | 55 { IceType_i1, IceType_i32, IceType_i32 }, 3 }, |
| 51 "nacl.atomic.is.lock.free" }, | 56 "nacl.atomic.is.lock.free" }, |
| 52 | 57 |
| 53 #define AtomicLoadInit(Overload, NameSuffix) \ | 58 #define AtomicLoadInit(Overload, NameSuffix) \ |
| 54 { \ | 59 { \ |
| 55 { \ | 60 { \ |
| 56 { Intrinsics::AtomicLoad, true } \ | 61 { Intrinsics::AtomicLoad, true, false } \ |
| 57 , { Overload, IceType_i32, IceType_i32 }, 3 \ | 62 , { Overload, IceType_i32, IceType_i32 }, 3 \ |
| 58 } \ | 63 } \ |
| 59 , "nacl.atomic.load." NameSuffix \ | 64 , "nacl.atomic.load." NameSuffix \ |
| 60 } | 65 } |
| 61 AtomicLoadInit(IceType_i8, "i8"), | 66 AtomicLoadInit(IceType_i8, "i8"), |
| 62 AtomicLoadInit(IceType_i16, "i16"), | 67 AtomicLoadInit(IceType_i16, "i16"), |
| 63 AtomicLoadInit(IceType_i32, "i32"), | 68 AtomicLoadInit(IceType_i32, "i32"), |
| 64 AtomicLoadInit(IceType_i64, "i64"), | 69 AtomicLoadInit(IceType_i64, "i64"), |
| 65 #undef AtomicLoadInit | 70 #undef AtomicLoadInit |
| 66 | 71 |
| 67 #define AtomicRMWInit(Overload, NameSuffix) \ | 72 #define AtomicRMWInit(Overload, NameSuffix) \ |
| 68 { \ | 73 { \ |
| 69 { \ | 74 { \ |
| 70 { Intrinsics::AtomicRMW, true } \ | 75 { Intrinsics::AtomicRMW, true, false } \ |
| 71 , { Overload, IceType_i32, IceType_i32, Overload, IceType_i32 }, 5 \ | 76 , { Overload, IceType_i32, IceType_i32, Overload, IceType_i32 }, 5 \ |
| 72 } \ | 77 } \ |
| 73 , "nacl.atomic.rmw." NameSuffix \ | 78 , "nacl.atomic.rmw." NameSuffix \ |
| 74 } | 79 } |
| 75 AtomicRMWInit(IceType_i8, "i8"), | 80 AtomicRMWInit(IceType_i8, "i8"), |
| 76 AtomicRMWInit(IceType_i16, "i16"), | 81 AtomicRMWInit(IceType_i16, "i16"), |
| 77 AtomicRMWInit(IceType_i32, "i32"), | 82 AtomicRMWInit(IceType_i32, "i32"), |
| 78 AtomicRMWInit(IceType_i64, "i64"), | 83 AtomicRMWInit(IceType_i64, "i64"), |
| 79 #undef AtomicRMWInit | 84 #undef AtomicRMWInit |
| 80 | 85 |
| 81 #define AtomicStoreInit(Overload, NameSuffix) \ | 86 #define AtomicStoreInit(Overload, NameSuffix) \ |
| 82 { \ | 87 { \ |
| 83 { \ | 88 { \ |
| 84 { Intrinsics::AtomicStore, true } \ | 89 { Intrinsics::AtomicStore, true, false } \ |
| 85 , { IceType_void, Overload, IceType_i32, IceType_i32 }, 4 \ | 90 , { IceType_void, Overload, IceType_i32, IceType_i32 }, 4 \ |
| 86 } \ | 91 } \ |
| 87 , "nacl.atomic.store." NameSuffix \ | 92 , "nacl.atomic.store." NameSuffix \ |
| 88 } | 93 } |
| 89 AtomicStoreInit(IceType_i8, "i8"), | 94 AtomicStoreInit(IceType_i8, "i8"), |
| 90 AtomicStoreInit(IceType_i16, "i16"), | 95 AtomicStoreInit(IceType_i16, "i16"), |
| 91 AtomicStoreInit(IceType_i32, "i32"), | 96 AtomicStoreInit(IceType_i32, "i32"), |
| 92 AtomicStoreInit(IceType_i64, "i64"), | 97 AtomicStoreInit(IceType_i64, "i64"), |
| 93 #undef AtomicStoreInit | 98 #undef AtomicStoreInit |
| 94 | 99 |
| 95 #define BswapInit(Overload, NameSuffix) \ | 100 #define BswapInit(Overload, NameSuffix) \ |
| 96 { \ | 101 { \ |
| 97 { \ | 102 { \ |
| 98 { Intrinsics::Bswap, false } \ | 103 { Intrinsics::Bswap, false, false } \ |
| 99 , { Overload, Overload }, 2 \ | 104 , { Overload, Overload }, 2 \ |
| 100 } \ | 105 } \ |
| 101 , "bswap." NameSuffix \ | 106 , "bswap." NameSuffix \ |
| 102 } | 107 } |
| 103 BswapInit(IceType_i16, "i16"), | 108 BswapInit(IceType_i16, "i16"), |
| 104 BswapInit(IceType_i32, "i32"), | 109 BswapInit(IceType_i32, "i32"), |
| 105 BswapInit(IceType_i64, "i64"), | 110 BswapInit(IceType_i64, "i64"), |
| 106 #undef BswapInit | 111 #undef BswapInit |
| 107 | 112 |
| 108 #define CtlzInit(Overload, NameSuffix) \ | 113 #define CtlzInit(Overload, NameSuffix) \ |
| 109 { \ | 114 { \ |
| 110 { \ | 115 { \ |
| 111 { Intrinsics::Ctlz, false } \ | 116 { Intrinsics::Ctlz, false, false } \ |
| 112 , { Overload, Overload, IceType_i1 }, 3 \ | 117 , { Overload, Overload, IceType_i1 }, 3 \ |
| 113 } \ | 118 } \ |
| 114 , "ctlz." NameSuffix \ | 119 , "ctlz." NameSuffix \ |
| 115 } | 120 } |
| 116 CtlzInit(IceType_i32, "i32"), | 121 CtlzInit(IceType_i32, "i32"), |
| 117 CtlzInit(IceType_i64, "i64"), | 122 CtlzInit(IceType_i64, "i64"), |
| 118 #undef CtlzInit | 123 #undef CtlzInit |
| 119 | 124 |
| 120 #define CtpopInit(Overload, NameSuffix) \ | 125 #define CtpopInit(Overload, NameSuffix) \ |
| 121 { \ | 126 { \ |
| 122 { \ | 127 { \ |
| 123 { Intrinsics::Ctpop, false } \ | 128 { Intrinsics::Ctpop, false, false } \ |
| 124 , { Overload, Overload }, 2 \ | 129 , { Overload, Overload }, 2 \ |
| 125 } \ | 130 } \ |
| 126 , "ctpop." NameSuffix \ | 131 , "ctpop." NameSuffix \ |
| 127 } | 132 } |
| 128 CtpopInit(IceType_i32, "i32"), | 133 CtpopInit(IceType_i32, "i32"), |
| 129 CtpopInit(IceType_i64, "i64"), | 134 CtpopInit(IceType_i64, "i64"), |
| 130 #undef CtpopInit | 135 #undef CtpopInit |
| 131 | 136 |
| 132 #define CttzInit(Overload, NameSuffix) \ | 137 #define CttzInit(Overload, NameSuffix) \ |
| 133 { \ | 138 { \ |
| 134 { \ | 139 { \ |
| 135 { Intrinsics::Cttz, false } \ | 140 { Intrinsics::Cttz, false, false } \ |
| 136 , { Overload, Overload, IceType_i1 }, 3 \ | 141 , { Overload, Overload, IceType_i1 }, 3 \ |
| 137 } \ | 142 } \ |
| 138 , "cttz." NameSuffix \ | 143 , "cttz." NameSuffix \ |
| 139 } | 144 } |
| 140 CttzInit(IceType_i32, "i32"), | 145 CttzInit(IceType_i32, "i32"), |
| 141 CttzInit(IceType_i64, "i64"), | 146 CttzInit(IceType_i64, "i64"), |
| 142 #undef CttzInit | 147 #undef CttzInit |
| 143 { { { Intrinsics::Longjmp, true }, | 148 |
| 149 { { { Intrinsics::Longjmp, true, false }, | |
| 144 { IceType_void, IceType_i32, IceType_i32 }, 3 }, | 150 { IceType_void, IceType_i32, IceType_i32 }, 3 }, |
| 145 "nacl.longjmp" }, | 151 "nacl.longjmp" }, |
| 146 { { { Intrinsics::Memcpy, true }, { IceType_void, IceType_i32, IceType_i32, | 152 { { { Intrinsics::Memcpy, true, false }, |
| 147 IceType_i32, IceType_i32, IceType_i1 }, | 153 { IceType_void, IceType_i32, IceType_i32, IceType_i32, IceType_i32, |
| 154 IceType_i1}, | |
| 148 6 }, | 155 6 }, |
| 149 "memcpy.p0i8.p0i8.i32" }, | 156 "memcpy.p0i8.p0i8.i32" }, |
| 150 { { { Intrinsics::Memmove, true }, | 157 { { { Intrinsics::Memmove, true, false }, |
| 151 { IceType_void, IceType_i32, IceType_i32, | 158 { IceType_void, IceType_i32, IceType_i32, IceType_i32, IceType_i32, |
| 152 IceType_i32, IceType_i32, IceType_i1 }, | 159 IceType_i1 }, |
| 153 6 }, | 160 6 }, |
| 154 "memmove.p0i8.p0i8.i32" }, | 161 "memmove.p0i8.p0i8.i32" }, |
| 155 { { { Intrinsics::Memset, true }, { IceType_void, IceType_i32, IceType_i8, | 162 { { { Intrinsics::Memset, true, false }, |
| 156 IceType_i32, IceType_i32, IceType_i1 }, | 163 { IceType_void, IceType_i32, IceType_i8, IceType_i32, IceType_i32, |
| 164 IceType_i1 }, | |
| 157 6 }, | 165 6 }, |
| 158 "memset.p0i8.i32" }, | 166 "memset.p0i8.i32" }, |
| 159 { { { Intrinsics::NaClReadTP, false }, { IceType_i32 }, 1 }, | 167 { { { Intrinsics::NaClReadTP, false, false }, { IceType_i32 }, 1 }, |
| 160 "nacl.read.tp" }, | 168 "nacl.read.tp" }, |
| 161 { { { Intrinsics::Setjmp, true }, { IceType_i32, IceType_i32 }, 2 }, | 169 { { { Intrinsics::Setjmp, true, true }, { IceType_i32, IceType_i32 }, 2 }, |
| 162 "nacl.setjmp" }, | 170 "nacl.setjmp" }, |
| 163 | 171 |
| 164 #define SqrtInit(Overload, NameSuffix) \ | 172 #define SqrtInit(Overload, NameSuffix) \ |
| 165 { \ | 173 { \ |
| 166 { \ | 174 { \ |
| 167 { Intrinsics::Sqrt, false } \ | 175 { Intrinsics::Sqrt, false, false } \ |
| 168 , { Overload, Overload }, 2 \ | 176 , { Overload, Overload }, 2 \ |
| 169 } \ | 177 } \ |
| 170 , "sqrt." NameSuffix \ | 178 , "sqrt." NameSuffix \ |
| 171 } | 179 } |
| 172 SqrtInit(IceType_f32, "f32"), | 180 SqrtInit(IceType_f32, "f32"), |
| 173 SqrtInit(IceType_f64, "f64"), | 181 SqrtInit(IceType_f64, "f64"), |
| 174 #undef SqrtInit | 182 #undef SqrtInit |
| 175 { { { Intrinsics::Stacksave, true }, { IceType_i32 }, 1 }, "stacksave" }, | 183 |
| 176 { { { Intrinsics::Stackrestore, true }, { IceType_void, IceType_i32 }, 2 }, | 184 { { { Intrinsics::Stacksave, true, false }, { IceType_i32 }, 1 }, |
| 185 "stacksave" }, | |
| 186 { { { Intrinsics::Stackrestore, true, false }, | |
| 187 { IceType_void, IceType_i32 }, | |
| 188 2 }, | |
| 177 "stackrestore" }, | 189 "stackrestore" }, |
| 178 { { { Intrinsics::Trap, true }, { IceType_void }, 1 }, "trap" } | 190 { { { Intrinsics::Trap, true, false }, { IceType_void }, 1 }, "trap" } |
| 179 }; | 191 }; |
| 180 const size_t IceIntrinsicsTableSize = llvm::array_lengthof(IceIntrinsicsTable); | 192 const size_t IceIntrinsicsTableSize = llvm::array_lengthof(IceIntrinsicsTable); |
| 181 | 193 |
| 182 } // end of anonymous namespace | 194 } // end of anonymous namespace |
| 183 | 195 |
| 184 Intrinsics::Intrinsics() { | 196 Intrinsics::Intrinsics() { |
| 185 for (size_t I = 0; I < IceIntrinsicsTableSize; ++I) { | 197 for (size_t I = 0; I < IceIntrinsicsTableSize; ++I) { |
| 186 const struct IceIntrinsicsEntry_ &Entry = IceIntrinsicsTable[I]; | 198 const struct IceIntrinsicsEntry_ &Entry = IceIntrinsicsTable[I]; |
| 187 assert(Entry.Info.NumTypes <= kMaxIntrinsicParameters); | 199 assert(Entry.Info.NumTypes <= kMaxIntrinsicParameters); |
| 188 map.insert(std::make_pair(IceString(Entry.IntrinsicName), Entry.Info)); | 200 map.insert(std::make_pair(IceString(Entry.IntrinsicName), Entry.Info)); |
| 189 } | 201 } |
| 190 } | 202 } |
| 191 | 203 |
| 192 Intrinsics::~Intrinsics() {} | 204 Intrinsics::~Intrinsics() {} |
| 193 | 205 |
| 194 const Intrinsics::FullIntrinsicInfo * | 206 const Intrinsics::FullIntrinsicInfo * |
| 195 Intrinsics::find(const IceString &Name) const { | 207 Intrinsics::find(const IceString &Name) const { |
| 196 IntrinsicMap::const_iterator it = map.find(Name); | 208 IntrinsicMap::const_iterator it = map.find(Name); |
| 197 if (it == map.end()) | 209 if (it == map.end()) |
| 198 return NULL; | 210 return NULL; |
| 199 return &it->second; | 211 return &it->second; |
| 200 } | 212 } |
| 201 | 213 |
| 202 bool Intrinsics::VerifyMemoryOrder(uint64_t Order) { | 214 bool Intrinsics::VerifyMemoryOrder(uint64_t Order) { |
| 203 // There is only one memory ordering for atomics allowed right now. | 215 // There is only one memory ordering for atomics allowed right now. |
| 204 return Order == Intrinsics::MemoryOrderSequentiallyConsistent; | 216 return Order == Intrinsics::MemoryOrderSequentiallyConsistent; |
| 205 } | 217 } |
| 206 | 218 |
| 207 } // end of namespace Ice | 219 } // end of namespace Ice |
| OLD | NEW |