Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp

Issue 17777004: Concurrency support for PNaCl ABI (Closed) Base URL: http://git.chromium.org/native_client/pnacl-llvm.git@master
Patch Set: Simplify overloading and function verification. Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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.
11 // 11 //
12 // 12 //
13 //===----------------------------------------------------------------------===// 13 //===----------------------------------------------------------------------===//
14 14
15 #include "llvm/ADT/Twine.h" 15 #include "llvm/ADT/Twine.h"
16 #include "llvm/Analysis/NaCl.h" 16 #include "llvm/Analysis/NaCl.h"
17 #include "llvm/IR/Function.h" 17 #include "llvm/IR/Function.h"
18 #include "llvm/IR/Instructions.h" 18 #include "llvm/IR/Instructions.h"
19 #include "llvm/IR/IntrinsicInst.h" 19 #include "llvm/IR/IntrinsicInst.h"
20 #include "llvm/IR/LLVMContext.h" 20 #include "llvm/IR/LLVMContext.h"
21 #include "llvm/IR/Metadata.h" 21 #include "llvm/IR/Metadata.h"
22 #include "llvm/IR/NaClIntrinsics.h"
22 #include "llvm/IR/Operator.h" 23 #include "llvm/IR/Operator.h"
23 #include "llvm/Pass.h" 24 #include "llvm/Pass.h"
24 #include "llvm/Support/raw_ostream.h" 25 #include "llvm/Support/raw_ostream.h"
25 26
26 #include "PNaClABITypeChecker.h" 27 #include "PNaClABITypeChecker.h"
27 using namespace llvm; 28 using namespace llvm;
28 29
29 namespace { 30 namespace {
30 31
31 // Checks that examine anything in the function body should be in 32 // Checks that examine anything in the function body should be in
(...skipping 14 matching lines...) Expand all
46 initializePNaClABIVerifyFunctionsPass(*PassRegistry::getPassRegistry()); 47 initializePNaClABIVerifyFunctionsPass(*PassRegistry::getPassRegistry());
47 } 48 }
48 ~PNaClABIVerifyFunctions() { 49 ~PNaClABIVerifyFunctions() {
49 if (ReporterIsOwned) 50 if (ReporterIsOwned)
50 delete Reporter; 51 delete Reporter;
51 } 52 }
52 bool runOnFunction(Function &F); 53 bool runOnFunction(Function &F);
53 virtual void print(raw_ostream &O, const Module *M) const; 54 virtual void print(raw_ostream &O, const Module *M) const;
54 private: 55 private:
55 bool IsWhitelistedMetadata(unsigned MDKind); 56 bool IsWhitelistedMetadata(unsigned MDKind);
56 const char *checkInstruction(const Instruction *Inst); 57 const char *checkInstruction(LLVMContext &C, const NaCl::AtomicIntrinsics &AI,
58 const Instruction *Inst);
57 PNaClABIErrorReporter *Reporter; 59 PNaClABIErrorReporter *Reporter;
58 bool ReporterIsOwned; 60 bool ReporterIsOwned;
59 }; 61 };
60 62
61 } // and anonymous namespace 63 } // and anonymous namespace
62 64
63 // There's no built-in way to get the name of an MDNode, so use a 65 // There's no built-in way to get the name of an MDNode, so use a
64 // string ostream to print it. 66 // string ostream to print it.
65 static std::string getMDNodeString(unsigned Kind, 67 static std::string getMDNodeString(unsigned Kind,
66 const SmallVectorImpl<StringRef> &MDNames) { 68 const SmallVectorImpl<StringRef> &MDNames) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 if (isa<Instruction>(Val) || isa<Argument>(Val) || isa<BasicBlock>(Val)) 133 if (isa<Instruction>(Val) || isa<Argument>(Val) || isa<BasicBlock>(Val))
132 return true; 134 return true;
133 135
134 // Allow some Constants. Note that this excludes ConstantExprs. 136 // Allow some Constants. Note that this excludes ConstantExprs.
135 return PNaClABITypeChecker::isValidScalarType(Val->getType()) && 137 return PNaClABITypeChecker::isValidScalarType(Val->getType()) &&
136 (isa<ConstantInt>(Val) || 138 (isa<ConstantInt>(Val) ||
137 isa<ConstantFP>(Val) || 139 isa<ConstantFP>(Val) ||
138 isa<UndefValue>(Val)); 140 isa<UndefValue>(Val));
139 } 141 }
140 142
141 static bool isAllowedAlignment(unsigned Alignment, Type *Ty, bool IsAtomic) { 143 static bool isAllowedAlignment(unsigned Alignment, Type *Ty) {
142 if (IsAtomic) {
143 // For atomic operations, the alignment must match the size of the type.
144 if (Ty->isIntegerTy()) {
145 unsigned Bits = Ty->getIntegerBitWidth();
146 return Bits % 8 == 0 && Alignment == Bits / 8;
147 }
148 return (Ty->isDoubleTy() && Alignment == 8) ||
149 (Ty->isFloatTy() && Alignment == 4);
150 }
151 // Non-atomic integer operations must always use "align 1", since we 144 // Non-atomic integer operations must always use "align 1", since we
152 // do not want the backend to generate code with non-portable 145 // do not want the backend to generate code with non-portable
153 // undefined behaviour (such as misaligned access faults) if user 146 // undefined behaviour (such as misaligned access faults) if user
154 // code specifies "align 4" but uses a misaligned pointer. As a 147 // code specifies "align 4" but uses a misaligned pointer. As a
155 // concession to performance, we allow larger alignment values for 148 // concession to performance, we allow larger alignment values for
156 // floating point types. 149 // floating point types.
157 // 150 //
158 // To reduce the set of alignment values that need to be encoded in 151 // To reduce the set of alignment values that need to be encoded in
159 // pexes, we disallow other alignment values. We require alignments 152 // pexes, we disallow other alignment values. We require alignments
160 // to be explicit by disallowing Alignment == 0. 153 // to be explicit by disallowing Alignment == 0.
161 return Alignment == 1 || 154 return Alignment == 1 ||
162 (Ty->isDoubleTy() && Alignment == 8) || 155 (Ty->isDoubleTy() && Alignment == 8) ||
163 (Ty->isFloatTy() && Alignment == 4); 156 (Ty->isFloatTy() && Alignment == 4);
164 } 157 }
165 158
159 static bool hasAllowedAtomicRMWOperation(
160 NaCl::AtomicIntrinsics::const_iterator AI, const CallInst *Call) {
161 for (size_t P = 0; P != NaCl::MaxAtomicIntrinsicsParameters; ++P) {
162 if (AI->ParamType[P] != NaCl::AtomicIntrinsics::RMW)
163 continue;
164
165 const Value *Operation = Call->getOperand(P);
166 if (!Operation)
167 return false;
168 const Constant *C = dyn_cast<Constant>(Operation);
169 if (!C)
170 return false;
171 const APInt &I = C->getUniqueInteger();
172 if (I.ule(NaCl::AtomicInvalid) || I.uge(NaCl::AtomicNum))
173 return false;
174 }
175 return true;
176 }
177
178 static bool hasAllowedAtomicMemoryOrder(
179 NaCl::AtomicIntrinsics::const_iterator AI, const CallInst *Call) {
180 for (size_t P = 0; P != NaCl::MaxAtomicIntrinsicsParameters; ++P) {
181 if (AI->ParamType[P] != NaCl::AtomicIntrinsics::Mem)
182 continue;
183
184 const Value *MemoryOrder = Call->getOperand(P);
185 if (!MemoryOrder)
186 return false;
187 const Constant *C = dyn_cast<Constant>(MemoryOrder);
188 if (!C)
189 return false;
190 const APInt &I = C->getUniqueInteger();
191 if (I.ule(NaCl::MemoryOrderInvalid) || I.uge(NaCl::MemoryOrderNum))
192 return false;
193 // TODO For now only sequential consistency is allowed. When more
194 // are allowed we need to validate that the memory order is
195 // allowed on the specific atomic operation (e.g. no store
196 // acquire, and relationship between success/failure memory
197 // order on compare exchange).
198 if (I != NaCl::MemoryOrderSequentiallyConsistent)
199 return false;
200 }
201 return true;
202 }
203
166 // Check the instruction's opcode and its operands. The operands may 204 // Check the instruction's opcode and its operands. The operands may
167 // require opcode-specific checking. 205 // require opcode-specific checking.
168 // 206 //
169 // This returns an error string if the instruction is rejected, or 207 // This returns an error string if the instruction is rejected, or
170 // NULL if the instruction is allowed. 208 // NULL if the instruction is allowed.
171 const char *PNaClABIVerifyFunctions::checkInstruction(const Instruction *Inst) { 209 const char *PNaClABIVerifyFunctions::checkInstruction(LLVMContext &C,
210 const NaCl::AtomicIntrinsics &AI, const Instruction *Inst) {
172 // If the instruction has a single pointer operand, PtrOperandIndex is 211 // If the instruction has a single pointer operand, PtrOperandIndex is
173 // set to its operand index. 212 // set to its operand index.
174 unsigned PtrOperandIndex = -1; 213 unsigned PtrOperandIndex = -1;
175 214
176 switch (Inst->getOpcode()) { 215 switch (Inst->getOpcode()) {
177 // Disallowed instructions. Default is to disallow. 216 // Disallowed instructions. Default is to disallow.
178 // We expand GetElementPtr out into arithmetic. 217 // We expand GetElementPtr out into arithmetic.
179 case Instruction::GetElementPtr: 218 case Instruction::GetElementPtr:
180 // VAArg is expanded out by ExpandVarArgs. 219 // VAArg is expanded out by ExpandVarArgs.
181 case Instruction::VAArg: 220 case Instruction::VAArg:
182 // Zero-cost C++ exception handling is not supported yet. 221 // Zero-cost C++ exception handling is not supported yet.
183 case Instruction::Invoke: 222 case Instruction::Invoke:
184 case Instruction::LandingPad: 223 case Instruction::LandingPad:
185 case Instruction::Resume: 224 case Instruction::Resume:
186 // indirectbr may interfere with streaming 225 // indirectbr may interfere with streaming
187 case Instruction::IndirectBr: 226 case Instruction::IndirectBr:
188 // No vector instructions yet 227 // No vector instructions yet
189 case Instruction::ExtractElement: 228 case Instruction::ExtractElement:
190 case Instruction::InsertElement: 229 case Instruction::InsertElement:
191 case Instruction::ShuffleVector: 230 case Instruction::ShuffleVector:
192 // ExtractValue and InsertValue operate on struct values. 231 // ExtractValue and InsertValue operate on struct values.
193 case Instruction::ExtractValue: 232 case Instruction::ExtractValue:
194 case Instruction::InsertValue: 233 case Instruction::InsertValue:
234 // Atomics should become NaCl intrinsics.
235 case Instruction::AtomicCmpXchg:
236 case Instruction::AtomicRMW:
237 case Instruction::Fence:
195 return "bad instruction opcode"; 238 return "bad instruction opcode";
196 default: 239 default:
197 return "unknown instruction opcode"; 240 return "unknown instruction opcode";
198 241
199 // Terminator instructions 242 // Terminator instructions
200 case Instruction::Ret: 243 case Instruction::Ret:
201 case Instruction::Br: 244 case Instruction::Br:
202 case Instruction::Unreachable: 245 case Instruction::Unreachable:
203 // Binary operations 246 // Binary operations
204 case Instruction::Add: 247 case Instruction::Add:
205 case Instruction::FAdd: 248 case Instruction::FAdd:
206 case Instruction::Sub: 249 case Instruction::Sub:
207 case Instruction::FSub: 250 case Instruction::FSub:
208 case Instruction::Mul: 251 case Instruction::Mul:
209 case Instruction::FMul: 252 case Instruction::FMul:
210 case Instruction::UDiv: 253 case Instruction::UDiv:
211 case Instruction::SDiv: 254 case Instruction::SDiv:
212 case Instruction::FDiv: 255 case Instruction::FDiv:
213 case Instruction::URem: 256 case Instruction::URem:
214 case Instruction::SRem: 257 case Instruction::SRem:
215 case Instruction::FRem: 258 case Instruction::FRem:
216 // Bitwise binary operations 259 // Bitwise binary operations
217 case Instruction::Shl: 260 case Instruction::Shl:
218 case Instruction::LShr: 261 case Instruction::LShr:
219 case Instruction::AShr: 262 case Instruction::AShr:
220 case Instruction::And: 263 case Instruction::And:
221 case Instruction::Or: 264 case Instruction::Or:
222 case Instruction::Xor: 265 case Instruction::Xor:
223 // Memory instructions
224 case Instruction::Fence:
225 // Conversion operations 266 // Conversion operations
226 case Instruction::Trunc: 267 case Instruction::Trunc:
227 case Instruction::ZExt: 268 case Instruction::ZExt:
228 case Instruction::SExt: 269 case Instruction::SExt:
229 case Instruction::FPTrunc: 270 case Instruction::FPTrunc:
230 case Instruction::FPExt: 271 case Instruction::FPExt:
231 case Instruction::FPToUI: 272 case Instruction::FPToUI:
232 case Instruction::FPToSI: 273 case Instruction::FPToSI:
233 case Instruction::UIToFP: 274 case Instruction::UIToFP:
234 case Instruction::SIToFP: 275 case Instruction::SIToFP:
235 // Other operations 276 // Other operations
236 case Instruction::ICmp: 277 case Instruction::ICmp:
237 case Instruction::FCmp: 278 case Instruction::FCmp:
238 case Instruction::PHI: 279 case Instruction::PHI:
239 case Instruction::Select: 280 case Instruction::Select:
240 break; 281 break;
241 282
242 // Memory accesses. 283 // Memory accesses.
243 case Instruction::Load: { 284 case Instruction::Load: {
244 const LoadInst *Load = cast<LoadInst>(Inst); 285 const LoadInst *Load = cast<LoadInst>(Inst);
286 PtrOperandIndex = Load->getPointerOperandIndex();
287 if (Load->isAtomic())
288 return "atomic";
289 if (Load->isVolatile())
290 return "volatile";
245 if (!isAllowedAlignment(Load->getAlignment(), 291 if (!isAllowedAlignment(Load->getAlignment(),
246 Load->getType(), 292 Load->getType()))
247 Load->isAtomic()))
248 return "bad alignment"; 293 return "bad alignment";
249 PtrOperandIndex = 0;
250 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex))) 294 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex)))
251 return "bad pointer"; 295 return "bad pointer";
252 break; 296 break;
253 } 297 }
254 case Instruction::Store: { 298 case Instruction::Store: {
255 const StoreInst *Store = cast<StoreInst>(Inst); 299 const StoreInst *Store = cast<StoreInst>(Inst);
300 PtrOperandIndex = Store->getPointerOperandIndex();
301 if (Store->isAtomic())
302 return "atomic";
303 if (Store->isVolatile())
304 return "volatile";
256 if (!isAllowedAlignment(Store->getAlignment(), 305 if (!isAllowedAlignment(Store->getAlignment(),
257 Store->getValueOperand()->getType(), 306 Store->getValueOperand()->getType()))
258 Store->isAtomic()))
259 return "bad alignment"; 307 return "bad alignment";
260 PtrOperandIndex = 1;
261 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex))) 308 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex)))
262 return "bad pointer"; 309 return "bad pointer";
263 break; 310 break;
264 } 311 }
265 case Instruction::AtomicCmpXchg:
266 case Instruction::AtomicRMW:
267 PtrOperandIndex = 0;
268 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex)))
269 return "bad pointer";
270 break;
271 312
272 // Casts. 313 // Casts.
273 case Instruction::BitCast: 314 case Instruction::BitCast:
274 if (Inst->getType()->isPointerTy()) { 315 if (Inst->getType()->isPointerTy()) {
275 PtrOperandIndex = 0; 316 PtrOperandIndex = 0;
276 if (!isInherentPtr(Inst->getOperand(PtrOperandIndex))) 317 if (!isInherentPtr(Inst->getOperand(PtrOperandIndex)))
277 return "operand not InherentPtr"; 318 return "operand not InherentPtr";
278 } 319 }
279 break; 320 break;
280 case Instruction::IntToPtr: 321 case Instruction::IntToPtr:
(...skipping 27 matching lines...) Expand all
308 // metadata arguments, so handle them specially. 349 // metadata arguments, so handle them specially.
309 if (const IntrinsicInst *Call = dyn_cast<IntrinsicInst>(Inst)) { 350 if (const IntrinsicInst *Call = dyn_cast<IntrinsicInst>(Inst)) {
310 for (unsigned ArgNum = 0, E = Call->getNumArgOperands(); 351 for (unsigned ArgNum = 0, E = Call->getNumArgOperands();
311 ArgNum < E; ++ArgNum) { 352 ArgNum < E; ++ArgNum) {
312 const Value *Arg = Call->getArgOperand(ArgNum); 353 const Value *Arg = Call->getArgOperand(ArgNum);
313 if (!(isValidScalarOperand(Arg) || 354 if (!(isValidScalarOperand(Arg) ||
314 isNormalizedPtr(Arg) || 355 isNormalizedPtr(Arg) ||
315 isa<MDNode>(Arg))) 356 isa<MDNode>(Arg)))
316 return "bad intrinsic operand"; 357 return "bad intrinsic operand";
317 } 358 }
359
318 // Disallow alignments other than 1 on memcpy() etc., for the 360 // Disallow alignments other than 1 on memcpy() etc., for the
319 // same reason that we disallow them on integer loads and 361 // same reason that we disallow them on integer loads and
320 // stores. 362 // stores.
321 if (const MemIntrinsic *MemOp = dyn_cast<MemIntrinsic>(Call)) { 363 if (const MemIntrinsic *MemOp = dyn_cast<MemIntrinsic>(Call)) {
322 // Avoid the getAlignment() method here because it aborts if 364 // Avoid the getAlignment() method here because it aborts if
323 // the alignment argument is not a Constant. 365 // the alignment argument is not a Constant.
324 Value *AlignArg = MemOp->getArgOperand(3); 366 Value *AlignArg = MemOp->getArgOperand(3);
325 if (!isa<ConstantInt>(AlignArg) || 367 if (!isa<ConstantInt>(AlignArg) ||
326 cast<ConstantInt>(AlignArg)->getZExtValue() != 1) { 368 cast<ConstantInt>(AlignArg)->getZExtValue() != 1) {
327 return "bad alignment"; 369 return "bad alignment";
328 } 370 }
329 } 371 }
372
373 // Disallow NaCl atomic intrinsics which don't have valid
374 // constant NaCl::AtomicOperation and NaCl::MemoryOrder
375 // parameters.
376 switch (Call->getIntrinsicID()) {
Mark Seaborn 2013/07/02 19:16:02 Fix indentation: reduce by 2
JF 2013/07/02 23:14:54 This is inconsistent with the rest of the file.
Mark Seaborn 2013/07/02 23:34:10 This 'switch' statement doesn't line up with the c
JF 2013/07/02 23:49:04 Done.
377 default: break; // Non-atomic intrinsic.
378 case Intrinsic::nacl_atomic_load:
379 case Intrinsic::nacl_atomic_store:
380 case Intrinsic::nacl_atomic_rmw:
381 case Intrinsic::nacl_atomic_cmpxchg:
382 case Intrinsic::nacl_atomic_fence: {
383 NaCl::AtomicIntrinsics::const_iterator I =
384 AI.find(Call->getIntrinsicID(), Type::getInt32Ty(C));
385 if (!hasAllowedAtomicMemoryOrder(I, Call))
386 return "invalid memory order";
387 if (!hasAllowedAtomicRMWOperation(I, Call))
388 return "invalid atomicRMW operation";
389 } break;
Mark Seaborn 2013/07/02 19:16:02 "break" should go inside the {} block.
JF 2013/07/02 23:14:54 There's enough code this way in the code base, and
390 }
391
330 // Allow the instruction and skip the later checks. 392 // Allow the instruction and skip the later checks.
331 return NULL; 393 return NULL;
332 } 394 }
333 395
334 // The callee is the last operand. 396 // The callee is the last operand.
335 PtrOperandIndex = Inst->getNumOperands() - 1; 397 PtrOperandIndex = Inst->getNumOperands() - 1;
336 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex))) 398 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex)))
337 return "bad function callee operand"; 399 return "bad function callee operand";
338 break; 400 break;
339 } 401 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 if (Op->isExact()) 450 if (Op->isExact())
389 return "has \"exact\" attribute"; 451 return "has \"exact\" attribute";
390 } 452 }
391 453
392 // Allow the instruction. 454 // Allow the instruction.
393 return NULL; 455 return NULL;
394 } 456 }
395 457
396 bool PNaClABIVerifyFunctions::runOnFunction(Function &F) { 458 bool PNaClABIVerifyFunctions::runOnFunction(Function &F) {
397 SmallVector<StringRef, 8> MDNames; 459 SmallVector<StringRef, 8> MDNames;
398 F.getContext().getMDKindNames(MDNames); 460 LLVMContext &C = F.getContext();
Mark Seaborn 2013/07/02 19:16:02 Nit: 'C' -> 'Context'. This isn't used often enou
JF 2013/07/02 23:14:54 It's pretty much split in the middle on C versus C
461 C.getMDKindNames(MDNames);
462
463 NaCl::AtomicIntrinsics AI(C);
399 464
400 for (Function::const_iterator FI = F.begin(), FE = F.end(); 465 for (Function::const_iterator FI = F.begin(), FE = F.end();
401 FI != FE; ++FI) { 466 FI != FE; ++FI) {
402 for (BasicBlock::const_iterator BBI = FI->begin(), BBE = FI->end(); 467 for (BasicBlock::const_iterator BBI = FI->begin(), BBE = FI->end();
403 BBI != BBE; ++BBI) { 468 BBI != BBE; ++BBI) {
404 const Instruction *Inst = BBI; 469 const Instruction *Inst = BBI;
405 // Check the instruction opcode first. This simplifies testing, 470 // Check the instruction opcode first. This simplifies testing,
406 // because some instruction opcodes must be rejected out of hand 471 // because some instruction opcodes must be rejected out of hand
407 // (regardless of the instruction's result type) and the tests 472 // (regardless of the instruction's result type) and the tests
408 // check the reason for rejection. 473 // check the reason for rejection.
409 const char *Error = checkInstruction(BBI); 474 const char *Error = checkInstruction(C, AI, BBI);
410 // Check the instruction's result type. 475 // Check the instruction's result type.
411 if (!Error && !(PNaClABITypeChecker::isValidScalarType(Inst->getType()) || 476 if (!Error && !(PNaClABITypeChecker::isValidScalarType(Inst->getType()) ||
412 isNormalizedPtr(Inst) || 477 isNormalizedPtr(Inst) ||
413 isa<AllocaInst>(Inst))) { 478 isa<AllocaInst>(Inst))) {
414 Error = "bad result type"; 479 Error = "bad result type";
415 } 480 }
416 if (Error) { 481 if (Error) {
417 Reporter->addError() << "Function " << F.getName() << 482 Reporter->addError() << "Function " << F.getName() <<
418 " disallowed: " << Error << ": " << *BBI << "\n"; 483 " disallowed: " << Error << ": " << *BBI << "\n";
419 } 484 }
(...skipping 27 matching lines...) Expand all
447 } 512 }
448 513
449 char PNaClABIVerifyFunctions::ID = 0; 514 char PNaClABIVerifyFunctions::ID = 0;
450 INITIALIZE_PASS(PNaClABIVerifyFunctions, "verify-pnaclabi-functions", 515 INITIALIZE_PASS(PNaClABIVerifyFunctions, "verify-pnaclabi-functions",
451 "Verify functions for PNaCl", false, true) 516 "Verify functions for PNaCl", false, true)
452 517
453 FunctionPass *llvm::createPNaClABIVerifyFunctionsPass( 518 FunctionPass *llvm::createPNaClABIVerifyFunctionsPass(
454 PNaClABIErrorReporter *Reporter) { 519 PNaClABIErrorReporter *Reporter) {
455 return new PNaClABIVerifyFunctions(Reporter); 520 return new PNaClABIVerifyFunctions(Reporter);
456 } 521 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698