diff options
Diffstat (limited to 'llvm/lib/Transforms/Scalar/GVN.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/GVN.cpp | 62 |
1 files changed, 19 insertions, 43 deletions
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp index 07be4955cb4..a1fb7e9a65c 100644 --- a/llvm/lib/Transforms/Scalar/GVN.cpp +++ b/llvm/lib/Transforms/Scalar/GVN.cpp @@ -45,6 +45,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Target/TargetLibraryInfo.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" +#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/SSAUpdater.h" #include <vector> using namespace llvm; @@ -1776,49 +1777,24 @@ static void patchReplacementInstruction(Instruction *I, Value *Repl) { ReplOp->setHasNoUnsignedWrap(false); } if (Instruction *ReplInst = dyn_cast<Instruction>(Repl)) { - SmallVector<std::pair<unsigned, MDNode*>, 4> Metadata; - ReplInst->getAllMetadataOtherThanDebugLoc(Metadata); - for (int i = 0, n = Metadata.size(); i < n; ++i) { - unsigned Kind = Metadata[i].first; - MDNode *IMD = I->getMetadata(Kind); - MDNode *ReplMD = Metadata[i].second; - switch(Kind) { - default: - ReplInst->setMetadata(Kind, nullptr); // Remove unknown metadata - break; - case LLVMContext::MD_dbg: - llvm_unreachable("getAllMetadataOtherThanDebugLoc returned a MD_dbg"); - case LLVMContext::MD_tbaa: - ReplInst->setMetadata(Kind, MDNode::getMostGenericTBAA(IMD, ReplMD)); - break; - case LLVMContext::MD_alias_scope: - case LLVMContext::MD_noalias: - // FIXME: If both the original and replacement value are part of the - // same control-flow region (meaning that the execution of one - // guarentees the executation of the other), then we can combine the - // noalias scopes here and do better than the general conservative - // answer. - - // In general, GVN unifies expressions over different control-flow - // regions, and so we need a conservative combination of the noalias - // scopes. - ReplInst->setMetadata(Kind, MDNode::intersect(IMD, ReplMD)); - break; - case LLVMContext::MD_range: - ReplInst->setMetadata(Kind, MDNode::getMostGenericRange(IMD, ReplMD)); - break; - case LLVMContext::MD_prof: - llvm_unreachable("MD_prof in a non-terminator instruction"); - break; - case LLVMContext::MD_fpmath: - ReplInst->setMetadata(Kind, MDNode::getMostGenericFPMath(IMD, ReplMD)); - break; - case LLVMContext::MD_invariant_load: - // Only set the !invariant.load if it is present in both instructions. - ReplInst->setMetadata(Kind, IMD); - break; - } - } + // FIXME: If both the original and replacement value are part of the + // same control-flow region (meaning that the execution of one + // guarentees the executation of the other), then we can combine the + // noalias scopes here and do better than the general conservative + // answer used in combineMetadata(). + + // In general, GVN unifies expressions over different control-flow + // regions, and so we need a conservative combination of the noalias + // scopes. + unsigned KnownIDs[] = { + LLVMContext::MD_tbaa, + LLVMContext::MD_alias_scope, + LLVMContext::MD_noalias, + LLVMContext::MD_range, + LLVMContext::MD_fpmath, + LLVMContext::MD_invariant_load, + }; + combineMetadata(ReplInst, I, KnownIDs); } } |