diff options
Diffstat (limited to 'llvm/lib/Transforms/Utils/Local.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/Local.cpp | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index e285f8a..89e62fb 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -3392,3 +3392,33 @@ Value *llvm::invertCondition(Value *Condition) { Inverted->insertBefore(&*Parent->getFirstInsertionPt()); return Inverted; } + +bool llvm::inferAttributesFromOthers(Function &F) { + // Note: We explicitly check for attributes rather than using cover functions + // because some of the cover functions include the logic being implemented. + + bool Changed = false; + // readnone + not convergent implies nosync + if (!F.hasFnAttribute(Attribute::NoSync) && + F.doesNotAccessMemory() && !F.isConvergent()) { + F.setNoSync(); + Changed = true; + } + + // readonly implies nofree + if (!F.hasFnAttribute(Attribute::NoFree) && F.onlyReadsMemory()) { + F.setDoesNotFreeMemory(); + Changed = true; + } + + // willreturn implies mustprogress + if (!F.hasFnAttribute(Attribute::MustProgress) && F.willReturn()) { + F.setMustProgress(); + Changed = true; + } + + // TODO: There are a bunch of cases of restrictive memory effects we + // can infer by inspecting arguments of argmemonly-ish functions. + + return Changed; +} |