forked from OSchip/llvm-project
[Transforms] move copying of load metadata to helper function; NFC
There's another proposed load combine that can make use of this code in D64432. llvm-svn: 366949
This commit is contained in:
parent
87186b2447
commit
86e9f9dc26
|
@ -427,6 +427,10 @@ void combineMetadata(Instruction *K, const Instruction *J,
|
||||||
void combineMetadataForCSE(Instruction *K, const Instruction *J,
|
void combineMetadataForCSE(Instruction *K, const Instruction *J,
|
||||||
bool DoesKMove);
|
bool DoesKMove);
|
||||||
|
|
||||||
|
/// Copy the metadata from the source instruction to the destination (the
|
||||||
|
/// replacement for the source instruction).
|
||||||
|
void copyMetadataForLoad(LoadInst &Dest, const LoadInst &Source);
|
||||||
|
|
||||||
/// Patch the replacement so that it is not more restrictive than the value
|
/// Patch the replacement so that it is not more restrictive than the value
|
||||||
/// being replaced. It assumes that the replacement does not get moved from
|
/// being replaced. It assumes that the replacement does not get moved from
|
||||||
/// its original position.
|
/// its original position.
|
||||||
|
|
|
@ -455,9 +455,6 @@ static LoadInst *combineLoadToNewType(InstCombiner &IC, LoadInst &LI, Type *NewT
|
||||||
|
|
||||||
Value *Ptr = LI.getPointerOperand();
|
Value *Ptr = LI.getPointerOperand();
|
||||||
unsigned AS = LI.getPointerAddressSpace();
|
unsigned AS = LI.getPointerAddressSpace();
|
||||||
SmallVector<std::pair<unsigned, MDNode *>, 8> MD;
|
|
||||||
LI.getAllMetadata(MD);
|
|
||||||
|
|
||||||
Value *NewPtr = nullptr;
|
Value *NewPtr = nullptr;
|
||||||
if (!(match(Ptr, m_BitCast(m_Value(NewPtr))) &&
|
if (!(match(Ptr, m_BitCast(m_Value(NewPtr))) &&
|
||||||
NewPtr->getType()->getPointerElementType() == NewTy &&
|
NewPtr->getType()->getPointerElementType() == NewTy &&
|
||||||
|
@ -467,48 +464,7 @@ static LoadInst *combineLoadToNewType(InstCombiner &IC, LoadInst &LI, Type *NewT
|
||||||
LoadInst *NewLoad = IC.Builder.CreateAlignedLoad(
|
LoadInst *NewLoad = IC.Builder.CreateAlignedLoad(
|
||||||
NewTy, NewPtr, LI.getAlignment(), LI.isVolatile(), LI.getName() + Suffix);
|
NewTy, NewPtr, LI.getAlignment(), LI.isVolatile(), LI.getName() + Suffix);
|
||||||
NewLoad->setAtomic(LI.getOrdering(), LI.getSyncScopeID());
|
NewLoad->setAtomic(LI.getOrdering(), LI.getSyncScopeID());
|
||||||
MDBuilder MDB(NewLoad->getContext());
|
copyMetadataForLoad(*NewLoad, LI);
|
||||||
for (const auto &MDPair : MD) {
|
|
||||||
unsigned ID = MDPair.first;
|
|
||||||
MDNode *N = MDPair.second;
|
|
||||||
// Note, essentially every kind of metadata should be preserved here! This
|
|
||||||
// routine is supposed to clone a load instruction changing *only its type*.
|
|
||||||
// The only metadata it makes sense to drop is metadata which is invalidated
|
|
||||||
// when the pointer type changes. This should essentially never be the case
|
|
||||||
// in LLVM, but we explicitly switch over only known metadata to be
|
|
||||||
// conservatively correct. If you are adding metadata to LLVM which pertains
|
|
||||||
// to loads, you almost certainly want to add it here.
|
|
||||||
switch (ID) {
|
|
||||||
case LLVMContext::MD_dbg:
|
|
||||||
case LLVMContext::MD_tbaa:
|
|
||||||
case LLVMContext::MD_prof:
|
|
||||||
case LLVMContext::MD_fpmath:
|
|
||||||
case LLVMContext::MD_tbaa_struct:
|
|
||||||
case LLVMContext::MD_invariant_load:
|
|
||||||
case LLVMContext::MD_alias_scope:
|
|
||||||
case LLVMContext::MD_noalias:
|
|
||||||
case LLVMContext::MD_nontemporal:
|
|
||||||
case LLVMContext::MD_mem_parallel_loop_access:
|
|
||||||
case LLVMContext::MD_access_group:
|
|
||||||
// All of these directly apply.
|
|
||||||
NewLoad->setMetadata(ID, N);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LLVMContext::MD_nonnull:
|
|
||||||
copyNonnullMetadata(LI, N, *NewLoad);
|
|
||||||
break;
|
|
||||||
case LLVMContext::MD_align:
|
|
||||||
case LLVMContext::MD_dereferenceable:
|
|
||||||
case LLVMContext::MD_dereferenceable_or_null:
|
|
||||||
// These only directly apply if the new type is also a pointer.
|
|
||||||
if (NewTy->isPointerTy())
|
|
||||||
NewLoad->setMetadata(ID, N);
|
|
||||||
break;
|
|
||||||
case LLVMContext::MD_range:
|
|
||||||
copyRangeMetadata(IC.getDataLayout(), LI, N, *NewLoad);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NewLoad;
|
return NewLoad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2390,6 +2390,57 @@ void llvm::combineMetadataForCSE(Instruction *K, const Instruction *J,
|
||||||
combineMetadata(K, J, KnownIDs, KDominatesJ);
|
combineMetadata(K, J, KnownIDs, KDominatesJ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void llvm::copyMetadataForLoad(LoadInst &Dest, const LoadInst &Source) {
|
||||||
|
SmallVector<std::pair<unsigned, MDNode *>, 8> MD;
|
||||||
|
Source.getAllMetadata(MD);
|
||||||
|
MDBuilder MDB(Dest.getContext());
|
||||||
|
Type *NewType = Dest.getType();
|
||||||
|
const DataLayout &DL = Source.getModule()->getDataLayout();
|
||||||
|
for (const auto &MDPair : MD) {
|
||||||
|
unsigned ID = MDPair.first;
|
||||||
|
MDNode *N = MDPair.second;
|
||||||
|
// Note, essentially every kind of metadata should be preserved here! This
|
||||||
|
// routine is supposed to clone a load instruction changing *only its type*.
|
||||||
|
// The only metadata it makes sense to drop is metadata which is invalidated
|
||||||
|
// when the pointer type changes. This should essentially never be the case
|
||||||
|
// in LLVM, but we explicitly switch over only known metadata to be
|
||||||
|
// conservatively correct. If you are adding metadata to LLVM which pertains
|
||||||
|
// to loads, you almost certainly want to add it here.
|
||||||
|
switch (ID) {
|
||||||
|
case LLVMContext::MD_dbg:
|
||||||
|
case LLVMContext::MD_tbaa:
|
||||||
|
case LLVMContext::MD_prof:
|
||||||
|
case LLVMContext::MD_fpmath:
|
||||||
|
case LLVMContext::MD_tbaa_struct:
|
||||||
|
case LLVMContext::MD_invariant_load:
|
||||||
|
case LLVMContext::MD_alias_scope:
|
||||||
|
case LLVMContext::MD_noalias:
|
||||||
|
case LLVMContext::MD_nontemporal:
|
||||||
|
case LLVMContext::MD_mem_parallel_loop_access:
|
||||||
|
case LLVMContext::MD_access_group:
|
||||||
|
// All of these directly apply.
|
||||||
|
Dest.setMetadata(ID, N);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LLVMContext::MD_nonnull:
|
||||||
|
copyNonnullMetadata(Source, N, Dest);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LLVMContext::MD_align:
|
||||||
|
case LLVMContext::MD_dereferenceable:
|
||||||
|
case LLVMContext::MD_dereferenceable_or_null:
|
||||||
|
// These only directly apply if the new type is also a pointer.
|
||||||
|
if (NewType->isPointerTy())
|
||||||
|
Dest.setMetadata(ID, N);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LLVMContext::MD_range:
|
||||||
|
copyRangeMetadata(DL, Source, N, Dest);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void llvm::patchReplacementInstruction(Instruction *I, Value *Repl) {
|
void llvm::patchReplacementInstruction(Instruction *I, Value *Repl) {
|
||||||
auto *ReplInst = dyn_cast<Instruction>(Repl);
|
auto *ReplInst = dyn_cast<Instruction>(Repl);
|
||||||
if (!ReplInst)
|
if (!ReplInst)
|
||||||
|
|
Loading…
Reference in New Issue