diff options
author | Sanjay Patel <spatel@rotateright.com> | 2017-02-27 18:13:48 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2017-02-27 18:13:48 +0000 |
commit | 40975e05ebc8371bd7aee01076f4ce916d18a549 (patch) | |
tree | 1ed47e07f8d26501b173d22b81c0471e8dfbfb0c /llvm/lib/Transforms/Utils/InlineFunction.cpp | |
parent | e9be35596e609c707a07c4eecb435f685d55b457 (diff) | |
download | bcm5719-llvm-40975e05ebc8371bd7aee01076f4ce916d18a549.tar.gz bcm5719-llvm-40975e05ebc8371bd7aee01076f4ce916d18a549.zip |
[InlineFunction] add nonnull assumptions based on argument attributes
This was suggested in D27855: have the inliner add assumptions, so we don't
lose nonnull info provided by argument attributes.
This still doesn't solve PR28430 (dyn_cast), but this gets us closer.
https://reviews.llvm.org/D29999
llvm-svn: 296366
Diffstat (limited to 'llvm/lib/Transforms/Utils/InlineFunction.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/InlineFunction.cpp | 58 |
1 files changed, 36 insertions, 22 deletions
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index bd3aa8d3867..f835e864dc5 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -1093,38 +1093,52 @@ static void AddAliasScopeMetadata(CallSite CS, ValueToValueMapTy &VMap, } } -/// If the inlined function has non-byval align arguments, then -/// add @llvm.assume-based alignment assumptions to preserve this information. -static void AddAlignmentAssumptions(CallSite CS, InlineFunctionInfo &IFI) { - if (!PreserveAlignmentAssumptions || !IFI.GetAssumptionCache) +/// Add @llvm.assume-based assumptions to preserve information supplied by +/// argument attributes because the attributes will disappear after inlining. +static void addAssumptions(CallSite CS, InlineFunctionInfo &IFI) { + if (!IFI.GetAssumptionCache) return; AssumptionCache *AC = &(*IFI.GetAssumptionCache)(*CS.getCaller()); auto &DL = CS.getCaller()->getParent()->getDataLayout(); - // To avoid inserting redundant assumptions, we should check for assumptions - // already in the caller. To do this, we might need a DT of the caller. + // To avoid inserting redundant assumptions, check that an assumption provides + // new information in the caller. This might require a dominator tree. DominatorTree DT; bool DTCalculated = false; + auto calcDomTreeIfNeeded = [&]() { + if (!DTCalculated) { + DT.recalculate(*CS.getCaller()); + DTCalculated = true; + } + }; Function *CalledFunc = CS.getCalledFunction(); + IRBuilder<> Builder(CS.getInstruction()); for (Argument &Arg : CalledFunc->args()) { - unsigned Align = Arg.getType()->isPointerTy() ? Arg.getParamAlignment() : 0; - if (Align && !Arg.hasByValOrInAllocaAttr() && !Arg.hasNUses(0)) { - if (!DTCalculated) { - DT.recalculate(*CS.getCaller()); - DTCalculated = true; - } + Value *ArgVal = CS.getArgument(Arg.getArgNo()); + unsigned Align = Arg.getType()->isPointerTy() ? Arg.getParamAlignment() : 0; + if (PreserveAlignmentAssumptions && Align && + !Arg.hasByValOrInAllocaAttr() && !Arg.hasNUses(0)) { // If we can already prove the asserted alignment in the context of the // caller, then don't bother inserting the assumption. - Value *ArgVal = CS.getArgument(Arg.getArgNo()); - if (getKnownAlignment(ArgVal, DL, CS.getInstruction(), AC, &DT) >= Align) - continue; + calcDomTreeIfNeeded(); + if (getKnownAlignment(ArgVal, DL, CS.getInstruction(), AC, &DT) < Align) { + CallInst *Asmp = Builder.CreateAlignmentAssumption(DL, ArgVal, Align); + AC->registerAssumption(Asmp); + } + } - CallInst *NewAsmp = IRBuilder<>(CS.getInstruction()) - .CreateAlignmentAssumption(DL, ArgVal, Align); - AC->registerAssumption(NewAsmp); + if (Arg.hasNonNullAttr()) { + // If we can already prove nonnull in the context of the caller, then + // don't bother inserting the assumption. + calcDomTreeIfNeeded(); + if (!isKnownNonNullAt(ArgVal, CS.getInstruction(), &DT)) { + Value *NotNull = Builder.CreateIsNotNull(ArgVal); + CallInst *Asmp = Builder.CreateAssumption(NotNull); + AC->registerAssumption(Asmp); + } } } } @@ -1621,10 +1635,10 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, VMap[&*I] = ActualArg; } - // Add alignment assumptions if necessary. We do this before the inlined - // instructions are actually cloned into the caller so that we can easily - // check what will be known at the start of the inlined code. - AddAlignmentAssumptions(CS, IFI); + // Add assumptions if necessary. We do this before the inlined instructions + // are actually cloned into the caller so that we can easily check what will + // be known at the start of the inlined code. + addAssumptions(CS, IFI); // We want the inliner to prune the code as it copies. We would LOVE to // have no dead or constant instructions leftover after inlining occurs |