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

Commit a5ef069

Browse files
authored
Merge pull request #90 from arielb1/sroa-nonnull
Preserve nonnull metadata on Loads through SROA & mem2reg
2 parents f0a23af + b514eb0 commit a5ef069

File tree

7 files changed

+307
-41
lines changed

7 files changed

+307
-41
lines changed

include/llvm/Transforms/Utils/Local.h

+13
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,19 @@ unsigned replaceDominatedUsesWith(Value *From, Value *To, DominatorTree &DT,
366366
/// during lowering by the GC infrastructure.
367367
bool callsGCLeafFunction(ImmutableCallSite CS);
368368

369+
/// Copy a nonnull metadata node to a new load instruction.
370+
///
371+
/// This handles mapping it to range metadata if the new load is an integer
372+
/// load instead of a pointer load.
373+
void copyNonnullMetadata(const LoadInst &OldLI, MDNode *N, LoadInst &NewLI);
374+
375+
/// Copy a range metadata node to a new load instruction.
376+
///
377+
/// This handles mapping it to nonnull metadata if the new load is a pointer
378+
/// load instead of an integer load and the range doesn't cover null.
379+
void copyRangeMetadata(const DataLayout &DL, const LoadInst &OldLI, MDNode *N,
380+
LoadInst &NewLI);
381+
369382
//===----------------------------------------------------------------------===//
370383
// Intrinsic pattern matching
371384
//

lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp

+2-26
Original file line numberDiff line numberDiff line change
@@ -471,21 +471,7 @@ static LoadInst *combineLoadToNewType(InstCombiner &IC, LoadInst &LI, Type *NewT
471471
break;
472472

473473
case LLVMContext::MD_nonnull:
474-
// This only directly applies if the new type is also a pointer.
475-
if (NewTy->isPointerTy()) {
476-
NewLoad->setMetadata(ID, N);
477-
break;
478-
}
479-
// If it's integral now, translate it to !range metadata.
480-
if (NewTy->isIntegerTy()) {
481-
auto *ITy = cast<IntegerType>(NewTy);
482-
auto *NullInt = ConstantExpr::getPtrToInt(
483-
ConstantPointerNull::get(cast<PointerType>(Ptr->getType())), ITy);
484-
auto *NonNullInt =
485-
ConstantExpr::getAdd(NullInt, ConstantInt::get(ITy, 1));
486-
NewLoad->setMetadata(LLVMContext::MD_range,
487-
MDB.createRange(NonNullInt, NullInt));
488-
}
474+
copyNonnullMetadata(LI, N, *NewLoad);
489475
break;
490476
case LLVMContext::MD_align:
491477
case LLVMContext::MD_dereferenceable:
@@ -495,17 +481,7 @@ static LoadInst *combineLoadToNewType(InstCombiner &IC, LoadInst &LI, Type *NewT
495481
NewLoad->setMetadata(ID, N);
496482
break;
497483
case LLVMContext::MD_range:
498-
// FIXME: It would be nice to propagate this in some way, but the type
499-
// conversions make it hard.
500-
501-
// If it's a pointer now and the range does not contain 0, make it !nonnull.
502-
if (NewTy->isPointerTy()) {
503-
unsigned BitWidth = IC.getDataLayout().getTypeSizeInBits(NewTy);
504-
if (!getConstantRangeFromMetadata(*N).contains(APInt(BitWidth, 0))) {
505-
MDNode *NN = MDNode::get(LI.getContext(), None);
506-
NewLoad->setMetadata(LLVMContext::MD_nonnull, NN);
507-
}
508-
}
484+
copyRangeMetadata(IC.getDataLayout(), LI, N, *NewLoad);
509485
break;
510486
}
511487
}

lib/Transforms/Scalar/SROA.cpp

+15
Original file line numberDiff line numberDiff line change
@@ -2387,6 +2387,21 @@ class llvm::sroa::AllocaSliceRewriter
23872387
LI.isVolatile(), LI.getName());
23882388
if (LI.isVolatile())
23892389
NewLI->setAtomic(LI.getOrdering(), LI.getSynchScope());
2390+
2391+
// Any !nonnull metadata or !range metadata on the old load is also valid
2392+
// on the new load. This is even true in some cases even when the loads
2393+
// are different types, for example by mapping !nonnull metadata to
2394+
// !range metadata by modeling the null pointer constant converted to the
2395+
// integer type.
2396+
// FIXME: Add support for range metadata here. Currently the utilities
2397+
// for this don't propagate range metadata in trivial cases from one
2398+
// integer load to another, don't handle non-addrspace-0 null pointers
2399+
// correctly, and don't have any support for mapping ranges as the
2400+
// integer type becomes winder or narrower.
2401+
if (MDNode *N = LI.getMetadata(LLVMContext::MD_nonnull))
2402+
copyNonnullMetadata(LI, N, *NewLI);
2403+
2404+
// Try to preserve nonnull metadata
23902405
V = NewLI;
23912406

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

lib/Transforms/Utils/Local.cpp

+49-5
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "llvm/Analysis/LazyValueInfo.h"
2727
#include "llvm/Analysis/ValueTracking.h"
2828
#include "llvm/IR/CFG.h"
29+
#include "llvm/IR/ConstantRange.h"
2930
#include "llvm/IR/Constants.h"
3031
#include "llvm/IR/DIBuilder.h"
3132
#include "llvm/IR/DataLayout.h"
@@ -1069,7 +1070,7 @@ static bool LdStHasDebugValue(DILocalVariable *DIVar, DIExpression *DIExpr,
10691070
}
10701071

10711072
/// See if there is a dbg.value intrinsic for DIVar for the PHI node.
1072-
static bool PhiHasDebugValue(DILocalVariable *DIVar,
1073+
static bool PhiHasDebugValue(DILocalVariable *DIVar,
10731074
DIExpression *DIExpr,
10741075
PHINode *APN) {
10751076
// Since we can't guarantee that the original dbg.declare instrinsic
@@ -1152,7 +1153,7 @@ void llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
11521153
DbgValue->insertAfter(LI);
11531154
}
11541155

1155-
/// Inserts a llvm.dbg.value intrinsic after a phi
1156+
/// Inserts a llvm.dbg.value intrinsic after a phi
11561157
/// that has an associated llvm.dbg.decl intrinsic.
11571158
void llvm::ConvertDebugDeclareToDebugValue(DbgDeclareInst *DDI,
11581159
PHINode *APN, DIBuilder &Builder) {
@@ -1723,12 +1724,12 @@ void llvm::combineMetadata(Instruction *K, const Instruction *J,
17231724
// Preserve !invariant.group in K.
17241725
break;
17251726
case LLVMContext::MD_align:
1726-
K->setMetadata(Kind,
1727+
K->setMetadata(Kind,
17271728
MDNode::getMostGenericAlignmentOrDereferenceable(JMD, KMD));
17281729
break;
17291730
case LLVMContext::MD_dereferenceable:
17301731
case LLVMContext::MD_dereferenceable_or_null:
1731-
K->setMetadata(Kind,
1732+
K->setMetadata(Kind,
17321733
MDNode::getMostGenericAlignmentOrDereferenceable(JMD, KMD));
17331734
break;
17341735
}
@@ -1812,6 +1813,49 @@ bool llvm::callsGCLeafFunction(ImmutableCallSite CS) {
18121813
return false;
18131814
}
18141815

1816+
void llvm::copyNonnullMetadata(const LoadInst &OldLI, MDNode *N,
1817+
LoadInst &NewLI) {
1818+
auto *NewTy = NewLI.getType();
1819+
1820+
// This only directly applies if the new type is also a pointer.
1821+
if (NewTy->isPointerTy()) {
1822+
NewLI.setMetadata(LLVMContext::MD_nonnull, N);
1823+
return;
1824+
}
1825+
1826+
// The only other translation we can do is to integral loads with !range
1827+
// metadata.
1828+
if (!NewTy->isIntegerTy())
1829+
return;
1830+
1831+
MDBuilder MDB(NewLI.getContext());
1832+
const Value *Ptr = OldLI.getPointerOperand();
1833+
auto *ITy = cast<IntegerType>(NewTy);
1834+
auto *NullInt = ConstantExpr::getPtrToInt(
1835+
ConstantPointerNull::get(cast<PointerType>(Ptr->getType())), ITy);
1836+
auto *NonNullInt = ConstantExpr::getAdd(NullInt, ConstantInt::get(ITy, 1));
1837+
NewLI.setMetadata(LLVMContext::MD_range,
1838+
MDB.createRange(NonNullInt, NullInt));
1839+
}
1840+
1841+
void llvm::copyRangeMetadata(const DataLayout &DL, const LoadInst &OldLI,
1842+
MDNode *N, LoadInst &NewLI) {
1843+
auto *NewTy = NewLI.getType();
1844+
1845+
// Give up unless it is converted to a pointer where there is a single very
1846+
// valuable mapping we can do reliably.
1847+
// FIXME: It would be nice to propagate this in more ways, but the type
1848+
// conversions make it hard.
1849+
if (!NewTy->isPointerTy())
1850+
return;
1851+
1852+
unsigned BitWidth = DL.getTypeSizeInBits(NewTy);
1853+
if (!getConstantRangeFromMetadata(*N).contains(APInt(BitWidth, 0))) {
1854+
MDNode *NN = MDNode::get(OldLI.getContext(), None);
1855+
NewLI.setMetadata(LLVMContext::MD_nonnull, NN);
1856+
}
1857+
}
1858+
18151859
namespace {
18161860
/// A potential constituent of a bitreverse or bswap expression. See
18171861
/// collectBitParts for a fuller explanation.
@@ -1933,7 +1977,7 @@ collectBitParts(Value *V, bool MatchBSwaps, bool MatchBitReversals,
19331977
unsigned NumMaskedBits = AndMask.countPopulation();
19341978
if (!MatchBitReversals && NumMaskedBits % 8 != 0)
19351979
return Result;
1936-
1980+
19371981
auto &Res = collectBitParts(I->getOperand(0), MatchBSwaps,
19381982
MatchBitReversals, BPS);
19391983
if (!Res)

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;
@@ -940,6 +970,13 @@ void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred,
940970

941971
Value *V = IncomingVals[AI->second];
942972

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

0 commit comments

Comments
 (0)