OLD | NEW |
1 //===- PNaClABIVerifyFunctions.cpp - Verify PNaCl ABI rules ---------------===// | 1 //===- PNaClABIVerifyFunctions.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 function-level PNaCl ABI requirements. | 10 // Verify function-level PNaCl ABI requirements. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 initializePNaClABIVerifyFunctionsPass(*PassRegistry::getPassRegistry()); | 49 initializePNaClABIVerifyFunctionsPass(*PassRegistry::getPassRegistry()); |
50 } | 50 } |
51 ~PNaClABIVerifyFunctions() { | 51 ~PNaClABIVerifyFunctions() { |
52 if (ReporterIsOwned) | 52 if (ReporterIsOwned) |
53 delete Reporter; | 53 delete Reporter; |
54 } | 54 } |
55 virtual bool doInitialization(Module &M) { | 55 virtual bool doInitialization(Module &M) { |
56 AtomicIntrinsics.reset(new NaCl::AtomicIntrinsics(M.getContext())); | 56 AtomicIntrinsics.reset(new NaCl::AtomicIntrinsics(M.getContext())); |
57 return false; | 57 return false; |
58 } | 58 } |
| 59 virtual void getAnalysisUsage(AnalysisUsage &Info) const { |
| 60 Info.setPreservesAll(); |
| 61 Info.addRequired<DataLayout>(); |
| 62 } |
59 bool runOnFunction(Function &F); | 63 bool runOnFunction(Function &F); |
60 virtual void print(raw_ostream &O, const Module *M) const; | 64 virtual void print(raw_ostream &O, const Module *M) const; |
61 private: | 65 private: |
62 bool IsWhitelistedMetadata(unsigned MDKind); | 66 bool IsWhitelistedMetadata(unsigned MDKind); |
63 const char *checkInstruction(const Instruction *Inst); | 67 const char *checkInstruction(const DataLayout *DL, const Instruction *Inst); |
64 PNaClABIErrorReporter *Reporter; | 68 PNaClABIErrorReporter *Reporter; |
65 bool ReporterIsOwned; | 69 bool ReporterIsOwned; |
66 OwningPtr<NaCl::AtomicIntrinsics> AtomicIntrinsics; | 70 OwningPtr<NaCl::AtomicIntrinsics> AtomicIntrinsics; |
67 }; | 71 }; |
68 | 72 |
69 } // and anonymous namespace | 73 } // and anonymous namespace |
70 | 74 |
71 // There's no built-in way to get the name of an MDNode, so use a | 75 // There's no built-in way to get the name of an MDNode, so use a |
72 // string ostream to print it. | 76 // string ostream to print it. |
73 static std::string getMDNodeString(unsigned Kind, | 77 static std::string getMDNodeString(unsigned Kind, |
74 const SmallVectorImpl<StringRef> &MDNames) { | 78 const SmallVectorImpl<StringRef> &MDNames) { |
75 std::string MDName; | 79 std::string MDName; |
76 raw_string_ostream N(MDName); | 80 raw_string_ostream N(MDName); |
77 if (Kind < MDNames.size()) { | 81 if (Kind < MDNames.size()) { |
78 N << "!" << MDNames[Kind]; | 82 N << "!" << MDNames[Kind]; |
79 } else { | 83 } else { |
80 N << "!<unknown kind #" << Kind << ">"; | 84 N << "!<unknown kind #" << Kind << ">"; |
81 } | 85 } |
82 return N.str(); | 86 return N.str(); |
83 } | 87 } |
84 | 88 |
85 bool PNaClABIVerifyFunctions::IsWhitelistedMetadata(unsigned MDKind) { | 89 bool PNaClABIVerifyFunctions::IsWhitelistedMetadata(unsigned MDKind) { |
86 return MDKind == LLVMContext::MD_dbg && PNaClABIAllowDebugMetadata; | 90 return MDKind == LLVMContext::MD_dbg && PNaClABIAllowDebugMetadata; |
87 } | 91 } |
88 | 92 |
89 // A valid pointer type is either: | 93 // A valid pointer type is either: |
90 // * a pointer to a valid PNaCl scalar type (except i1), or | 94 // * a pointer to a valid PNaCl scalar type (except i1), or |
| 95 // * a pointer to a valid PNaCl vector type (except i1), or |
91 // * a function pointer (with valid argument and return types). | 96 // * a function pointer (with valid argument and return types). |
92 // | 97 // |
93 // i1 is disallowed so that all loads and stores are a whole number of | 98 // i1 is disallowed so that all loads and stores are a whole number of |
94 // bytes, and so that we do not need to define whether a store of i1 | 99 // bytes, and so that we do not need to define whether a store of i1 |
95 // zero-extends. | 100 // zero-extends. |
96 // | |
97 // Vector pointer types aren't currently allowed because vector memory | |
98 // accesses go through their scalar elements. | |
99 static bool isValidPointerType(Type *Ty) { | 101 static bool isValidPointerType(Type *Ty) { |
100 if (PointerType *PtrTy = dyn_cast<PointerType>(Ty)) { | 102 if (PointerType *PtrTy = dyn_cast<PointerType>(Ty)) { |
101 if (PtrTy->getAddressSpace() != 0) | 103 if (PtrTy->getAddressSpace() != 0) |
102 return false; | 104 return false; |
103 Type *EltTy = PtrTy->getElementType(); | 105 Type *EltTy = PtrTy->getElementType(); |
104 if (PNaClABITypeChecker::isValidScalarType(EltTy) && !EltTy->isIntegerTy(1)) | 106 if (PNaClABITypeChecker::isValidScalarType(EltTy) && !EltTy->isIntegerTy(1)) |
105 return true; | 107 return true; |
| 108 if (PNaClABITypeChecker::isValidVectorType(EltTy) && |
| 109 !cast<VectorType>(EltTy)->getElementType()->isIntegerTy(1)) |
| 110 return true; |
106 if (FunctionType *FTy = dyn_cast<FunctionType>(EltTy)) | 111 if (FunctionType *FTy = dyn_cast<FunctionType>(EltTy)) |
107 return PNaClABITypeChecker::isValidFunctionType(FTy); | 112 return PNaClABITypeChecker::isValidFunctionType(FTy); |
108 } | 113 } |
109 return false; | 114 return false; |
110 } | 115 } |
111 | 116 |
112 static bool isIntrinsicFunc(const Value *Val) { | 117 static bool isIntrinsicFunc(const Value *Val) { |
113 if (const Function *F = dyn_cast<Function>(Val)) | 118 if (const Function *F = dyn_cast<Function>(Val)) |
114 return F->isIntrinsic(); | 119 return F->isIntrinsic(); |
115 return false; | 120 return false; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 if (isa<Instruction>(Val) || isa<Argument>(Val)) | 164 if (isa<Instruction>(Val) || isa<Argument>(Val)) |
160 return true; | 165 return true; |
161 // Contrary to scalars, constant vector values aren't allowed on | 166 // Contrary to scalars, constant vector values aren't allowed on |
162 // instructions, except undefined. Constant vectors are loaded from | 167 // instructions, except undefined. Constant vectors are loaded from |
163 // constant global memory instead, and can be rematerialized as | 168 // constant global memory instead, and can be rematerialized as |
164 // constants by the backend if need be. | 169 // constants by the backend if need be. |
165 return PNaClABITypeChecker::isValidVectorType(Val->getType()) && | 170 return PNaClABITypeChecker::isValidVectorType(Val->getType()) && |
166 isa<UndefValue>(Val); | 171 isa<UndefValue>(Val); |
167 } | 172 } |
168 | 173 |
169 static bool isAllowedAlignment(unsigned Alignment, Type *Ty) { | 174 static bool isAllowedAlignment(const DataLayout *DL, uint64_t Alignment, |
170 // Non-atomic integer operations must always use "align 1", since we | 175 Type *Ty) { |
171 // do not want the backend to generate code with non-portable | 176 // Non-atomic integer operations must always use "align 1", since we do not |
172 // undefined behaviour (such as misaligned access faults) if user | 177 // want the backend to generate code with non-portable undefined behaviour |
173 // code specifies "align 4" but uses a misaligned pointer. As a | 178 // (such as misaligned access faults) if user code specifies "align 4" but |
174 // concession to performance, we allow larger alignment values for | 179 // uses a misaligned pointer. As a concession to performance, we allow larger |
175 // floating point types. | 180 // alignment values for floating point types, and we only allow vectors to be |
| 181 // aligned by their element's size. |
176 // | 182 // |
177 // To reduce the set of alignment values that need to be encoded in | 183 // TODO(jfb) Allow vectors to be marked as align == 1. This requires proper |
178 // pexes, we disallow other alignment values. We require alignments | 184 // testing on each supported ISA, and is probably not as common as |
179 // to be explicit by disallowing Alignment == 0. | 185 // align == elemsize. |
180 // | 186 // |
181 // Vector memory accesses go through their scalar elements, there is | 187 // To reduce the set of alignment values that need to be encoded in pexes, we |
182 // therefore no such thing as vector alignment. | 188 // disallow other alignment values. We require alignments to be explicit by |
183 return Alignment == 1 || | 189 // disallowing Alignment == 0. |
184 (Ty->isDoubleTy() && Alignment == 8) || | 190 if (Alignment > std::numeric_limits<uint64_t>::max() / CHAR_BIT) |
185 (Ty->isFloatTy() && Alignment == 4); | 191 return false; // No overflow assumed below. |
| 192 else if (VectorType *VTy = dyn_cast<VectorType>(Ty)) |
| 193 return !VTy->getElementType()->isIntegerTy(1) && |
| 194 (Alignment * CHAR_BIT == |
| 195 DL->getTypeSizeInBits(VTy->getElementType())); |
| 196 else |
| 197 return Alignment == 1 || |
| 198 (Ty->isDoubleTy() && Alignment == 8) || |
| 199 (Ty->isFloatTy() && Alignment == 4); |
186 } | 200 } |
187 | 201 |
188 static bool hasAllowedAtomicRMWOperation( | 202 static bool hasAllowedAtomicRMWOperation( |
189 const NaCl::AtomicIntrinsics::AtomicIntrinsic *I, const CallInst *Call) { | 203 const NaCl::AtomicIntrinsics::AtomicIntrinsic *I, const CallInst *Call) { |
190 for (size_t P = 0; P != I->NumParams; ++P) { | 204 for (size_t P = 0; P != I->NumParams; ++P) { |
191 if (I->ParamType[P] != NaCl::AtomicIntrinsics::RMW) | 205 if (I->ParamType[P] != NaCl::AtomicIntrinsics::RMW) |
192 continue; | 206 continue; |
193 | 207 |
194 const Value *Operation = Call->getOperand(P); | 208 const Value *Operation = Call->getOperand(P); |
195 if (!Operation) | 209 if (!Operation) |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 if (I == 1 || I == 2 || I == 4 || I == 8) | 260 if (I == 1 || I == 2 || I == 4 || I == 8) |
247 return true; | 261 return true; |
248 return false; | 262 return false; |
249 } | 263 } |
250 | 264 |
251 // Check the instruction's opcode and its operands. The operands may | 265 // Check the instruction's opcode and its operands. The operands may |
252 // require opcode-specific checking. | 266 // require opcode-specific checking. |
253 // | 267 // |
254 // This returns an error string if the instruction is rejected, or | 268 // This returns an error string if the instruction is rejected, or |
255 // NULL if the instruction is allowed. | 269 // NULL if the instruction is allowed. |
256 const char *PNaClABIVerifyFunctions::checkInstruction(const Instruction *Inst) { | 270 const char *PNaClABIVerifyFunctions::checkInstruction(const DataLayout *DL, |
| 271 const Instruction *Inst) { |
257 // If the instruction has a single pointer operand, PtrOperandIndex is | 272 // If the instruction has a single pointer operand, PtrOperandIndex is |
258 // set to its operand index. | 273 // set to its operand index. |
259 unsigned PtrOperandIndex = -1; | 274 unsigned PtrOperandIndex = -1; |
260 | 275 |
261 switch (Inst->getOpcode()) { | 276 switch (Inst->getOpcode()) { |
262 // Disallowed instructions. Default is to disallow. | 277 // Disallowed instructions. Default is to disallow. |
263 // We expand GetElementPtr out into arithmetic. | 278 // We expand GetElementPtr out into arithmetic. |
264 case Instruction::GetElementPtr: | 279 case Instruction::GetElementPtr: |
265 // VAArg is expanded out by ExpandVarArgs. | 280 // VAArg is expanded out by ExpandVarArgs. |
266 case Instruction::VAArg: | 281 case Instruction::VAArg: |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 // Memory accesses. | 372 // Memory accesses. |
358 case Instruction::Load: { | 373 case Instruction::Load: { |
359 const LoadInst *Load = cast<LoadInst>(Inst); | 374 const LoadInst *Load = cast<LoadInst>(Inst); |
360 PtrOperandIndex = Load->getPointerOperandIndex(); | 375 PtrOperandIndex = Load->getPointerOperandIndex(); |
361 if (Load->isAtomic()) | 376 if (Load->isAtomic()) |
362 return "atomic load"; | 377 return "atomic load"; |
363 if (Load->isVolatile()) | 378 if (Load->isVolatile()) |
364 return "volatile load"; | 379 return "volatile load"; |
365 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex))) | 380 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex))) |
366 return "bad pointer"; | 381 return "bad pointer"; |
367 if (!isAllowedAlignment(Load->getAlignment(), | 382 if (!isAllowedAlignment(DL, Load->getAlignment(), Load->getType())) |
368 Load->getType())) | |
369 return "bad alignment"; | 383 return "bad alignment"; |
370 break; | 384 break; |
371 } | 385 } |
372 case Instruction::Store: { | 386 case Instruction::Store: { |
373 const StoreInst *Store = cast<StoreInst>(Inst); | 387 const StoreInst *Store = cast<StoreInst>(Inst); |
374 PtrOperandIndex = Store->getPointerOperandIndex(); | 388 PtrOperandIndex = Store->getPointerOperandIndex(); |
375 if (Store->isAtomic()) | 389 if (Store->isAtomic()) |
376 return "atomic store"; | 390 return "atomic store"; |
377 if (Store->isVolatile()) | 391 if (Store->isVolatile()) |
378 return "volatile store"; | 392 return "volatile store"; |
379 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex))) | 393 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex))) |
380 return "bad pointer"; | 394 return "bad pointer"; |
381 if (!isAllowedAlignment(Store->getAlignment(), | 395 if (!isAllowedAlignment(DL, Store->getAlignment(), |
382 Store->getValueOperand()->getType())) | 396 Store->getValueOperand()->getType())) |
383 return "bad alignment"; | 397 return "bad alignment"; |
384 break; | 398 break; |
385 } | 399 } |
386 | 400 |
387 // Casts. | 401 // Casts. |
388 case Instruction::BitCast: | 402 case Instruction::BitCast: |
389 if (Inst->getType()->isPointerTy()) { | 403 if (Inst->getType()->isPointerTy()) { |
390 PtrOperandIndex = 0; | 404 PtrOperandIndex = 0; |
391 if (!isInherentPtr(Inst->getOperand(PtrOperandIndex))) | 405 if (!isInherentPtr(Inst->getOperand(PtrOperandIndex))) |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 dyn_cast<PossiblyExactOperator>(Inst)) { | 548 dyn_cast<PossiblyExactOperator>(Inst)) { |
535 if (Op->isExact()) | 549 if (Op->isExact()) |
536 return "has \"exact\" attribute"; | 550 return "has \"exact\" attribute"; |
537 } | 551 } |
538 | 552 |
539 // Allow the instruction. | 553 // Allow the instruction. |
540 return NULL; | 554 return NULL; |
541 } | 555 } |
542 | 556 |
543 bool PNaClABIVerifyFunctions::runOnFunction(Function &F) { | 557 bool PNaClABIVerifyFunctions::runOnFunction(Function &F) { |
| 558 const DataLayout *DL = &getAnalysis<DataLayout>(); |
544 SmallVector<StringRef, 8> MDNames; | 559 SmallVector<StringRef, 8> MDNames; |
545 F.getContext().getMDKindNames(MDNames); | 560 F.getContext().getMDKindNames(MDNames); |
546 | 561 |
547 for (Function::const_iterator FI = F.begin(), FE = F.end(); | 562 for (Function::const_iterator FI = F.begin(), FE = F.end(); |
548 FI != FE; ++FI) { | 563 FI != FE; ++FI) { |
549 for (BasicBlock::const_iterator BBI = FI->begin(), BBE = FI->end(); | 564 for (BasicBlock::const_iterator BBI = FI->begin(), BBE = FI->end(); |
550 BBI != BBE; ++BBI) { | 565 BBI != BBE; ++BBI) { |
551 const Instruction *Inst = BBI; | 566 const Instruction *Inst = BBI; |
552 // Check the instruction opcode first. This simplifies testing, | 567 // Check the instruction opcode first. This simplifies testing, |
553 // because some instruction opcodes must be rejected out of hand | 568 // because some instruction opcodes must be rejected out of hand |
554 // (regardless of the instruction's result type) and the tests | 569 // (regardless of the instruction's result type) and the tests |
555 // check the reason for rejection. | 570 // check the reason for rejection. |
556 const char *Error = checkInstruction(BBI); | 571 const char *Error = checkInstruction(DL, BBI); |
557 // Check the instruction's result type. | 572 // Check the instruction's result type. |
558 bool BadResult = false; | 573 bool BadResult = false; |
559 if (!Error && !(PNaClABITypeChecker::isValidScalarType(Inst->getType()) || | 574 if (!Error && !(PNaClABITypeChecker::isValidScalarType(Inst->getType()) || |
560 PNaClABITypeChecker::isValidVectorType(Inst->getType()) || | 575 PNaClABITypeChecker::isValidVectorType(Inst->getType()) || |
561 isNormalizedPtr(Inst) || | 576 isNormalizedPtr(Inst) || |
562 isa<AllocaInst>(Inst))) { | 577 isa<AllocaInst>(Inst))) { |
563 Error = "bad result type"; | 578 Error = "bad result type"; |
564 BadResult = true; | 579 BadResult = true; |
565 } | 580 } |
566 if (Error) { | 581 if (Error) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
599 } | 614 } |
600 | 615 |
601 char PNaClABIVerifyFunctions::ID = 0; | 616 char PNaClABIVerifyFunctions::ID = 0; |
602 INITIALIZE_PASS(PNaClABIVerifyFunctions, "verify-pnaclabi-functions", | 617 INITIALIZE_PASS(PNaClABIVerifyFunctions, "verify-pnaclabi-functions", |
603 "Verify functions for PNaCl", false, true) | 618 "Verify functions for PNaCl", false, true) |
604 | 619 |
605 FunctionPass *llvm::createPNaClABIVerifyFunctionsPass( | 620 FunctionPass *llvm::createPNaClABIVerifyFunctionsPass( |
606 PNaClABIErrorReporter *Reporter) { | 621 PNaClABIErrorReporter *Reporter) { |
607 return new PNaClABIVerifyFunctions(Reporter); | 622 return new PNaClABIVerifyFunctions(Reporter); |
608 } | 623 } |
OLD | NEW |