OLD | NEW |
1 //===- PNaClABIVerifyModule.cpp - Verify PNaCl ABI rules ------------------===// | 1 //===- PNaClABIVerifyModule.cpp - Verify PNaCl ABI rules ------------------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
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 // Verify module-level PNaCl ABI requirements (specifically those that do not | 10 // Verify module-level PNaCl ABI requirements (specifically those that do not |
11 // require looking at the function bodies) | 11 // require looking at the function bodies) |
12 // | 12 // |
13 // | 13 // |
14 //===----------------------------------------------------------------------===// | 14 //===----------------------------------------------------------------------===// |
15 | 15 |
16 #include "llvm/Pass.h" | 16 #include "llvm/ADT/STLExtras.h" |
17 #include "llvm/ADT/StringMap.h" | 17 #include "llvm/ADT/StringMap.h" |
18 #include "llvm/ADT/Twine.h" | 18 #include "llvm/ADT/Twine.h" |
19 #include "llvm/Analysis/NaCl.h" | 19 #include "llvm/Analysis/NaCl.h" |
20 #include "llvm/IR/Constants.h" | 20 #include "llvm/IR/Constants.h" |
21 #include "llvm/IR/DerivedTypes.h" | 21 #include "llvm/IR/DerivedTypes.h" |
| 22 #include "llvm/IR/Instructions.h" |
22 #include "llvm/IR/Intrinsics.h" | 23 #include "llvm/IR/Intrinsics.h" |
23 #include "llvm/IR/Module.h" | 24 #include "llvm/IR/Module.h" |
| 25 #include "llvm/Pass.h" |
24 #include "llvm/Support/Debug.h" | 26 #include "llvm/Support/Debug.h" |
25 #include "llvm/Support/raw_ostream.h" | 27 #include "llvm/Support/raw_ostream.h" |
26 | 28 |
27 #include "PNaClABITypeChecker.h" | 29 #include "PNaClABITypeChecker.h" |
28 using namespace llvm; | 30 using namespace llvm; |
29 | 31 |
30 namespace llvm { | 32 namespace llvm { |
31 cl::opt<bool> | 33 cl::opt<bool> |
32 PNaClABIAllowDebugMetadata("pnaclabi-allow-debug-metadata", | 34 PNaClABIAllowDebugMetadata("pnaclabi-allow-debug-metadata", |
33 cl::desc("Allow debug metadata during PNaCl ABI verification."), | 35 cl::desc("Allow debug metadata during PNaCl ABI verification."), |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 // definitions, but that should be done by user-toolchain | 168 // definitions, but that should be done by user-toolchain |
167 // optimization passes, not by the PNaCl translator. | 169 // optimization passes, not by the PNaCl translator. |
168 if (GV->hasUnnamedAddr()) { | 170 if (GV->hasUnnamedAddr()) { |
169 Reporter->addError() << GVTypeName << GV->getName() | 171 Reporter->addError() << GVTypeName << GV->getName() |
170 << " has disallowed \"unnamed_addr\" attribute\n"; | 172 << " has disallowed \"unnamed_addr\" attribute\n"; |
171 } | 173 } |
172 } | 174 } |
173 | 175 |
174 AllowedIntrinsics::AllowedIntrinsics(LLVMContext *Context) : Context(Context) { | 176 AllowedIntrinsics::AllowedIntrinsics(LLVMContext *Context) : Context(Context) { |
175 Type *I8Ptr = Type::getInt8PtrTy(*Context); | 177 Type *I8Ptr = Type::getInt8PtrTy(*Context); |
| 178 Type *I8 = Type::getInt8Ty(*Context); |
176 Type *I16 = Type::getInt16Ty(*Context); | 179 Type *I16 = Type::getInt16Ty(*Context); |
177 Type *I32 = Type::getInt32Ty(*Context); | 180 Type *I32 = Type::getInt32Ty(*Context); |
178 Type *I64 = Type::getInt64Ty(*Context); | 181 Type *I64 = Type::getInt64Ty(*Context); |
179 Type *Float = Type::getFloatTy(*Context); | 182 Type *Float = Type::getFloatTy(*Context); |
180 Type *Double = Type::getDoubleTy(*Context); | 183 Type *Double = Type::getDoubleTy(*Context); |
181 | 184 |
182 // We accept bswap for a limited set of types (i16, i32, i64). The | 185 // We accept bswap for a limited set of types (i16, i32, i64). The |
183 // various backends are able to generate instructions to implement | 186 // various backends are able to generate instructions to implement |
184 // the intrinsic. Also, i16 and i64 are easy to implement as along | 187 // the intrinsic. Also, i16 and i64 are easy to implement as along |
185 // as there is a way to do i32. | 188 // as there is a way to do i32. |
(...skipping 10 matching lines...) Expand all Loading... |
196 addIntrinsic(Intrinsic::ctpop, I64); | 199 addIntrinsic(Intrinsic::ctpop, I64); |
197 | 200 |
198 addIntrinsic(Intrinsic::nacl_read_tp); | 201 addIntrinsic(Intrinsic::nacl_read_tp); |
199 addIntrinsic(Intrinsic::nacl_longjmp); | 202 addIntrinsic(Intrinsic::nacl_longjmp); |
200 addIntrinsic(Intrinsic::nacl_setjmp); | 203 addIntrinsic(Intrinsic::nacl_setjmp); |
201 | 204 |
202 // For native sqrt instructions. Must guarantee when x < -0.0, sqrt(x) = NaN. | 205 // For native sqrt instructions. Must guarantee when x < -0.0, sqrt(x) = NaN. |
203 addIntrinsic(Intrinsic::sqrt, Float); | 206 addIntrinsic(Intrinsic::sqrt, Float); |
204 addIntrinsic(Intrinsic::sqrt, Double); | 207 addIntrinsic(Intrinsic::sqrt, Double); |
205 | 208 |
| 209 Type *AtomicTypes[] = { I8, I16, I32, I64 }; |
| 210 for (size_t T = 0, E = array_lengthof(AtomicTypes); T != E; ++T) { |
| 211 addIntrinsic(Intrinsic::nacl_atomic_load, AtomicTypes[T]); |
| 212 addIntrinsic(Intrinsic::nacl_atomic_store, AtomicTypes[T]); |
| 213 addIntrinsic(Intrinsic::nacl_atomic_rmw, AtomicTypes[T]); |
| 214 addIntrinsic(Intrinsic::nacl_atomic_cmpxchg, AtomicTypes[T]); |
| 215 } |
| 216 addIntrinsic(Intrinsic::nacl_atomic_fence); |
| 217 |
206 // Stack save and restore are used to support C99 VLAs. | 218 // Stack save and restore are used to support C99 VLAs. |
207 addIntrinsic(Intrinsic::stacksave); | 219 addIntrinsic(Intrinsic::stacksave); |
208 addIntrinsic(Intrinsic::stackrestore); | 220 addIntrinsic(Intrinsic::stackrestore); |
209 | 221 |
210 addIntrinsic(Intrinsic::trap); | 222 addIntrinsic(Intrinsic::trap); |
211 | 223 |
212 // We only allow the variants of memcpy/memmove/memset with an i32 | 224 // We only allow the variants of memcpy/memmove/memset with an i32 |
213 // "len" argument, not an i64 argument. | 225 // "len" argument, not an i64 argument. |
214 Type *MemcpyTypes[] = { I8Ptr, I8Ptr, I32 }; | 226 Type *MemcpyTypes[] = { I8Ptr, I8Ptr, I32 }; |
215 addIntrinsic(Intrinsic::memcpy, MemcpyTypes); | 227 addIntrinsic(Intrinsic::memcpy, MemcpyTypes); |
216 addIntrinsic(Intrinsic::memmove, MemcpyTypes); | 228 addIntrinsic(Intrinsic::memmove, MemcpyTypes); |
217 Type *MemsetTypes[] = { I8Ptr, I32 }; | 229 Type *MemsetTypes[] = { I8Ptr, I32 }; |
218 addIntrinsic(Intrinsic::memset, MemsetTypes); | 230 addIntrinsic(Intrinsic::memset, MemsetTypes); |
219 } | 231 } |
220 | 232 |
221 bool AllowedIntrinsics::isAllowed(const Function *Func) { | 233 bool AllowedIntrinsics::isAllowed(const Function *Func) { |
222 // Keep 3 categories of intrinsics for now. | 234 // Keep 3 categories of intrinsics for now. |
223 // (1) Allowed always, provided the exact name and type match. | 235 // (1) Allowed always, provided the exact name and type match. |
224 // (2) Never allowed | 236 // (2) Never allowed. |
225 // (3) "Dev" intrinsics, which may or may not be allowed. | 237 // (3) "Dev" intrinsics, which may or may not be allowed. |
226 // "Dev" intrinsics are controlled by the PNaClABIAllowDevIntrinsics flag. | 238 // "Dev" intrinsics are controlled by the PNaClABIAllowDevIntrinsics flag. |
227 // Please keep these sorted or grouped in a sensible way, within | 239 // Please keep these sorted or grouped in a sensible way, within |
228 // each category. | 240 // each category. |
229 | 241 |
230 // (1) Allowed always, provided the exact name and type match. | 242 // (1) Allowed always, provided the exact name and type match. |
231 if (Mapping.count(Func->getName()) == 1) | 243 if (Mapping.count(Func->getName()) == 1) |
232 return Func->getFunctionType() == Mapping[Func->getName()]; | 244 return Func->getFunctionType() == Mapping[Func->getName()]; |
233 | 245 |
234 switch (Func->getIntrinsicID()) { | 246 switch (Func->getIntrinsicID()) { |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
507 } | 519 } |
508 | 520 |
509 char PNaClABIVerifyModule::ID = 0; | 521 char PNaClABIVerifyModule::ID = 0; |
510 INITIALIZE_PASS(PNaClABIVerifyModule, "verify-pnaclabi-module", | 522 INITIALIZE_PASS(PNaClABIVerifyModule, "verify-pnaclabi-module", |
511 "Verify module for PNaCl", false, true) | 523 "Verify module for PNaCl", false, true) |
512 | 524 |
513 ModulePass *llvm::createPNaClABIVerifyModulePass( | 525 ModulePass *llvm::createPNaClABIVerifyModulePass( |
514 PNaClABIErrorReporter *Reporter, bool StreamingMode) { | 526 PNaClABIErrorReporter *Reporter, bool StreamingMode) { |
515 return new PNaClABIVerifyModule(Reporter, StreamingMode); | 527 return new PNaClABIVerifyModule(Reporter, StreamingMode); |
516 } | 528 } |
OLD | NEW |