aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/Local.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/Utils/Local.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/Local.cpp30
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;
+}