Mercurial > hg > Members > tobaru > cbc > CbC_llvm
comparison lib/Transforms/IPO/FunctionAttrs.cpp @ 77:54457678186b
LLVM 3.6
author | Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 08 Sep 2014 22:06:00 +0900 |
parents | e4204d083e25 |
children | 60c9769439b8 |
comparison
equal
deleted
inserted
replaced
34:e874dbf0ad9d | 77:54457678186b |
---|---|
16 // function's standard definition. This pass is implemented as a | 16 // function's standard definition. This pass is implemented as a |
17 // bottom-up traversal of the call-graph. | 17 // bottom-up traversal of the call-graph. |
18 // | 18 // |
19 //===----------------------------------------------------------------------===// | 19 //===----------------------------------------------------------------------===// |
20 | 20 |
21 #define DEBUG_TYPE "functionattrs" | |
22 #include "llvm/Transforms/IPO.h" | 21 #include "llvm/Transforms/IPO.h" |
23 #include "llvm/ADT/SCCIterator.h" | 22 #include "llvm/ADT/SCCIterator.h" |
24 #include "llvm/ADT/SetVector.h" | 23 #include "llvm/ADT/SetVector.h" |
25 #include "llvm/ADT/SmallSet.h" | 24 #include "llvm/ADT/SmallSet.h" |
26 #include "llvm/ADT/Statistic.h" | 25 #include "llvm/ADT/Statistic.h" |
27 #include "llvm/Analysis/AliasAnalysis.h" | 26 #include "llvm/Analysis/AliasAnalysis.h" |
28 #include "llvm/Analysis/CallGraph.h" | 27 #include "llvm/Analysis/CallGraph.h" |
29 #include "llvm/Analysis/CallGraphSCCPass.h" | 28 #include "llvm/Analysis/CallGraphSCCPass.h" |
30 #include "llvm/Analysis/CaptureTracking.h" | 29 #include "llvm/Analysis/CaptureTracking.h" |
31 #include "llvm/IR/GlobalVariable.h" | 30 #include "llvm/IR/GlobalVariable.h" |
31 #include "llvm/IR/InstIterator.h" | |
32 #include "llvm/IR/IntrinsicInst.h" | 32 #include "llvm/IR/IntrinsicInst.h" |
33 #include "llvm/IR/LLVMContext.h" | 33 #include "llvm/IR/LLVMContext.h" |
34 #include "llvm/Support/InstIterator.h" | |
35 #include "llvm/Target/TargetLibraryInfo.h" | 34 #include "llvm/Target/TargetLibraryInfo.h" |
36 using namespace llvm; | 35 using namespace llvm; |
36 | |
37 #define DEBUG_TYPE "functionattrs" | |
37 | 38 |
38 STATISTIC(NumReadNone, "Number of functions marked readnone"); | 39 STATISTIC(NumReadNone, "Number of functions marked readnone"); |
39 STATISTIC(NumReadOnly, "Number of functions marked readonly"); | 40 STATISTIC(NumReadOnly, "Number of functions marked readonly"); |
40 STATISTIC(NumNoCapture, "Number of arguments marked nocapture"); | 41 STATISTIC(NumNoCapture, "Number of arguments marked nocapture"); |
41 STATISTIC(NumReadNoneArg, "Number of arguments marked readnone"); | 42 STATISTIC(NumReadNoneArg, "Number of arguments marked readnone"); |
44 STATISTIC(NumAnnotated, "Number of attributes added to library functions"); | 45 STATISTIC(NumAnnotated, "Number of attributes added to library functions"); |
45 | 46 |
46 namespace { | 47 namespace { |
47 struct FunctionAttrs : public CallGraphSCCPass { | 48 struct FunctionAttrs : public CallGraphSCCPass { |
48 static char ID; // Pass identification, replacement for typeid | 49 static char ID; // Pass identification, replacement for typeid |
49 FunctionAttrs() : CallGraphSCCPass(ID), AA(0) { | 50 FunctionAttrs() : CallGraphSCCPass(ID), AA(nullptr) { |
50 initializeFunctionAttrsPass(*PassRegistry::getPassRegistry()); | 51 initializeFunctionAttrsPass(*PassRegistry::getPassRegistry()); |
51 } | 52 } |
52 | 53 |
53 // runOnSCC - Analyze the SCC, performing the transformation if possible. | 54 // runOnSCC - Analyze the SCC, performing the transformation if possible. |
54 bool runOnSCC(CallGraphSCC &SCC); | 55 bool runOnSCC(CallGraphSCC &SCC) override; |
55 | 56 |
56 // AddReadAttrs - Deduce readonly/readnone attributes for the SCC. | 57 // AddReadAttrs - Deduce readonly/readnone attributes for the SCC. |
57 bool AddReadAttrs(const CallGraphSCC &SCC); | 58 bool AddReadAttrs(const CallGraphSCC &SCC); |
58 | 59 |
59 // AddArgumentAttrs - Deduce nocapture attributes for the SCC. | 60 // AddArgumentAttrs - Deduce nocapture attributes for the SCC. |
118 | 119 |
119 // annotateLibraryCalls - Adds attributes to well-known standard library | 120 // annotateLibraryCalls - Adds attributes to well-known standard library |
120 // call declarations. | 121 // call declarations. |
121 bool annotateLibraryCalls(const CallGraphSCC &SCC); | 122 bool annotateLibraryCalls(const CallGraphSCC &SCC); |
122 | 123 |
123 virtual void getAnalysisUsage(AnalysisUsage &AU) const { | 124 void getAnalysisUsage(AnalysisUsage &AU) const override { |
124 AU.setPreservesCFG(); | 125 AU.setPreservesCFG(); |
125 AU.addRequired<AliasAnalysis>(); | 126 AU.addRequired<AliasAnalysis>(); |
126 AU.addRequired<TargetLibraryInfo>(); | 127 AU.addRequired<TargetLibraryInfo>(); |
127 CallGraphSCCPass::getAnalysisUsage(AU); | 128 CallGraphSCCPass::getAnalysisUsage(AU); |
128 } | 129 } |
158 // write memory then they can't be marked readnone or readonly. | 159 // write memory then they can't be marked readnone or readonly. |
159 bool ReadsMemory = false; | 160 bool ReadsMemory = false; |
160 for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) { | 161 for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) { |
161 Function *F = (*I)->getFunction(); | 162 Function *F = (*I)->getFunction(); |
162 | 163 |
163 if (F == 0) | 164 if (!F || F->hasFnAttribute(Attribute::OptimizeNone)) |
164 // External node - may write memory. Just give up. | 165 // External node or node we don't want to optimize - assume it may write |
166 // memory and give up. | |
165 return false; | 167 return false; |
166 | 168 |
167 AliasAnalysis::ModRefBehavior MRB = AA->getModRefBehavior(F); | 169 AliasAnalysis::ModRefBehavior MRB = AA->getModRefBehavior(F); |
168 if (MRB == AliasAnalysis::DoesNotAccessMemory) | 170 if (MRB == AliasAnalysis::DoesNotAccessMemory) |
169 // Already perfect! | 171 // Already perfect! |
201 // ignore calls that only access local memory. | 203 // ignore calls that only access local memory. |
202 for (CallSite::arg_iterator CI = CS.arg_begin(), CE = CS.arg_end(); | 204 for (CallSite::arg_iterator CI = CS.arg_begin(), CE = CS.arg_end(); |
203 CI != CE; ++CI) { | 205 CI != CE; ++CI) { |
204 Value *Arg = *CI; | 206 Value *Arg = *CI; |
205 if (Arg->getType()->isPointerTy()) { | 207 if (Arg->getType()->isPointerTy()) { |
208 AAMDNodes AAInfo; | |
209 I->getAAMetadata(AAInfo); | |
210 | |
206 AliasAnalysis::Location Loc(Arg, | 211 AliasAnalysis::Location Loc(Arg, |
207 AliasAnalysis::UnknownSize, | 212 AliasAnalysis::UnknownSize, AAInfo); |
208 I->getMetadata(LLVMContext::MD_tbaa)); | |
209 if (!AA->pointsToConstantMemory(Loc, /*OrLocal=*/true)) { | 213 if (!AA->pointsToConstantMemory(Loc, /*OrLocal=*/true)) { |
210 if (MRB & AliasAnalysis::Mod) | 214 if (MRB & AliasAnalysis::Mod) |
211 // Writes non-local memory. Give up. | 215 // Writes non-local memory. Give up. |
212 return false; | 216 return false; |
213 if (MRB & AliasAnalysis::Ref) | 217 if (MRB & AliasAnalysis::Ref) |
317 // uses every node. Because the graph is directed and nothing points into | 321 // uses every node. Because the graph is directed and nothing points into |
318 // the root, it will not participate in any SCCs (except for its own). | 322 // the root, it will not participate in any SCCs (except for its own). |
319 ArgumentGraphNode SyntheticRoot; | 323 ArgumentGraphNode SyntheticRoot; |
320 | 324 |
321 public: | 325 public: |
322 ArgumentGraph() { SyntheticRoot.Definition = 0; } | 326 ArgumentGraph() { SyntheticRoot.Definition = nullptr; } |
323 | 327 |
324 typedef SmallVectorImpl<ArgumentGraphNode*>::iterator iterator; | 328 typedef SmallVectorImpl<ArgumentGraphNode*>::iterator iterator; |
325 | 329 |
326 iterator begin() { return SyntheticRoot.Uses.begin(); } | 330 iterator begin() { return SyntheticRoot.Uses.begin(); } |
327 iterator end() { return SyntheticRoot.Uses.end(); } | 331 iterator end() { return SyntheticRoot.Uses.end(); } |
340 // continuing with the analysis. | 344 // continuing with the analysis. |
341 struct ArgumentUsesTracker : public CaptureTracker { | 345 struct ArgumentUsesTracker : public CaptureTracker { |
342 ArgumentUsesTracker(const SmallPtrSet<Function*, 8> &SCCNodes) | 346 ArgumentUsesTracker(const SmallPtrSet<Function*, 8> &SCCNodes) |
343 : Captured(false), SCCNodes(SCCNodes) {} | 347 : Captured(false), SCCNodes(SCCNodes) {} |
344 | 348 |
345 void tooManyUses() { Captured = true; } | 349 void tooManyUses() override { Captured = true; } |
346 | 350 |
347 bool captured(Use *U) { | 351 bool captured(const Use *U) override { |
348 CallSite CS(U->getUser()); | 352 CallSite CS(U->getUser()); |
349 if (!CS.getInstruction()) { Captured = true; return true; } | 353 if (!CS.getInstruction()) { Captured = true; return true; } |
350 | 354 |
351 Function *F = CS.getCalledFunction(); | 355 Function *F = CS.getCalledFunction(); |
352 if (!F || !SCCNodes.count(F)) { Captured = true; return true; } | 356 if (!F || !SCCNodes.count(F)) { Captured = true; return true; } |
412 | 416 |
413 SmallVector<Use*, 32> Worklist; | 417 SmallVector<Use*, 32> Worklist; |
414 SmallSet<Use*, 32> Visited; | 418 SmallSet<Use*, 32> Visited; |
415 int Count = 0; | 419 int Count = 0; |
416 | 420 |
421 // inalloca arguments are always clobbered by the call. | |
422 if (A->hasInAllocaAttr()) | |
423 return Attribute::None; | |
424 | |
417 bool IsRead = false; | 425 bool IsRead = false; |
418 // We don't need to track IsWritten. If A is written to, return immediately. | 426 // We don't need to track IsWritten. If A is written to, return immediately. |
419 | 427 |
420 for (Value::use_iterator UI = A->use_begin(), UE = A->use_end(); | 428 for (Use &U : A->uses()) { |
421 UI != UE; ++UI) { | |
422 if (Count++ >= 20) | 429 if (Count++ >= 20) |
423 return Attribute::None; | 430 return Attribute::None; |
424 | 431 |
425 Use *U = &UI.getUse(); | 432 Visited.insert(&U); |
426 Visited.insert(U); | 433 Worklist.push_back(&U); |
427 Worklist.push_back(U); | |
428 } | 434 } |
429 | 435 |
430 while (!Worklist.empty()) { | 436 while (!Worklist.empty()) { |
431 Use *U = Worklist.pop_back_val(); | 437 Use *U = Worklist.pop_back_val(); |
432 Instruction *I = cast<Instruction>(U->getUser()); | 438 Instruction *I = cast<Instruction>(U->getUser()); |
435 switch (I->getOpcode()) { | 441 switch (I->getOpcode()) { |
436 case Instruction::BitCast: | 442 case Instruction::BitCast: |
437 case Instruction::GetElementPtr: | 443 case Instruction::GetElementPtr: |
438 case Instruction::PHI: | 444 case Instruction::PHI: |
439 case Instruction::Select: | 445 case Instruction::Select: |
446 case Instruction::AddrSpaceCast: | |
440 // The original value is not read/written via this if the new value isn't. | 447 // The original value is not read/written via this if the new value isn't. |
441 for (Instruction::use_iterator UI = I->use_begin(), UE = I->use_end(); | 448 for (Use &UU : I->uses()) |
442 UI != UE; ++UI) { | 449 if (Visited.insert(&UU)) |
443 Use *U = &UI.getUse(); | 450 Worklist.push_back(&UU); |
444 if (Visited.insert(U)) | |
445 Worklist.push_back(U); | |
446 } | |
447 break; | 451 break; |
448 | 452 |
449 case Instruction::Call: | 453 case Instruction::Call: |
450 case Instruction::Invoke: { | 454 case Instruction::Invoke: { |
455 bool Captures = true; | |
456 | |
457 if (I->getType()->isVoidTy()) | |
458 Captures = false; | |
459 | |
460 auto AddUsersToWorklistIfCapturing = [&] { | |
461 if (Captures) | |
462 for (Use &UU : I->uses()) | |
463 if (Visited.insert(&UU)) | |
464 Worklist.push_back(&UU); | |
465 }; | |
466 | |
451 CallSite CS(I); | 467 CallSite CS(I); |
452 if (CS.doesNotAccessMemory()) | 468 if (CS.doesNotAccessMemory()) { |
469 AddUsersToWorklistIfCapturing(); | |
453 continue; | 470 continue; |
471 } | |
454 | 472 |
455 Function *F = CS.getCalledFunction(); | 473 Function *F = CS.getCalledFunction(); |
456 if (!F) { | 474 if (!F) { |
457 if (CS.onlyReadsMemory()) { | 475 if (CS.onlyReadsMemory()) { |
458 IsRead = true; | 476 IsRead = true; |
477 AddUsersToWorklistIfCapturing(); | |
459 continue; | 478 continue; |
460 } | 479 } |
461 return Attribute::None; | 480 return Attribute::None; |
462 } | 481 } |
463 | 482 |
468 if (AI == AE) { | 487 if (AI == AE) { |
469 assert(F->isVarArg() && | 488 assert(F->isVarArg() && |
470 "More params than args in non-varargs call."); | 489 "More params than args in non-varargs call."); |
471 return Attribute::None; | 490 return Attribute::None; |
472 } | 491 } |
492 Captures &= !CS.doesNotCapture(A - B); | |
473 if (SCCNodes.count(AI)) | 493 if (SCCNodes.count(AI)) |
474 continue; | 494 continue; |
475 if (!CS.onlyReadsMemory() && !CS.onlyReadsMemory(A - B)) | 495 if (!CS.onlyReadsMemory() && !CS.onlyReadsMemory(A - B)) |
476 return Attribute::None; | 496 return Attribute::None; |
477 if (!CS.doesNotAccessMemory(A - B)) | 497 if (!CS.doesNotAccessMemory(A - B)) |
478 IsRead = true; | 498 IsRead = true; |
479 } | 499 } |
480 } | 500 } |
501 AddUsersToWorklistIfCapturing(); | |
481 break; | 502 break; |
482 } | 503 } |
483 | 504 |
484 case Instruction::Load: | 505 case Instruction::Load: |
485 IsRead = true; | 506 IsRead = true; |
505 | 526 |
506 // Fill SCCNodes with the elements of the SCC. Used for quickly | 527 // Fill SCCNodes with the elements of the SCC. Used for quickly |
507 // looking up whether a given CallGraphNode is in this SCC. | 528 // looking up whether a given CallGraphNode is in this SCC. |
508 for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) { | 529 for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) { |
509 Function *F = (*I)->getFunction(); | 530 Function *F = (*I)->getFunction(); |
510 if (F && !F->isDeclaration() && !F->mayBeOverridden()) | 531 if (F && !F->isDeclaration() && !F->mayBeOverridden() && |
532 !F->hasFnAttribute(Attribute::OptimizeNone)) | |
511 SCCNodes.insert(F); | 533 SCCNodes.insert(F); |
512 } | 534 } |
513 | 535 |
514 ArgumentGraph AG; | 536 ArgumentGraph AG; |
515 | 537 |
519 // Check each function in turn, determining which pointer arguments are not | 541 // Check each function in turn, determining which pointer arguments are not |
520 // captured. | 542 // captured. |
521 for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) { | 543 for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) { |
522 Function *F = (*I)->getFunction(); | 544 Function *F = (*I)->getFunction(); |
523 | 545 |
524 if (F == 0) | 546 if (!F || F->hasFnAttribute(Attribute::OptimizeNone)) |
525 // External node - only a problem for arguments that we pass to it. | 547 // External node or function we're trying not to optimize - only a problem |
548 // for arguments that we pass to it. | |
526 continue; | 549 continue; |
527 | 550 |
528 // Definitions with weak linkage may be overridden at linktime with | 551 // Definitions with weak linkage may be overridden at linktime with |
529 // something that captures pointers, so treat them like declarations. | 552 // something that captures pointers, so treat them like declarations. |
530 if (F->isDeclaration() || F->mayBeOverridden()) | 553 if (F->isDeclaration() || F->mayBeOverridden()) |
597 // show up as ArgumentGraphNode objects with an empty Uses list, and for | 620 // show up as ArgumentGraphNode objects with an empty Uses list, and for |
598 // these nodes the final decision about whether they capture has already been | 621 // these nodes the final decision about whether they capture has already been |
599 // made. If the definition doesn't have a 'nocapture' attribute by now, it | 622 // made. If the definition doesn't have a 'nocapture' attribute by now, it |
600 // captures. | 623 // captures. |
601 | 624 |
602 for (scc_iterator<ArgumentGraph*> I = scc_begin(&AG), E = scc_end(&AG); | 625 for (scc_iterator<ArgumentGraph*> I = scc_begin(&AG); !I.isAtEnd(); ++I) { |
603 I != E; ++I) { | 626 const std::vector<ArgumentGraphNode *> &ArgumentSCC = *I; |
604 std::vector<ArgumentGraphNode*> &ArgumentSCC = *I; | |
605 if (ArgumentSCC.size() == 1) { | 627 if (ArgumentSCC.size() == 1) { |
606 if (!ArgumentSCC[0]->Definition) continue; // synthetic root node | 628 if (!ArgumentSCC[0]->Definition) continue; // synthetic root node |
607 | 629 |
608 // eg. "void f(int* x) { if (...) f(x); }" | 630 // eg. "void f(int* x) { if (...) f(x); }" |
609 if (ArgumentSCC[0]->Uses.size() == 1 && | 631 if (ArgumentSCC[0]->Uses.size() == 1 && |
615 } | 637 } |
616 continue; | 638 continue; |
617 } | 639 } |
618 | 640 |
619 bool SCCCaptured = false; | 641 bool SCCCaptured = false; |
620 for (std::vector<ArgumentGraphNode*>::iterator I = ArgumentSCC.begin(), | 642 for (auto I = ArgumentSCC.begin(), E = ArgumentSCC.end(); |
621 E = ArgumentSCC.end(); I != E && !SCCCaptured; ++I) { | 643 I != E && !SCCCaptured; ++I) { |
622 ArgumentGraphNode *Node = *I; | 644 ArgumentGraphNode *Node = *I; |
623 if (Node->Uses.empty()) { | 645 if (Node->Uses.empty()) { |
624 if (!Node->Definition->hasNoCaptureAttr()) | 646 if (!Node->Definition->hasNoCaptureAttr()) |
625 SCCCaptured = true; | 647 SCCCaptured = true; |
626 } | 648 } |
628 if (SCCCaptured) continue; | 650 if (SCCCaptured) continue; |
629 | 651 |
630 SmallPtrSet<Argument*, 8> ArgumentSCCNodes; | 652 SmallPtrSet<Argument*, 8> ArgumentSCCNodes; |
631 // Fill ArgumentSCCNodes with the elements of the ArgumentSCC. Used for | 653 // Fill ArgumentSCCNodes with the elements of the ArgumentSCC. Used for |
632 // quickly looking up whether a given Argument is in this ArgumentSCC. | 654 // quickly looking up whether a given Argument is in this ArgumentSCC. |
633 for (std::vector<ArgumentGraphNode*>::iterator I = ArgumentSCC.begin(), | 655 for (auto I = ArgumentSCC.begin(), E = ArgumentSCC.end(); I != E; ++I) { |
634 E = ArgumentSCC.end(); I != E; ++I) { | |
635 ArgumentSCCNodes.insert((*I)->Definition); | 656 ArgumentSCCNodes.insert((*I)->Definition); |
636 } | 657 } |
637 | 658 |
638 for (std::vector<ArgumentGraphNode*>::iterator I = ArgumentSCC.begin(), | 659 for (auto I = ArgumentSCC.begin(), E = ArgumentSCC.end(); |
639 E = ArgumentSCC.end(); I != E && !SCCCaptured; ++I) { | 660 I != E && !SCCCaptured; ++I) { |
640 ArgumentGraphNode *N = *I; | 661 ArgumentGraphNode *N = *I; |
641 for (SmallVectorImpl<ArgumentGraphNode*>::iterator UI = N->Uses.begin(), | 662 for (SmallVectorImpl<ArgumentGraphNode*>::iterator UI = N->Uses.begin(), |
642 UE = N->Uses.end(); UI != UE; ++UI) { | 663 UE = N->Uses.end(); UI != UE; ++UI) { |
643 Argument *A = (*UI)->Definition; | 664 Argument *A = (*UI)->Definition; |
644 if (A->hasNoCaptureAttr() || ArgumentSCCNodes.count(A)) | 665 if (A->hasNoCaptureAttr() || ArgumentSCCNodes.count(A)) |
721 if (Instruction *RVI = dyn_cast<Instruction>(RetVal)) | 742 if (Instruction *RVI = dyn_cast<Instruction>(RetVal)) |
722 switch (RVI->getOpcode()) { | 743 switch (RVI->getOpcode()) { |
723 // Extend the analysis by looking upwards. | 744 // Extend the analysis by looking upwards. |
724 case Instruction::BitCast: | 745 case Instruction::BitCast: |
725 case Instruction::GetElementPtr: | 746 case Instruction::GetElementPtr: |
747 case Instruction::AddrSpaceCast: | |
726 FlowsToReturn.insert(RVI->getOperand(0)); | 748 FlowsToReturn.insert(RVI->getOperand(0)); |
727 continue; | 749 continue; |
728 case Instruction::Select: { | 750 case Instruction::Select: { |
729 SelectInst *SI = cast<SelectInst>(RVI); | 751 SelectInst *SI = cast<SelectInst>(RVI); |
730 FlowsToReturn.insert(SI->getTrueValue()); | 752 FlowsToReturn.insert(SI->getTrueValue()); |
773 // Check each function in turn, determining which functions return noalias | 795 // Check each function in turn, determining which functions return noalias |
774 // pointers. | 796 // pointers. |
775 for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) { | 797 for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) { |
776 Function *F = (*I)->getFunction(); | 798 Function *F = (*I)->getFunction(); |
777 | 799 |
778 if (F == 0) | 800 if (!F || F->hasFnAttribute(Attribute::OptimizeNone)) |
779 // External node - skip it; | 801 // External node or node we don't want to optimize - skip it; |
780 return false; | 802 return false; |
781 | 803 |
782 // Already noalias. | 804 // Already noalias. |
783 if (F->doesNotAlias(0)) | 805 if (F->doesNotAlias(0)) |
784 continue; | 806 continue; |
813 | 835 |
814 /// inferPrototypeAttributes - Analyze the name and prototype of the | 836 /// inferPrototypeAttributes - Analyze the name and prototype of the |
815 /// given function and set any applicable attributes. Returns true | 837 /// given function and set any applicable attributes. Returns true |
816 /// if any attributes were set and false otherwise. | 838 /// if any attributes were set and false otherwise. |
817 bool FunctionAttrs::inferPrototypeAttributes(Function &F) { | 839 bool FunctionAttrs::inferPrototypeAttributes(Function &F) { |
840 if (F.hasFnAttribute(Attribute::OptimizeNone)) | |
841 return false; | |
842 | |
818 FunctionType *FTy = F.getFunctionType(); | 843 FunctionType *FTy = F.getFunctionType(); |
819 LibFunc::Func TheLibFunc; | 844 LibFunc::Func TheLibFunc; |
820 if (!(TLI->getLibFunc(F.getName(), TheLibFunc) && TLI->has(TheLibFunc))) | 845 if (!(TLI->getLibFunc(F.getName(), TheLibFunc) && TLI->has(TheLibFunc))) |
821 return false; | 846 return false; |
822 | 847 |
1647 // gettimeofday. To be conservative, do not add noalias to gettimeofday's | 1672 // gettimeofday. To be conservative, do not add noalias to gettimeofday's |
1648 // arguments. | 1673 // arguments. |
1649 setDoesNotThrow(F); | 1674 setDoesNotThrow(F); |
1650 setDoesNotCapture(F, 1); | 1675 setDoesNotCapture(F, 1); |
1651 setDoesNotCapture(F, 2); | 1676 setDoesNotCapture(F, 2); |
1677 break; | |
1652 default: | 1678 default: |
1653 // Didn't mark any attributes. | 1679 // Didn't mark any attributes. |
1654 return false; | 1680 return false; |
1655 } | 1681 } |
1656 | 1682 |
1665 // Check each function in turn annotating well-known library function | 1691 // Check each function in turn annotating well-known library function |
1666 // declarations with attributes. | 1692 // declarations with attributes. |
1667 for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) { | 1693 for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) { |
1668 Function *F = (*I)->getFunction(); | 1694 Function *F = (*I)->getFunction(); |
1669 | 1695 |
1670 if (F != 0 && F->isDeclaration()) | 1696 if (F && F->isDeclaration()) |
1671 MadeChange |= inferPrototypeAttributes(*F); | 1697 MadeChange |= inferPrototypeAttributes(*F); |
1672 } | 1698 } |
1673 | 1699 |
1674 return MadeChange; | 1700 return MadeChange; |
1675 } | 1701 } |