From d37ec47374bf5c4ab3e443be1fe208f459afc696 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 15 Aug 2014 15:46:38 +0000 Subject: [PATCH] Introduce a helper to combine instruction metadata. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the old code in GVN and BBVectorize with it. Update SimplifyCFG to use it. Patch by Björn Steinbrink! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215723 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Transforms/Utils/Local.h | 5 ++ lib/Transforms/Scalar/GVN.cpp | 60 +++++++----------------- lib/Transforms/Utils/Local.cpp | 36 ++++++++++++++ lib/Transforms/Utils/SimplifyCFG.cpp | 8 ++++ lib/Transforms/Vectorize/BBVectorize.cpp | 39 +++------------ 5 files changed, 74 insertions(+), 74 deletions(-) diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h index c0c690664a9..81018598099 100644 --- a/include/llvm/Transforms/Utils/Local.h +++ b/include/llvm/Transforms/Utils/Local.h @@ -275,6 +275,11 @@ bool replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress, /// Returns true if any basic block was removed. bool removeUnreachableBlocks(Function &F); +/// \brief Combine the metadata of two instructions so that K can replace J +/// +/// Metadata not listed as known via KnownIDs is removed +void combineMetadata(Instruction *K, const Instruction *J, ArrayRef KnownIDs); + } // End llvm namespace #endif diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index 07be4955cb4..a1fb7e9a65c 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/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 using namespace llvm; @@ -1776,49 +1777,24 @@ static void patchReplacementInstruction(Instruction *I, Value *Repl) { ReplOp->setHasNoUnsignedWrap(false); } if (Instruction *ReplInst = dyn_cast(Repl)) { - SmallVector, 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. + // 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. - 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; - } - } + // 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); } } diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp index d891fc0ee1c..9b451449da9 100644 --- a/lib/Transforms/Utils/Local.cpp +++ b/lib/Transforms/Utils/Local.cpp @@ -1305,3 +1305,39 @@ bool llvm::removeUnreachableBlocks(Function &F) { return true; } + +void llvm::combineMetadata(Instruction *K, const Instruction *J, ArrayRef KnownIDs) { + SmallVector, 4> Metadata; + K->dropUnknownMetadata(KnownIDs); + K->getAllMetadataOtherThanDebugLoc(Metadata); + for (unsigned i = 0, n = Metadata.size(); i < n; ++i) { + unsigned Kind = Metadata[i].first; + MDNode *JMD = J->getMetadata(Kind); + MDNode *KMD = Metadata[i].second; + + switch (Kind) { + default: + K->setMetadata(Kind, nullptr); // Remove unknown metadata + break; + case LLVMContext::MD_dbg: + llvm_unreachable("getAllMetadataOtherThanDebugLoc returned a MD_dbg"); + case LLVMContext::MD_tbaa: + K->setMetadata(Kind, MDNode::getMostGenericTBAA(JMD, KMD)); + break; + case LLVMContext::MD_alias_scope: + case LLVMContext::MD_noalias: + K->setMetadata(Kind, MDNode::intersect(JMD, KMD)); + break; + case LLVMContext::MD_range: + K->setMetadata(Kind, MDNode::getMostGenericRange(JMD, KMD)); + break; + case LLVMContext::MD_fpmath: + K->setMetadata(Kind, MDNode::getMostGenericFPMath(JMD, KMD)); + break; + case LLVMContext::MD_invariant_load: + // Only set the !invariant.load if it is present in both instructions. + K->setMetadata(Kind, JMD); + break; + } + } +} diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp index 63cb1c9abbf..cc3fbb19a6e 100644 --- a/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/lib/Transforms/Utils/SimplifyCFG.cpp @@ -43,6 +43,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" +#include "llvm/Transforms/Utils/Local.h" #include #include #include @@ -1040,6 +1041,13 @@ static bool HoistThenElseCodeToIf(BranchInst *BI, const DataLayout *DL) { if (!I2->use_empty()) I2->replaceAllUsesWith(I1); I1->intersectOptionalDataWith(I2); + unsigned KnownIDs[] = { + LLVMContext::MD_tbaa, + LLVMContext::MD_range, + LLVMContext::MD_fpmath, + LLVMContext::MD_invariant_load + }; + combineMetadata(I1, I2, KnownIDs); I2->eraseFromParent(); Changed = true; diff --git a/lib/Transforms/Vectorize/BBVectorize.cpp b/lib/Transforms/Vectorize/BBVectorize.cpp index 9ee0ffb03bb..50c3fa41b1d 100644 --- a/lib/Transforms/Vectorize/BBVectorize.cpp +++ b/lib/Transforms/Vectorize/BBVectorize.cpp @@ -391,8 +391,6 @@ namespace { Instruction *&InsertionPt, Instruction *I, Instruction *J); - void combineMetadata(Instruction *K, const Instruction *J); - bool vectorizeBB(BasicBlock &BB) { if (skipOptnoneFunction(BB)) return false; @@ -2964,35 +2962,6 @@ namespace { } } - // When the first instruction in each pair is cloned, it will inherit its - // parent's metadata. This metadata must be combined with that of the other - // instruction in a safe way. - void BBVectorize::combineMetadata(Instruction *K, const Instruction *J) { - SmallVector, 4> Metadata; - K->getAllMetadataOtherThanDebugLoc(Metadata); - for (unsigned i = 0, n = Metadata.size(); i < n; ++i) { - unsigned Kind = Metadata[i].first; - MDNode *JMD = J->getMetadata(Kind); - MDNode *KMD = Metadata[i].second; - - switch (Kind) { - default: - K->setMetadata(Kind, nullptr); // Remove unknown metadata - break; - case LLVMContext::MD_tbaa: - K->setMetadata(Kind, MDNode::getMostGenericTBAA(JMD, KMD)); - break; - case LLVMContext::MD_alias_scope: - case LLVMContext::MD_noalias: - K->setMetadata(Kind, MDNode::intersect(JMD, KMD)); - break; - case LLVMContext::MD_fpmath: - K->setMetadata(Kind, MDNode::getMostGenericFPMath(JMD, KMD)); - break; - } - } - } - // This function fuses the chosen instruction pairs into vector instructions, // taking care preserve any needed scalar outputs and, then, it reorders the // remaining instructions as needed (users of the first member of the pair @@ -3142,7 +3111,13 @@ namespace { if (!isa(K)) K->mutateType(getVecTypeForPair(L->getType(), H->getType())); - combineMetadata(K, H); + unsigned KnownIDs[] = { + LLVMContext::MD_tbaa, + LLVMContext::MD_alias_scope, + LLVMContext::MD_noalias, + LLVMContext::MD_fpmath + }; + combineMetadata(K, H, KnownIDs); K->intersectOptionalDataWith(H); for (unsigned o = 0; o < NumOperands; ++o)