forked from OSchip/llvm-project
[GVNHoist] Merge metadata on hoisted instructions less conservatively
We can combine metadata from multiple instructions intelligently for certain metadata nodes. llvm-svn: 276602
This commit is contained in:
parent
4728569d0a
commit
68623a0e9f
|
@ -23,6 +23,7 @@
|
|||
#include "llvm/Analysis/ValueTracking.h"
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
#include "llvm/Transforms/Scalar/GVN.h"
|
||||
#include "llvm/Transforms/Utils/Local.h"
|
||||
#include "llvm/Transforms/Utils/MemorySSA.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
@ -172,6 +173,15 @@ typedef DenseMap<const BasicBlock *, bool> BBSideEffectsSet;
|
|||
typedef SmallVector<Instruction *, 4> SmallVecInsn;
|
||||
typedef SmallVectorImpl<Instruction *> SmallVecImplInsn;
|
||||
|
||||
static void combineKnownMetadata(Instruction *ReplInst, Instruction *I) {
|
||||
static const unsigned KnownIDs[] = {
|
||||
LLVMContext::MD_tbaa, LLVMContext::MD_alias_scope,
|
||||
LLVMContext::MD_noalias, LLVMContext::MD_range,
|
||||
LLVMContext::MD_fpmath, LLVMContext::MD_invariant_load,
|
||||
LLVMContext::MD_invariant_group};
|
||||
combineMetadata(ReplInst, I, KnownIDs);
|
||||
}
|
||||
|
||||
// This pass hoists common computations across branches sharing common
|
||||
// dominator. The primary goal is to reduce the code size, and in some
|
||||
// cases reduce critical path (by exposing more ILP).
|
||||
|
@ -604,15 +614,15 @@ public:
|
|||
ClonedGep->insertBefore(HoistPt->getTerminator());
|
||||
// Conservatively discard any optimization hints, they may differ on the
|
||||
// other paths.
|
||||
ClonedGep->dropUnknownNonDebugMetadata();
|
||||
for (const Instruction *OtherInst : InstructionsToHoist) {
|
||||
const GetElementPtrInst *OtherGep;
|
||||
for (Instruction *OtherInst : InstructionsToHoist) {
|
||||
GetElementPtrInst *OtherGep;
|
||||
if (auto *OtherLd = dyn_cast<LoadInst>(OtherInst))
|
||||
OtherGep = cast<GetElementPtrInst>(OtherLd->getPointerOperand());
|
||||
else
|
||||
OtherGep = cast<GetElementPtrInst>(
|
||||
cast<StoreInst>(OtherInst)->getPointerOperand());
|
||||
ClonedGep->intersectOptionalDataWith(OtherGep);
|
||||
combineKnownMetadata(ClonedGep, OtherGep);
|
||||
}
|
||||
Repl->replaceUsesOfWith(Gep, ClonedGep);
|
||||
|
||||
|
@ -622,11 +632,11 @@ public:
|
|||
ClonedVal->insertBefore(HoistPt->getTerminator());
|
||||
// Conservatively discard any optimization hints, they may differ on the
|
||||
// other paths.
|
||||
ClonedVal->dropUnknownNonDebugMetadata();
|
||||
for (const Instruction *OtherInst : InstructionsToHoist) {
|
||||
const auto *OtherVal =
|
||||
for (Instruction *OtherInst : InstructionsToHoist) {
|
||||
auto *OtherVal =
|
||||
cast<Instruction>(cast<StoreInst>(OtherInst)->getValueOperand());
|
||||
ClonedVal->intersectOptionalDataWith(OtherVal);
|
||||
combineKnownMetadata(ClonedVal, OtherVal);
|
||||
}
|
||||
Repl->replaceUsesOfWith(Val, ClonedVal);
|
||||
}
|
||||
|
@ -668,7 +678,6 @@ public:
|
|||
Repl->moveBefore(HoistPt->getTerminator());
|
||||
// TBAA may differ on one of the other paths, we need to get rid of
|
||||
// anything which might conflict.
|
||||
Repl->dropUnknownNonDebugMetadata();
|
||||
}
|
||||
|
||||
if (isa<LoadInst>(Repl))
|
||||
|
@ -702,6 +711,7 @@ public:
|
|||
++NumCallsRemoved;
|
||||
}
|
||||
Repl->intersectOptionalDataWith(I);
|
||||
combineKnownMetadata(Repl, I);
|
||||
I->replaceAllUsesWith(Repl);
|
||||
I->eraseFromParent();
|
||||
}
|
||||
|
|
|
@ -71,3 +71,28 @@ if.end: ; preds = %if.else, %if.then
|
|||
!4 = !{!"Simple C++ TBAA"}
|
||||
!5 = !{!6, !6, i64 0}
|
||||
!6 = !{!"_ZTS1e", !3, i64 0}
|
||||
|
||||
define i32 @test4(i1 %b, i32* %y) {
|
||||
entry:
|
||||
br i1 %b, label %if.then, label %if.end
|
||||
|
||||
if.then: ; preds = %entry
|
||||
%0 = load i32, i32* %y, align 4, !range !7
|
||||
br label %return
|
||||
|
||||
if.end: ; preds = %entry
|
||||
%1 = load i32, i32* %y, align 4, !range !8
|
||||
br label %return
|
||||
|
||||
return: ; preds = %if.end, %if.then
|
||||
%retval.0 = phi i32 [ %0, %if.then ], [ %1, %if.end ]
|
||||
ret i32 %retval.0
|
||||
}
|
||||
; CHECK-LABEL: define i32 @test4(
|
||||
; CHECK: %[[load:.*]] = load i32, i32* %y, align 4, !range ![[range_md:.*]]
|
||||
; CHECK: %[[phi:.*]] = phi i32 [ %[[load]], %{{.*}} ], [ %[[load]], %{{.*}} ]
|
||||
; CHECK: ret i32 %[[phi]]
|
||||
|
||||
!7 = !{i32 0, i32 2}
|
||||
!8 = !{i32 3, i32 4}
|
||||
; CHECK: ![[range_md]] = !{i32 0, i32 2, i32 3, i32 4}
|
||||
|
|
Loading…
Reference in New Issue