Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 2e83dcc

Browse files
authored
Merge pull request #68 from luqmana/cherrypick-D27114
Preserve nonnull metadata on Loads through SROA & mem2reg.
2 parents 2e951c3 + 0028e44 commit 2e83dcc

File tree

8 files changed

+228
-67
lines changed

8 files changed

+228
-67
lines changed

include/llvm/IR/Instruction.h

+10
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,16 @@ class Instruction : public User,
197197
void setMetadata(unsigned KindID, MDNode *Node);
198198
void setMetadata(StringRef Kind, MDNode *Node);
199199

200+
/// Copy metadata from \p SrcInst to this instruction. \p WL, if not empty,
201+
/// specifies the list of meta data that needs to be copied. If \p WL is
202+
/// empty, all meta data will be copied.
203+
void copyMetadata(const Instruction &SrcInst, ArrayRef<unsigned> WL = {});
204+
205+
/// If the instruction has "branch_weights" MD_prof metadata and the MDNode
206+
/// has three operands (including name string), swap the order of the
207+
/// metadata.
208+
void swapProfMetadata();
209+
200210
/// Drop all unknown metadata except for debug locations.
201211
/// @{
202212
/// Passes are required to drop metadata they don't understand. This is a

lib/IR/Instruction.cpp

+43-11
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//
1212
//===----------------------------------------------------------------------===//
1313

14+
#include "llvm/ADT/DenseSet.h"
1415
#include "llvm/IR/Instruction.h"
1516
#include "llvm/IR/CallSite.h"
1617
#include "llvm/IR/Constants.h"
@@ -627,6 +628,47 @@ Instruction *Instruction::cloneImpl() const {
627628
llvm_unreachable("Subclass of Instruction failed to implement cloneImpl");
628629
}
629630

631+
void Instruction::swapProfMetadata() {
632+
MDNode *ProfileData = getMetadata(LLVMContext::MD_prof);
633+
if (!ProfileData || ProfileData->getNumOperands() != 3 ||
634+
!isa<MDString>(ProfileData->getOperand(0)))
635+
return;
636+
637+
MDString *MDName = cast<MDString>(ProfileData->getOperand(0));
638+
if (MDName->getString() != "branch_weights")
639+
return;
640+
641+
// The first operand is the name. Fetch them backwards and build a new one.
642+
Metadata *Ops[] = {ProfileData->getOperand(0), ProfileData->getOperand(2),
643+
ProfileData->getOperand(1)};
644+
setMetadata(LLVMContext::MD_prof,
645+
MDNode::get(ProfileData->getContext(), Ops));
646+
}
647+
648+
/// Copy meta data from \p SrcInst to this instruction. If WL is empty, all
649+
/// data will be copied, otherwise only ones specified in WL will be copied.
650+
void Instruction::copyMetadata(const Instruction &SrcInst,
651+
ArrayRef<unsigned> WL) {
652+
if (!SrcInst.hasMetadata())
653+
return;
654+
655+
DenseSet<unsigned> WLS;
656+
for (unsigned M : WL)
657+
WLS.insert(M);
658+
659+
// Otherwise, enumerate and copy over metadata from the old instruction to the
660+
// new one.
661+
SmallVector<std::pair<unsigned, MDNode *>, 4> TheMDs;
662+
SrcInst.getAllMetadataOtherThanDebugLoc(TheMDs);
663+
for (const auto &MD : TheMDs) {
664+
if (WL.empty() || WLS.count(MD.first))
665+
setMetadata(MD.first, MD.second);
666+
}
667+
if (WL.empty() || WLS.count(LLVMContext::MD_dbg))
668+
setDebugLoc(SrcInst.getDebugLoc());
669+
return;
670+
}
671+
630672
Instruction *Instruction::clone() const {
631673
Instruction *New = nullptr;
632674
switch (getOpcode()) {
@@ -641,16 +683,6 @@ Instruction *Instruction::clone() const {
641683
}
642684

643685
New->SubclassOptionalData = SubclassOptionalData;
644-
if (!hasMetadata())
645-
return New;
646-
647-
// Otherwise, enumerate and copy over metadata from the old instruction to the
648-
// new one.
649-
SmallVector<std::pair<unsigned, MDNode *>, 4> TheMDs;
650-
getAllMetadataOtherThanDebugLoc(TheMDs);
651-
for (const auto &MD : TheMDs)
652-
New->setMetadata(MD.first, MD.second);
653-
654-
New->setDebugLoc(getDebugLoc());
686+
New->copyMetadata(*this);
655687
return New;
656688
}

lib/IR/Instructions.cpp

+1-9
Original file line numberDiff line numberDiff line change
@@ -1209,15 +1209,7 @@ void BranchInst::swapSuccessors() {
12091209

12101210
// Update profile metadata if present and it matches our structural
12111211
// expectations.
1212-
MDNode *ProfileData = getMetadata(LLVMContext::MD_prof);
1213-
if (!ProfileData || ProfileData->getNumOperands() != 3)
1214-
return;
1215-
1216-
// The first operand is the name. Fetch them backwards and build a new one.
1217-
Metadata *Ops[] = {ProfileData->getOperand(0), ProfileData->getOperand(2),
1218-
ProfileData->getOperand(1)};
1219-
setMetadata(LLVMContext::MD_prof,
1220-
MDNode::get(ProfileData->getContext(), Ops));
1212+
swapProfMetadata();
12211213
}
12221214

12231215
BasicBlock *BranchInst::getSuccessorV(unsigned idx) const {

lib/Transforms/Scalar/LoopUnswitch.cpp

+8-37
Original file line numberDiff line numberDiff line change
@@ -742,42 +742,6 @@ static Loop *CloneLoop(Loop *L, Loop *PL, ValueToValueMapTy &VM,
742742
return &New;
743743
}
744744

745-
static void copyMetadata(Instruction *DstInst, const Instruction *SrcInst,
746-
bool Swapped) {
747-
if (!SrcInst || !SrcInst->hasMetadata())
748-
return;
749-
750-
SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
751-
SrcInst->getAllMetadata(MDs);
752-
for (auto &MD : MDs) {
753-
switch (MD.first) {
754-
default:
755-
break;
756-
case LLVMContext::MD_prof:
757-
if (Swapped && MD.second->getNumOperands() == 3 &&
758-
isa<MDString>(MD.second->getOperand(0))) {
759-
MDString *MDName = cast<MDString>(MD.second->getOperand(0));
760-
if (MDName->getString() == "branch_weights") {
761-
auto *ValT = cast_or_null<ConstantAsMetadata>(
762-
MD.second->getOperand(1))->getValue();
763-
auto *ValF = cast_or_null<ConstantAsMetadata>(
764-
MD.second->getOperand(2))->getValue();
765-
assert(ValT && ValF && "Invalid Operands of branch_weights");
766-
auto NewMD =
767-
MDBuilder(DstInst->getParent()->getContext())
768-
.createBranchWeights(cast<ConstantInt>(ValF)->getZExtValue(),
769-
cast<ConstantInt>(ValT)->getZExtValue());
770-
MD.second = NewMD;
771-
}
772-
}
773-
// fallthrough.
774-
case LLVMContext::MD_make_implicit:
775-
case LLVMContext::MD_dbg:
776-
DstInst->setMetadata(MD.first, MD.second);
777-
}
778-
}
779-
}
780-
781745
/// Emit a conditional branch on two values if LIC == Val, branch to TrueDst,
782746
/// otherwise branch to FalseDest. Insert the code immediately before InsertPt.
783747
void LoopUnswitch::EmitPreheaderBranchOnCondition(Value *LIC, Constant *Val,
@@ -800,7 +764,14 @@ void LoopUnswitch::EmitPreheaderBranchOnCondition(Value *LIC, Constant *Val,
800764

801765
// Insert the new branch.
802766
BranchInst *BI = BranchInst::Create(TrueDest, FalseDest, BranchVal, InsertPt);
803-
copyMetadata(BI, TI, Swapped);
767+
if (TI) {
768+
// FIXME: check why white list is needed here:
769+
ArrayRef<unsigned> WL = {LLVMContext::MD_dbg, LLVMContext::MD_prof,
770+
LLVMContext::MD_make_implicit};
771+
BI->copyMetadata(*TI, WL);
772+
if (Swapped)
773+
BI->swapProfMetadata();
774+
}
804775

805776
// If either edge is critical, split it. This helps preserve LoopSimplify
806777
// form for enclosing loops.

lib/Transforms/Scalar/SROA.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -2390,6 +2390,10 @@ class llvm::sroa::AllocaSliceRewriter
23902390
LI.isVolatile(), LI.getName());
23912391
if (LI.isVolatile())
23922392
NewLI->setAtomic(LI.getOrdering(), LI.getSynchScope());
2393+
2394+
// Try to preserve nonnull metadata
2395+
if (TargetTy->isPointerTy())
2396+
NewLI->copyMetadata(LI, LLVMContext::MD_nonnull);
23932397
V = NewLI;
23942398

23952399
// If this is an integer load past the end of the slice (which means the

lib/Transforms/Utils/PromoteMemoryToRegister.cpp

+47-10
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@
1515
//
1616
//===----------------------------------------------------------------------===//
1717

18-
#include "llvm/Transforms/Utils/PromoteMemToReg.h"
1918
#include "llvm/ADT/ArrayRef.h"
2019
#include "llvm/ADT/DenseMap.h"
2120
#include "llvm/ADT/STLExtras.h"
2221
#include "llvm/ADT/SmallPtrSet.h"
2322
#include "llvm/ADT/SmallVector.h"
2423
#include "llvm/ADT/Statistic.h"
2524
#include "llvm/Analysis/AliasSetTracker.h"
25+
#include "llvm/Analysis/AssumptionCache.h"
2626
#include "llvm/Analysis/InstructionSimplify.h"
2727
#include "llvm/Analysis/IteratedDominanceFrontier.h"
2828
#include "llvm/Analysis/ValueTracking.h"
@@ -38,6 +38,7 @@
3838
#include "llvm/IR/Metadata.h"
3939
#include "llvm/IR/Module.h"
4040
#include "llvm/Transforms/Utils/Local.h"
41+
#include "llvm/Transforms/Utils/PromoteMemToReg.h"
4142
#include <algorithm>
4243
using namespace llvm;
4344

@@ -301,6 +302,18 @@ struct PromoteMem2Reg {
301302

302303
} // end of anonymous namespace
303304

305+
/// Given a LoadInst LI this adds assume(LI != null) after it.
306+
static void addAssumeNonNull(AssumptionCache *AC, LoadInst *LI) {
307+
Function *AssumeIntrinsic =
308+
Intrinsic::getDeclaration(LI->getModule(), Intrinsic::assume);
309+
ICmpInst *LoadNotNull = new ICmpInst(ICmpInst::ICMP_NE, LI,
310+
Constant::getNullValue(LI->getType()));
311+
LoadNotNull->insertAfter(LI);
312+
CallInst *CI = CallInst::Create(AssumeIntrinsic, {LoadNotNull});
313+
CI->insertAfter(LoadNotNull);
314+
AC->registerAssumption(CI);
315+
}
316+
304317
static void removeLifetimeIntrinsicUsers(AllocaInst *AI) {
305318
// Knowing that this alloca is promotable, we know that it's safe to kill all
306319
// instructions except for load and store.
@@ -334,9 +347,9 @@ static void removeLifetimeIntrinsicUsers(AllocaInst *AI) {
334347
/// and thus must be phi-ed with undef. We fall back to the standard alloca
335348
/// promotion algorithm in that case.
336349
static bool rewriteSingleStoreAlloca(AllocaInst *AI, AllocaInfo &Info,
337-
LargeBlockInfo &LBI,
338-
DominatorTree &DT,
339-
AliasSetTracker *AST) {
350+
LargeBlockInfo &LBI, DominatorTree &DT,
351+
AliasSetTracker *AST,
352+
AssumptionCache *AC) {
340353
StoreInst *OnlyStore = Info.OnlyStore;
341354
bool StoringGlobalVal = !isa<Instruction>(OnlyStore->getOperand(0));
342355
BasicBlock *StoreBB = OnlyStore->getParent();
@@ -387,6 +400,14 @@ static bool rewriteSingleStoreAlloca(AllocaInst *AI, AllocaInfo &Info,
387400
// code.
388401
if (ReplVal == LI)
389402
ReplVal = UndefValue::get(LI->getType());
403+
404+
// If the load was marked as nonnull we don't want to lose
405+
// that information when we erase this Load. So we preserve
406+
// it with an assume.
407+
if (AC && LI->getMetadata(LLVMContext::MD_nonnull) &&
408+
!llvm::isKnownNonNullAt(ReplVal, LI, &DT))
409+
addAssumeNonNull(AC, LI);
410+
390411
LI->replaceAllUsesWith(ReplVal);
391412
if (AST && LI->getType()->isPointerTy())
392413
AST->deleteValue(LI);
@@ -435,7 +456,9 @@ static bool rewriteSingleStoreAlloca(AllocaInst *AI, AllocaInfo &Info,
435456
/// }
436457
static bool promoteSingleBlockAlloca(AllocaInst *AI, const AllocaInfo &Info,
437458
LargeBlockInfo &LBI,
438-
AliasSetTracker *AST) {
459+
AliasSetTracker *AST,
460+
DominatorTree &DT,
461+
AssumptionCache *AC) {
439462
// The trickiest case to handle is when we have large blocks. Because of this,
440463
// this code is optimized assuming that large blocks happen. This does not
441464
// significantly pessimize the small block case. This uses LargeBlockInfo to
@@ -476,10 +499,17 @@ static bool promoteSingleBlockAlloca(AllocaInst *AI, const AllocaInfo &Info,
476499
// There is no store before this load, bail out (load may be affected
477500
// by the following stores - see main comment).
478501
return false;
479-
}
480-
else
502+
} else {
481503
// Otherwise, there was a store before this load, the load takes its value.
482-
LI->replaceAllUsesWith(std::prev(I)->second->getOperand(0));
504+
// Note, if the load was marked as nonnull we don't want to lose that
505+
// information when we erase it. So we preserve it with an assume.
506+
Value *ReplVal = std::prev(I)->second->getOperand(0);
507+
if (AC && LI->getMetadata(LLVMContext::MD_nonnull) &&
508+
!llvm::isKnownNonNullAt(ReplVal, LI, &DT))
509+
addAssumeNonNull(AC, LI);
510+
511+
LI->replaceAllUsesWith(ReplVal);
512+
}
483513

484514
if (AST && LI->getType()->isPointerTy())
485515
AST->deleteValue(LI);
@@ -553,7 +583,7 @@ void PromoteMem2Reg::run() {
553583
// If there is only a single store to this value, replace any loads of
554584
// it that are directly dominated by the definition with the value stored.
555585
if (Info.DefiningBlocks.size() == 1) {
556-
if (rewriteSingleStoreAlloca(AI, Info, LBI, DT, AST)) {
586+
if (rewriteSingleStoreAlloca(AI, Info, LBI, DT, AST, AC)) {
557587
// The alloca has been processed, move on.
558588
RemoveFromAllocasList(AllocaNum);
559589
++NumSingleStore;
@@ -564,7 +594,7 @@ void PromoteMem2Reg::run() {
564594
// If the alloca is only read and written in one basic block, just perform a
565595
// linear sweep over the block to eliminate it.
566596
if (Info.OnlyUsedInOneBlock &&
567-
promoteSingleBlockAlloca(AI, Info, LBI, AST)) {
597+
promoteSingleBlockAlloca(AI, Info, LBI, AST, DT, AC)) {
568598
// The alloca has been processed, move on.
569599
RemoveFromAllocasList(AllocaNum);
570600
continue;
@@ -938,6 +968,13 @@ void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred,
938968

939969
Value *V = IncomingVals[AI->second];
940970

971+
// If the load was marked as nonnull we don't want to lose
972+
// that information when we erase this Load. So we preserve
973+
// it with an assume.
974+
if (AC && LI->getMetadata(LLVMContext::MD_nonnull) &&
975+
!llvm::isKnownNonNullAt(V, LI, &DT))
976+
addAssumeNonNull(AC, LI);
977+
941978
// Anything using the load now uses the current value.
942979
LI->replaceAllUsesWith(V);
943980
if (AST && LI->getType()->isPointerTy())

0 commit comments

Comments
 (0)