diff options
Diffstat (limited to 'llvm/lib/Analysis')
| -rw-r--r-- | llvm/lib/Analysis/DemandedBits.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/Analysis/IVDescriptors.cpp | 5 | ||||
| -rw-r--r-- | llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp | 81 | ||||
| -rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 28 | 
4 files changed, 89 insertions, 27 deletions
| diff --git a/llvm/lib/Analysis/DemandedBits.cpp b/llvm/lib/Analysis/DemandedBits.cpp index 461fd7239905..dd11b0b02bf8 100644 --- a/llvm/lib/Analysis/DemandedBits.cpp +++ b/llvm/lib/Analysis/DemandedBits.cpp @@ -80,7 +80,7 @@ void DemandedBitsWrapperPass::print(raw_ostream &OS, const Module *M) const {  static bool isAlwaysLive(Instruction *I) {    return I->isTerminator() || isa<DbgInfoIntrinsic>(I) || I->isEHPad() || -         I->mayHaveSideEffects(); +         I->mayHaveSideEffects() || !I->willReturn();  }  void DemandedBits::determineLiveOperandBits( diff --git a/llvm/lib/Analysis/IVDescriptors.cpp b/llvm/lib/Analysis/IVDescriptors.cpp index 7f311d8f9a2b..94a24ccf2155 100644 --- a/llvm/lib/Analysis/IVDescriptors.cpp +++ b/llvm/lib/Analysis/IVDescriptors.cpp @@ -243,11 +243,14 @@ bool RecurrenceDescriptor::AddReductionVar(PHINode *Phi, RecurKind Kind,    if (RecurrenceType->isFloatingPointTy()) {      if (!isFloatingPointRecurrenceKind(Kind))        return false; -  } else { +  } else if (RecurrenceType->isIntegerTy()) {      if (!isIntegerRecurrenceKind(Kind))        return false;      if (isArithmeticRecurrenceKind(Kind))        Start = lookThroughAnd(Phi, RecurrenceType, VisitedInsts, CastInsts); +  } else { +    // Pointer min/max may exist, but it is not supported as a reduction op. +    return false;    }    Worklist.push_back(Start); diff --git a/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp b/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp index 7d97fc5da9b0..268acb682cf1 100644 --- a/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp +++ b/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp @@ -737,3 +737,84 @@ bool TypeBasedAAWrapperPass::doFinalization(Module &M) {  void TypeBasedAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {    AU.setPreservesAll();  } + +MDNode *AAMDNodes::ShiftTBAA(MDNode *MD, size_t Offset) { +  // Fast path if there's no offset +  if (Offset == 0) +    return MD; +  // Fast path if there's no path tbaa node (and thus scalar) +  if (!isStructPathTBAA(MD)) +    return MD; + +  TBAAStructTagNode Tag(MD); +  SmallVector<Metadata *, 5> Sub; +  Sub.push_back(MD->getOperand(0)); +  Sub.push_back(MD->getOperand(1)); +  ConstantInt *InnerOffset = mdconst::extract<ConstantInt>(MD->getOperand(2)); + +  if (Tag.isNewFormat()) { +    ConstantInt *InnerSize = mdconst::extract<ConstantInt>(MD->getOperand(3)); + +    if (InnerOffset->getZExtValue() + InnerSize->getZExtValue() <= Offset) { +      return nullptr; +    } + +    uint64_t NewSize = InnerSize->getZExtValue(); +    uint64_t NewOffset = InnerOffset->getZExtValue() - Offset; +    if (InnerOffset->getZExtValue() < Offset) { +      NewOffset = 0; +      NewSize -= Offset - InnerOffset->getZExtValue(); +    } + +    Sub.push_back(ConstantAsMetadata::get( +        ConstantInt::get(InnerOffset->getType(), NewOffset))); + +    Sub.push_back(ConstantAsMetadata::get( +        ConstantInt::get(InnerSize->getType(), NewSize))); + +    // immutable type +    if (MD->getNumOperands() >= 5) +      Sub.push_back(MD->getOperand(4)); +  } else { +    if (InnerOffset->getZExtValue() < Offset) +      return nullptr; + +    Sub.push_back(ConstantAsMetadata::get(ConstantInt::get( +        InnerOffset->getType(), InnerOffset->getZExtValue() - Offset))); + +    // immutable type +    if (MD->getNumOperands() >= 4) +      Sub.push_back(MD->getOperand(3)); +  } +  return MDNode::get(MD->getContext(), Sub); +} + +MDNode *AAMDNodes::ShiftTBAAStruct(MDNode *MD, size_t Offset) { +  // Fast path if there's no offset +  if (Offset == 0) +    return MD; +  SmallVector<Metadata *, 3> Sub; +  for (size_t i = 0, size = MD->getNumOperands(); i < size; i += 3) { +    ConstantInt *InnerOffset = mdconst::extract<ConstantInt>(MD->getOperand(i)); +    ConstantInt *InnerSize = +        mdconst::extract<ConstantInt>(MD->getOperand(i + 1)); +    // Don't include any triples that aren't in bounds +    if (InnerOffset->getZExtValue() + InnerSize->getZExtValue() <= Offset) +      continue; + +    uint64_t NewSize = InnerSize->getZExtValue(); +    uint64_t NewOffset = InnerOffset->getZExtValue() - Offset; +    if (InnerOffset->getZExtValue() < Offset) { +      NewOffset = 0; +      NewSize -= Offset - InnerOffset->getZExtValue(); +    } + +    // Shift the offset of the triple +    Sub.push_back(ConstantAsMetadata::get( +        ConstantInt::get(InnerOffset->getType(), NewOffset))); +    Sub.push_back(ConstantAsMetadata::get( +        ConstantInt::get(InnerSize->getType(), NewSize))); +    Sub.push_back(MD->getOperand(i + 2)); +  } +  return MDNode::get(MD->getContext(), Sub); +}
\ No newline at end of file diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 5600a3b33750..e174c5efe424 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -5018,36 +5018,14 @@ bool llvm::isGuaranteedToTransferExecutionToSuccessor(const Instruction *I) {    // arbitrary length of time, but programs aren't allowed to rely on that.    // If there is no successor, then execution can't transfer to it. -  if (const auto *CRI = dyn_cast<CleanupReturnInst>(I)) -    return !CRI->unwindsToCaller(); -  if (const auto *CatchSwitch = dyn_cast<CatchSwitchInst>(I)) -    return !CatchSwitch->unwindsToCaller(); -  if (isa<ResumeInst>(I)) -    return false;    if (isa<ReturnInst>(I))      return false;    if (isa<UnreachableInst>(I))      return false; -  // Calls can throw, or contain an infinite loop, or kill the process. -  if (const auto *CB = dyn_cast<CallBase>(I)) { -    // Call sites that throw have implicit non-local control flow. -    if (!CB->doesNotThrow()) -      return false; - -    // A function which doens't throw and has "willreturn" attribute will -    // always return. -    if (CB->hasFnAttr(Attribute::WillReturn)) -      return true; - -    // FIXME: Temporarily assume that all side-effect free intrinsics will -    // return. Remove this workaround once all intrinsics are appropriately -    // annotated. -    return isa<IntrinsicInst>(CB) && CB->onlyReadsMemory(); -  } - -  // Other instructions return normally. -  return true; +  // An instruction that returns without throwing must transfer control flow +  // to a successor. +  return !I->mayThrow() && I->willReturn();  }  bool llvm::isGuaranteedToTransferExecutionToSuccessor(const BasicBlock *BB) { | 
