mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-23 20:45:06 +00:00
Introduce a helper to combine instruction metadata.
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
This commit is contained in:
parent
f36437d945
commit
d37ec47374
@ -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<unsigned> KnownIDs);
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
|
@ -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.
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1305,3 +1305,39 @@ bool llvm::removeUnreachableBlocks(Function &F) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void llvm::combineMetadata(Instruction *K, const Instruction *J, ArrayRef<unsigned> KnownIDs) {
|
||||
SmallVector<std::pair<unsigned, MDNode*>, 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 <algorithm>
|
||||
#include <map>
|
||||
#include <set>
|
||||
@ -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;
|
||||
|
||||
|
@ -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<std::pair<unsigned, MDNode*>, 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<StoreInst>(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)
|
||||
|
Loading…
Reference in New Issue
Block a user