Mercurial > hg > Members > tobaru > cbc > CbC_llvm
comparison lib/Analysis/GlobalsModRef.cpp @ 121:803732b1fca8
LLVM 5.0
author | kono |
---|---|
date | Fri, 27 Oct 2017 17:07:41 +0900 |
parents | 1172e4bd9c6f |
children |
comparison
equal
deleted
inserted
replaced
120:1172e4bd9c6f | 121:803732b1fca8 |
---|---|
473 // visit all callees before callers (leaf-first). | 473 // visit all callees before callers (leaf-first). |
474 for (scc_iterator<CallGraph *> I = scc_begin(&CG); !I.isAtEnd(); ++I) { | 474 for (scc_iterator<CallGraph *> I = scc_begin(&CG); !I.isAtEnd(); ++I) { |
475 const std::vector<CallGraphNode *> &SCC = *I; | 475 const std::vector<CallGraphNode *> &SCC = *I; |
476 assert(!SCC.empty() && "SCC with no functions?"); | 476 assert(!SCC.empty() && "SCC with no functions?"); |
477 | 477 |
478 if (!SCC[0]->getFunction() || !SCC[0]->getFunction()->isDefinitionExact()) { | 478 Function *F = SCC[0]->getFunction(); |
479 | |
480 if (!F || !F->isDefinitionExact()) { | |
479 // Calls externally or not exact - can't say anything useful. Remove any | 481 // Calls externally or not exact - can't say anything useful. Remove any |
480 // existing function records (may have been created when scanning | 482 // existing function records (may have been created when scanning |
481 // globals). | 483 // globals). |
482 for (auto *Node : SCC) | 484 for (auto *Node : SCC) |
483 FunctionInfos.erase(Node->getFunction()); | 485 FunctionInfos.erase(Node->getFunction()); |
484 continue; | 486 continue; |
485 } | 487 } |
486 | 488 |
487 FunctionInfo &FI = FunctionInfos[SCC[0]->getFunction()]; | 489 FunctionInfo &FI = FunctionInfos[F]; |
488 bool KnowNothing = false; | 490 bool KnowNothing = false; |
489 | 491 |
490 // Collect the mod/ref properties due to called functions. We only compute | 492 // Collect the mod/ref properties due to called functions. We only compute |
491 // one mod-ref set. | 493 // one mod-ref set. |
492 for (unsigned i = 0, e = SCC.size(); i != e && !KnowNothing; ++i) { | 494 for (unsigned i = 0, e = SCC.size(); i != e && !KnowNothing; ++i) { |
493 Function *F = SCC[i]->getFunction(); | |
494 if (!F) { | 495 if (!F) { |
495 KnowNothing = true; | 496 KnowNothing = true; |
496 break; | 497 break; |
497 } | 498 } |
498 | 499 |
499 if (F->isDeclaration()) { | 500 if (F->isDeclaration() || F->hasFnAttribute(Attribute::OptimizeNone)) { |
500 // Try to get mod/ref behaviour from function attributes. | 501 // Try to get mod/ref behaviour from function attributes. |
501 if (F->doesNotAccessMemory()) { | 502 if (F->doesNotAccessMemory()) { |
502 // Can't do better than that! | 503 // Can't do better than that! |
503 } else if (F->onlyReadsMemory()) { | 504 } else if (F->onlyReadsMemory()) { |
504 FI.addModRefInfo(MRI_Ref); | 505 FI.addModRefInfo(MRI_Ref); |
543 | 544 |
544 // Scan the function bodies for explicit loads or stores. | 545 // Scan the function bodies for explicit loads or stores. |
545 for (auto *Node : SCC) { | 546 for (auto *Node : SCC) { |
546 if (FI.getModRefInfo() == MRI_ModRef) | 547 if (FI.getModRefInfo() == MRI_ModRef) |
547 break; // The mod/ref lattice saturates here. | 548 break; // The mod/ref lattice saturates here. |
549 | |
550 // Don't prove any properties based on the implementation of an optnone | |
551 // function. Function attributes were already used as a best approximation | |
552 // above. | |
553 if (Node->getFunction()->hasFnAttribute(Attribute::OptimizeNone)) | |
554 continue; | |
555 | |
548 for (Instruction &I : instructions(Node->getFunction())) { | 556 for (Instruction &I : instructions(Node->getFunction())) { |
549 if (FI.getModRefInfo() == MRI_ModRef) | 557 if (FI.getModRefInfo() == MRI_ModRef) |
550 break; // The mod/ref lattice saturates here. | 558 break; // The mod/ref lattice saturates here. |
551 | 559 |
552 // We handle calls specially because the graph-relevant aspects are | 560 // We handle calls specially because the graph-relevant aspects are |