summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Utils
diff options
context:
space:
mode:
authorPiotr Padlewski <prazek@google.com>2015-10-02 22:12:22 +0000
committerPiotr Padlewski <prazek@google.com>2015-10-02 22:12:22 +0000
commitdc9b2cfc5013684456ec7d632eaa2edf7c030f2b (patch)
treeaedc153caf7a87e8ddb930b4974f389663f9b1cc /llvm/lib/Transforms/Utils
parent1f31a2c11c1aa56431c43bfe62f8465635801058 (diff)
downloadbcm5719-llvm-dc9b2cfc5013684456ec7d632eaa2edf7c030f2b.tar.gz
bcm5719-llvm-dc9b2cfc5013684456ec7d632eaa2edf7c030f2b.zip
inariant.group handling in GVN
The most important part required to make clang devirtualization works ( ͡°͜ʖ ͡°). The code is able to find non local dependencies, but unfortunatelly because the caller can only handle local dependencies, I had to add some restrictions to look for dependencies only in the same BB. http://reviews.llvm.org/D12992 llvm-svn: 249196
Diffstat (limited to 'llvm/lib/Transforms/Utils')
-rw-r--r--llvm/lib/Transforms/Utils/Local.cpp15
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyCFG.cpp9
2 files changed, 17 insertions, 7 deletions
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index 1a74544045c..5be5a7df26b 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1386,7 +1386,8 @@ bool llvm::removeUnreachableBlocks(Function &F) {
return true;
}
-void llvm::combineMetadata(Instruction *K, const Instruction *J, ArrayRef<unsigned> KnownIDs) {
+void llvm::combineMetadata(Instruction *K, const Instruction *J,
+ ArrayRef<unsigned> KnownIDs) {
SmallVector<std::pair<unsigned, MDNode *>, 4> Metadata;
K->dropUnknownNonDebugMetadata(KnownIDs);
K->getAllMetadataOtherThanDebugLoc(Metadata);
@@ -1424,8 +1425,20 @@ void llvm::combineMetadata(Instruction *K, const Instruction *J, ArrayRef<unsign
// Only set the !nonnull if it is present in both instructions.
K->setMetadata(Kind, JMD);
break;
+ case LLVMContext::MD_invariant_group:
+ // Preserve !invariant.group in K.
+ break;
}
}
+ // Set !invariant.group from J if J has it. If both instructions have it
+ // then we will just pick it from J - even when they are different.
+ // Also make sure that K is load or store - f.e. combining bitcast with load
+ // could produce bitcast with invariant.group metadata, which is invalid.
+ // FIXME: we should try to preserve both invariant.group md if they are
+ // different, but right now instruction can only have one invariant.group.
+ if (auto *JMD = J->getMetadata(LLVMContext::MD_invariant_group))
+ if (isa<LoadInst>(K) || isa<StoreInst>(K))
+ K->setMetadata(LLVMContext::MD_invariant_group, JMD);
}
unsigned llvm::replaceDominatedUsesWith(Value *From, Value *To,
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 403356931ca..e2bd46e85c3 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -1095,12 +1095,9 @@ static bool HoistThenElseCodeToIf(BranchInst *BI,
I2->replaceAllUsesWith(I1);
I1->intersectOptionalDataWith(I2);
unsigned KnownIDs[] = {
- LLVMContext::MD_tbaa,
- LLVMContext::MD_range,
- LLVMContext::MD_fpmath,
- LLVMContext::MD_invariant_load,
- LLVMContext::MD_nonnull
- };
+ LLVMContext::MD_tbaa, LLVMContext::MD_range,
+ LLVMContext::MD_fpmath, LLVMContext::MD_invariant_load,
+ LLVMContext::MD_nonnull, LLVMContext::MD_invariant_group};
combineMetadata(I1, I2, KnownIDs);
I2->eraseFromParent();
Changed = true;
OpenPOWER on IntegriCloud