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,
|
||||
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
|
||||
/// being replaced. It assumes that the replacement does not get moved from
|
||||
/// its original position.
|
||||
|
|
|
@ -455,9 +455,6 @@ static LoadInst *combineLoadToNewType(InstCombiner &IC, LoadInst &LI, Type *NewT
|
|||
|
||||
Value *Ptr = LI.getPointerOperand();
|
||||
unsigned AS = LI.getPointerAddressSpace();
|
||||
SmallVector<std::pair<unsigned, MDNode *>, 8> MD;
|
||||
LI.getAllMetadata(MD);
|
||||
|
||||
Value *NewPtr = nullptr;
|
||||
if (!(match(Ptr, m_BitCast(m_Value(NewPtr))) &&
|
||||
NewPtr->getType()->getPointerElementType() == NewTy &&
|
||||
|
@ -467,48 +464,7 @@ static LoadInst *combineLoadToNewType(InstCombiner &IC, LoadInst &LI, Type *NewT
|
|||
LoadInst *NewLoad = IC.Builder.CreateAlignedLoad(
|
||||
NewTy, NewPtr, LI.getAlignment(), LI.isVolatile(), LI.getName() + Suffix);
|
||||
NewLoad->setAtomic(LI.getOrdering(), LI.getSyncScopeID());
|
||||
MDBuilder MDB(NewLoad->getContext());
|
||||
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;
|
||||
}
|
||||
}
|
||||
copyMetadataForLoad(*NewLoad, LI);
|
||||
return NewLoad;
|
||||
}
|
||||
|
||||
|
|
|
@ -2390,6 +2390,57 @@ void llvm::combineMetadataForCSE(Instruction *K, const Instruction *J,
|
|||
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) {
|
||||
auto *ReplInst = dyn_cast<Instruction>(Repl);
|
||||
if (!ReplInst)
|
||||
|
|
Loading…
Reference in New Issue