1 //===- AttributorAttributes.cpp - Attributes for Attributor deduction -----===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // See the Attributor.h file comment and the class descriptions in that file for 10 // more information. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Transforms/IPO/Attributor.h" 15 16 #include "llvm/ADT/APInt.h" 17 #include "llvm/ADT/ArrayRef.h" 18 #include "llvm/ADT/DenseMapInfo.h" 19 #include "llvm/ADT/MapVector.h" 20 #include "llvm/ADT/SCCIterator.h" 21 #include "llvm/ADT/STLExtras.h" 22 #include "llvm/ADT/SetOperations.h" 23 #include "llvm/ADT/SetVector.h" 24 #include "llvm/ADT/SmallPtrSet.h" 25 #include "llvm/ADT/SmallVector.h" 26 #include "llvm/ADT/Statistic.h" 27 #include "llvm/Analysis/AliasAnalysis.h" 28 #include "llvm/Analysis/AssumeBundleQueries.h" 29 #include "llvm/Analysis/AssumptionCache.h" 30 #include "llvm/Analysis/CaptureTracking.h" 31 #include "llvm/Analysis/CycleAnalysis.h" 32 #include "llvm/Analysis/InstructionSimplify.h" 33 #include "llvm/Analysis/LazyValueInfo.h" 34 #include "llvm/Analysis/MemoryBuiltins.h" 35 #include "llvm/Analysis/OptimizationRemarkEmitter.h" 36 #include "llvm/Analysis/ScalarEvolution.h" 37 #include "llvm/Analysis/TargetTransformInfo.h" 38 #include "llvm/Analysis/ValueTracking.h" 39 #include "llvm/IR/Argument.h" 40 #include "llvm/IR/Assumptions.h" 41 #include "llvm/IR/BasicBlock.h" 42 #include "llvm/IR/Constant.h" 43 #include "llvm/IR/Constants.h" 44 #include "llvm/IR/DataLayout.h" 45 #include "llvm/IR/DerivedTypes.h" 46 #include "llvm/IR/GlobalValue.h" 47 #include "llvm/IR/IRBuilder.h" 48 #include "llvm/IR/InlineAsm.h" 49 #include "llvm/IR/InstrTypes.h" 50 #include "llvm/IR/Instruction.h" 51 #include "llvm/IR/Instructions.h" 52 #include "llvm/IR/IntrinsicInst.h" 53 #include "llvm/IR/IntrinsicsAMDGPU.h" 54 #include "llvm/IR/IntrinsicsNVPTX.h" 55 #include "llvm/IR/NoFolder.h" 56 #include "llvm/IR/Value.h" 57 #include "llvm/IR/ValueHandle.h" 58 #include "llvm/Support/Alignment.h" 59 #include "llvm/Support/Casting.h" 60 #include "llvm/Support/CommandLine.h" 61 #include "llvm/Support/ErrorHandling.h" 62 #include "llvm/Support/GraphWriter.h" 63 #include "llvm/Support/MathExtras.h" 64 #include "llvm/Support/raw_ostream.h" 65 #include "llvm/Transforms/Utils/Local.h" 66 #include "llvm/Transforms/Utils/ValueMapper.h" 67 #include <cassert> 68 #include <numeric> 69 #include <optional> 70 71 using namespace llvm; 72 73 #define DEBUG_TYPE "attributor" 74 75 static cl::opt<bool> ManifestInternal( 76 "attributor-manifest-internal", cl::Hidden, 77 cl::desc("Manifest Attributor internal string attributes."), 78 cl::init(false)); 79 80 static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128), 81 cl::Hidden); 82 83 template <> 84 unsigned llvm::PotentialConstantIntValuesState::MaxPotentialValues = 0; 85 86 template <> unsigned llvm::PotentialLLVMValuesState::MaxPotentialValues = -1; 87 88 static cl::opt<unsigned, true> MaxPotentialValues( 89 "attributor-max-potential-values", cl::Hidden, 90 cl::desc("Maximum number of potential values to be " 91 "tracked for each position."), 92 cl::location(llvm::PotentialConstantIntValuesState::MaxPotentialValues), 93 cl::init(7)); 94 95 static cl::opt<int> MaxPotentialValuesIterations( 96 "attributor-max-potential-values-iterations", cl::Hidden, 97 cl::desc( 98 "Maximum number of iterations we keep dismantling potential values."), 99 cl::init(64)); 100 101 STATISTIC(NumAAs, "Number of abstract attributes created"); 102 103 // Some helper macros to deal with statistics tracking. 104 // 105 // Usage: 106 // For simple IR attribute tracking overload trackStatistics in the abstract 107 // attribute and choose the right STATS_DECLTRACK_********* macro, 108 // e.g.,: 109 // void trackStatistics() const override { 110 // STATS_DECLTRACK_ARG_ATTR(returned) 111 // } 112 // If there is a single "increment" side one can use the macro 113 // STATS_DECLTRACK with a custom message. If there are multiple increment 114 // sides, STATS_DECL and STATS_TRACK can also be used separately. 115 // 116 #define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \ 117 ("Number of " #TYPE " marked '" #NAME "'") 118 #define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME 119 #define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG); 120 #define STATS_DECL(NAME, TYPE, MSG) \ 121 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG); 122 #define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE)); 123 #define STATS_DECLTRACK(NAME, TYPE, MSG) \ 124 { \ 125 STATS_DECL(NAME, TYPE, MSG) \ 126 STATS_TRACK(NAME, TYPE) \ 127 } 128 #define STATS_DECLTRACK_ARG_ATTR(NAME) \ 129 STATS_DECLTRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME)) 130 #define STATS_DECLTRACK_CSARG_ATTR(NAME) \ 131 STATS_DECLTRACK(NAME, CSArguments, \ 132 BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME)) 133 #define STATS_DECLTRACK_FN_ATTR(NAME) \ 134 STATS_DECLTRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME)) 135 #define STATS_DECLTRACK_CS_ATTR(NAME) \ 136 STATS_DECLTRACK(NAME, CS, BUILD_STAT_MSG_IR_ATTR(call site, NAME)) 137 #define STATS_DECLTRACK_FNRET_ATTR(NAME) \ 138 STATS_DECLTRACK(NAME, FunctionReturn, \ 139 BUILD_STAT_MSG_IR_ATTR(function returns, NAME)) 140 #define STATS_DECLTRACK_CSRET_ATTR(NAME) \ 141 STATS_DECLTRACK(NAME, CSReturn, \ 142 BUILD_STAT_MSG_IR_ATTR(call site returns, NAME)) 143 #define STATS_DECLTRACK_FLOATING_ATTR(NAME) \ 144 STATS_DECLTRACK(NAME, Floating, \ 145 ("Number of floating values known to be '" #NAME "'")) 146 147 // Specialization of the operator<< for abstract attributes subclasses. This 148 // disambiguates situations where multiple operators are applicable. 149 namespace llvm { 150 #define PIPE_OPERATOR(CLASS) \ 151 raw_ostream &operator<<(raw_ostream &OS, const CLASS &AA) { \ 152 return OS << static_cast<const AbstractAttribute &>(AA); \ 153 } 154 155 PIPE_OPERATOR(AAIsDead) 156 PIPE_OPERATOR(AANoUnwind) 157 PIPE_OPERATOR(AANoSync) 158 PIPE_OPERATOR(AANoRecurse) 159 PIPE_OPERATOR(AAWillReturn) 160 PIPE_OPERATOR(AANoReturn) 161 PIPE_OPERATOR(AAReturnedValues) 162 PIPE_OPERATOR(AANonNull) 163 PIPE_OPERATOR(AANoAlias) 164 PIPE_OPERATOR(AADereferenceable) 165 PIPE_OPERATOR(AAAlign) 166 PIPE_OPERATOR(AAInstanceInfo) 167 PIPE_OPERATOR(AANoCapture) 168 PIPE_OPERATOR(AAValueSimplify) 169 PIPE_OPERATOR(AANoFree) 170 PIPE_OPERATOR(AAHeapToStack) 171 PIPE_OPERATOR(AAIntraFnReachability) 172 PIPE_OPERATOR(AAMemoryBehavior) 173 PIPE_OPERATOR(AAMemoryLocation) 174 PIPE_OPERATOR(AAValueConstantRange) 175 PIPE_OPERATOR(AAPrivatizablePtr) 176 PIPE_OPERATOR(AAUndefinedBehavior) 177 PIPE_OPERATOR(AAPotentialConstantValues) 178 PIPE_OPERATOR(AAPotentialValues) 179 PIPE_OPERATOR(AANoUndef) 180 PIPE_OPERATOR(AACallEdges) 181 PIPE_OPERATOR(AAInterFnReachability) 182 PIPE_OPERATOR(AAPointerInfo) 183 PIPE_OPERATOR(AAAssumptionInfo) 184 PIPE_OPERATOR(AAUnderlyingObjects) 185 186 #undef PIPE_OPERATOR 187 188 template <> 189 ChangeStatus clampStateAndIndicateChange<DerefState>(DerefState &S, 190 const DerefState &R) { 191 ChangeStatus CS0 = 192 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState); 193 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState); 194 return CS0 | CS1; 195 } 196 197 } // namespace llvm 198 199 /// Checks if a type could have padding bytes. 200 static bool isDenselyPacked(Type *Ty, const DataLayout &DL) { 201 // There is no size information, so be conservative. 202 if (!Ty->isSized()) 203 return false; 204 205 // If the alloc size is not equal to the storage size, then there are padding 206 // bytes. For x86_fp80 on x86-64, size: 80 alloc size: 128. 207 if (DL.getTypeSizeInBits(Ty) != DL.getTypeAllocSizeInBits(Ty)) 208 return false; 209 210 // FIXME: This isn't the right way to check for padding in vectors with 211 // non-byte-size elements. 212 if (VectorType *SeqTy = dyn_cast<VectorType>(Ty)) 213 return isDenselyPacked(SeqTy->getElementType(), DL); 214 215 // For array types, check for padding within members. 216 if (ArrayType *SeqTy = dyn_cast<ArrayType>(Ty)) 217 return isDenselyPacked(SeqTy->getElementType(), DL); 218 219 if (!isa<StructType>(Ty)) 220 return true; 221 222 // Check for padding within and between elements of a struct. 223 StructType *StructTy = cast<StructType>(Ty); 224 const StructLayout *Layout = DL.getStructLayout(StructTy); 225 uint64_t StartPos = 0; 226 for (unsigned I = 0, E = StructTy->getNumElements(); I < E; ++I) { 227 Type *ElTy = StructTy->getElementType(I); 228 if (!isDenselyPacked(ElTy, DL)) 229 return false; 230 if (StartPos != Layout->getElementOffsetInBits(I)) 231 return false; 232 StartPos += DL.getTypeAllocSizeInBits(ElTy); 233 } 234 235 return true; 236 } 237 238 /// Get pointer operand of memory accessing instruction. If \p I is 239 /// not a memory accessing instruction, return nullptr. If \p AllowVolatile, 240 /// is set to false and the instruction is volatile, return nullptr. 241 static const Value *getPointerOperand(const Instruction *I, 242 bool AllowVolatile) { 243 if (!AllowVolatile && I->isVolatile()) 244 return nullptr; 245 246 if (auto *LI = dyn_cast<LoadInst>(I)) { 247 return LI->getPointerOperand(); 248 } 249 250 if (auto *SI = dyn_cast<StoreInst>(I)) { 251 return SI->getPointerOperand(); 252 } 253 254 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(I)) { 255 return CXI->getPointerOperand(); 256 } 257 258 if (auto *RMWI = dyn_cast<AtomicRMWInst>(I)) { 259 return RMWI->getPointerOperand(); 260 } 261 262 return nullptr; 263 } 264 265 /// Helper function to create a pointer of type \p ResTy, based on \p Ptr, and 266 /// advanced by \p Offset bytes. To aid later analysis the method tries to build 267 /// getelement pointer instructions that traverse the natural type of \p Ptr if 268 /// possible. If that fails, the remaining offset is adjusted byte-wise, hence 269 /// through a cast to i8*. 270 /// 271 /// TODO: This could probably live somewhere more prominantly if it doesn't 272 /// already exist. 273 static Value *constructPointer(Type *ResTy, Type *PtrElemTy, Value *Ptr, 274 int64_t Offset, IRBuilder<NoFolder> &IRB, 275 const DataLayout &DL) { 276 assert(Offset >= 0 && "Negative offset not supported yet!"); 277 LLVM_DEBUG(dbgs() << "Construct pointer: " << *Ptr << " + " << Offset 278 << "-bytes as " << *ResTy << "\n"); 279 280 if (Offset) { 281 Type *Ty = PtrElemTy; 282 APInt IntOffset(DL.getIndexTypeSizeInBits(Ptr->getType()), Offset); 283 SmallVector<APInt> IntIndices = DL.getGEPIndicesForOffset(Ty, IntOffset); 284 285 SmallVector<Value *, 4> ValIndices; 286 std::string GEPName = Ptr->getName().str(); 287 for (const APInt &Index : IntIndices) { 288 ValIndices.push_back(IRB.getInt(Index)); 289 GEPName += "." + std::to_string(Index.getZExtValue()); 290 } 291 292 // Create a GEP for the indices collected above. 293 Ptr = IRB.CreateGEP(PtrElemTy, Ptr, ValIndices, GEPName); 294 295 // If an offset is left we use byte-wise adjustment. 296 if (IntOffset != 0) { 297 Ptr = IRB.CreateBitCast(Ptr, IRB.getInt8PtrTy()); 298 Ptr = IRB.CreateGEP(IRB.getInt8Ty(), Ptr, IRB.getInt(IntOffset), 299 GEPName + ".b" + Twine(IntOffset.getZExtValue())); 300 } 301 } 302 303 // Ensure the result has the requested type. 304 Ptr = IRB.CreatePointerBitCastOrAddrSpaceCast(Ptr, ResTy, 305 Ptr->getName() + ".cast"); 306 307 LLVM_DEBUG(dbgs() << "Constructed pointer: " << *Ptr << "\n"); 308 return Ptr; 309 } 310 311 static const Value * 312 stripAndAccumulateOffsets(Attributor &A, const AbstractAttribute &QueryingAA, 313 const Value *Val, const DataLayout &DL, APInt &Offset, 314 bool GetMinOffset, bool AllowNonInbounds, 315 bool UseAssumed = false) { 316 317 auto AttributorAnalysis = [&](Value &V, APInt &ROffset) -> bool { 318 const IRPosition &Pos = IRPosition::value(V); 319 // Only track dependence if we are going to use the assumed info. 320 const AAValueConstantRange &ValueConstantRangeAA = 321 A.getAAFor<AAValueConstantRange>(QueryingAA, Pos, 322 UseAssumed ? DepClassTy::OPTIONAL 323 : DepClassTy::NONE); 324 ConstantRange Range = UseAssumed ? ValueConstantRangeAA.getAssumed() 325 : ValueConstantRangeAA.getKnown(); 326 if (Range.isFullSet()) 327 return false; 328 329 // We can only use the lower part of the range because the upper part can 330 // be higher than what the value can really be. 331 if (GetMinOffset) 332 ROffset = Range.getSignedMin(); 333 else 334 ROffset = Range.getSignedMax(); 335 return true; 336 }; 337 338 return Val->stripAndAccumulateConstantOffsets(DL, Offset, AllowNonInbounds, 339 /* AllowInvariant */ true, 340 AttributorAnalysis); 341 } 342 343 static const Value * 344 getMinimalBaseOfPointer(Attributor &A, const AbstractAttribute &QueryingAA, 345 const Value *Ptr, int64_t &BytesOffset, 346 const DataLayout &DL, bool AllowNonInbounds = false) { 347 APInt OffsetAPInt(DL.getIndexTypeSizeInBits(Ptr->getType()), 0); 348 const Value *Base = 349 stripAndAccumulateOffsets(A, QueryingAA, Ptr, DL, OffsetAPInt, 350 /* GetMinOffset */ true, AllowNonInbounds); 351 352 BytesOffset = OffsetAPInt.getSExtValue(); 353 return Base; 354 } 355 356 /// Clamp the information known for all returned values of a function 357 /// (identified by \p QueryingAA) into \p S. 358 template <typename AAType, typename StateType = typename AAType::StateType> 359 static void clampReturnedValueStates( 360 Attributor &A, const AAType &QueryingAA, StateType &S, 361 const IRPosition::CallBaseContext *CBContext = nullptr) { 362 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for " 363 << QueryingAA << " into " << S << "\n"); 364 365 assert((QueryingAA.getIRPosition().getPositionKind() == 366 IRPosition::IRP_RETURNED || 367 QueryingAA.getIRPosition().getPositionKind() == 368 IRPosition::IRP_CALL_SITE_RETURNED) && 369 "Can only clamp returned value states for a function returned or call " 370 "site returned position!"); 371 372 // Use an optional state as there might not be any return values and we want 373 // to join (IntegerState::operator&) the state of all there are. 374 std::optional<StateType> T; 375 376 // Callback for each possibly returned value. 377 auto CheckReturnValue = [&](Value &RV) -> bool { 378 const IRPosition &RVPos = IRPosition::value(RV, CBContext); 379 const AAType &AA = 380 A.getAAFor<AAType>(QueryingAA, RVPos, DepClassTy::REQUIRED); 381 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV << " AA: " << AA.getAsStr() 382 << " @ " << RVPos << "\n"); 383 const StateType &AAS = AA.getState(); 384 if (!T) 385 T = StateType::getBestState(AAS); 386 *T &= AAS; 387 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T 388 << "\n"); 389 return T->isValidState(); 390 }; 391 392 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA)) 393 S.indicatePessimisticFixpoint(); 394 else if (T) 395 S ^= *T; 396 } 397 398 namespace { 399 /// Helper class for generic deduction: return value -> returned position. 400 template <typename AAType, typename BaseType, 401 typename StateType = typename BaseType::StateType, 402 bool PropagateCallBaseContext = false> 403 struct AAReturnedFromReturnedValues : public BaseType { 404 AAReturnedFromReturnedValues(const IRPosition &IRP, Attributor &A) 405 : BaseType(IRP, A) {} 406 407 /// See AbstractAttribute::updateImpl(...). 408 ChangeStatus updateImpl(Attributor &A) override { 409 StateType S(StateType::getBestState(this->getState())); 410 clampReturnedValueStates<AAType, StateType>( 411 A, *this, S, 412 PropagateCallBaseContext ? this->getCallBaseContext() : nullptr); 413 // TODO: If we know we visited all returned values, thus no are assumed 414 // dead, we can take the known information from the state T. 415 return clampStateAndIndicateChange<StateType>(this->getState(), S); 416 } 417 }; 418 419 /// Clamp the information known at all call sites for a given argument 420 /// (identified by \p QueryingAA) into \p S. 421 template <typename AAType, typename StateType = typename AAType::StateType> 422 static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA, 423 StateType &S) { 424 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for " 425 << QueryingAA << " into " << S << "\n"); 426 427 assert(QueryingAA.getIRPosition().getPositionKind() == 428 IRPosition::IRP_ARGUMENT && 429 "Can only clamp call site argument states for an argument position!"); 430 431 // Use an optional state as there might not be any return values and we want 432 // to join (IntegerState::operator&) the state of all there are. 433 std::optional<StateType> T; 434 435 // The argument number which is also the call site argument number. 436 unsigned ArgNo = QueryingAA.getIRPosition().getCallSiteArgNo(); 437 438 auto CallSiteCheck = [&](AbstractCallSite ACS) { 439 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo); 440 // Check if a coresponding argument was found or if it is on not associated 441 // (which can happen for callback calls). 442 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID) 443 return false; 444 445 const AAType &AA = 446 A.getAAFor<AAType>(QueryingAA, ACSArgPos, DepClassTy::REQUIRED); 447 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction() 448 << " AA: " << AA.getAsStr() << " @" << ACSArgPos << "\n"); 449 const StateType &AAS = AA.getState(); 450 if (!T) 451 T = StateType::getBestState(AAS); 452 *T &= AAS; 453 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T 454 << "\n"); 455 return T->isValidState(); 456 }; 457 458 bool UsedAssumedInformation = false; 459 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true, 460 UsedAssumedInformation)) 461 S.indicatePessimisticFixpoint(); 462 else if (T) 463 S ^= *T; 464 } 465 466 /// This function is the bridge between argument position and the call base 467 /// context. 468 template <typename AAType, typename BaseType, 469 typename StateType = typename AAType::StateType> 470 bool getArgumentStateFromCallBaseContext(Attributor &A, 471 BaseType &QueryingAttribute, 472 IRPosition &Pos, StateType &State) { 473 assert((Pos.getPositionKind() == IRPosition::IRP_ARGUMENT) && 474 "Expected an 'argument' position !"); 475 const CallBase *CBContext = Pos.getCallBaseContext(); 476 if (!CBContext) 477 return false; 478 479 int ArgNo = Pos.getCallSiteArgNo(); 480 assert(ArgNo >= 0 && "Invalid Arg No!"); 481 482 const auto &AA = A.getAAFor<AAType>( 483 QueryingAttribute, IRPosition::callsite_argument(*CBContext, ArgNo), 484 DepClassTy::REQUIRED); 485 const StateType &CBArgumentState = 486 static_cast<const StateType &>(AA.getState()); 487 488 LLVM_DEBUG(dbgs() << "[Attributor] Briding Call site context to argument" 489 << "Position:" << Pos << "CB Arg state:" << CBArgumentState 490 << "\n"); 491 492 // NOTE: If we want to do call site grouping it should happen here. 493 State ^= CBArgumentState; 494 return true; 495 } 496 497 /// Helper class for generic deduction: call site argument -> argument position. 498 template <typename AAType, typename BaseType, 499 typename StateType = typename AAType::StateType, 500 bool BridgeCallBaseContext = false> 501 struct AAArgumentFromCallSiteArguments : public BaseType { 502 AAArgumentFromCallSiteArguments(const IRPosition &IRP, Attributor &A) 503 : BaseType(IRP, A) {} 504 505 /// See AbstractAttribute::updateImpl(...). 506 ChangeStatus updateImpl(Attributor &A) override { 507 StateType S = StateType::getBestState(this->getState()); 508 509 if (BridgeCallBaseContext) { 510 bool Success = 511 getArgumentStateFromCallBaseContext<AAType, BaseType, StateType>( 512 A, *this, this->getIRPosition(), S); 513 if (Success) 514 return clampStateAndIndicateChange<StateType>(this->getState(), S); 515 } 516 clampCallSiteArgumentStates<AAType, StateType>(A, *this, S); 517 518 // TODO: If we know we visited all incoming values, thus no are assumed 519 // dead, we can take the known information from the state T. 520 return clampStateAndIndicateChange<StateType>(this->getState(), S); 521 } 522 }; 523 524 /// Helper class for generic replication: function returned -> cs returned. 525 template <typename AAType, typename BaseType, 526 typename StateType = typename BaseType::StateType, 527 bool IntroduceCallBaseContext = false> 528 struct AACallSiteReturnedFromReturned : public BaseType { 529 AACallSiteReturnedFromReturned(const IRPosition &IRP, Attributor &A) 530 : BaseType(IRP, A) {} 531 532 /// See AbstractAttribute::updateImpl(...). 533 ChangeStatus updateImpl(Attributor &A) override { 534 assert(this->getIRPosition().getPositionKind() == 535 IRPosition::IRP_CALL_SITE_RETURNED && 536 "Can only wrap function returned positions for call site returned " 537 "positions!"); 538 auto &S = this->getState(); 539 540 const Function *AssociatedFunction = 541 this->getIRPosition().getAssociatedFunction(); 542 if (!AssociatedFunction) 543 return S.indicatePessimisticFixpoint(); 544 545 CallBase &CBContext = cast<CallBase>(this->getAnchorValue()); 546 if (IntroduceCallBaseContext) 547 LLVM_DEBUG(dbgs() << "[Attributor] Introducing call base context:" 548 << CBContext << "\n"); 549 550 IRPosition FnPos = IRPosition::returned( 551 *AssociatedFunction, IntroduceCallBaseContext ? &CBContext : nullptr); 552 const AAType &AA = A.getAAFor<AAType>(*this, FnPos, DepClassTy::REQUIRED); 553 return clampStateAndIndicateChange(S, AA.getState()); 554 } 555 }; 556 557 /// Helper function to accumulate uses. 558 template <class AAType, typename StateType = typename AAType::StateType> 559 static void followUsesInContext(AAType &AA, Attributor &A, 560 MustBeExecutedContextExplorer &Explorer, 561 const Instruction *CtxI, 562 SetVector<const Use *> &Uses, 563 StateType &State) { 564 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI); 565 for (unsigned u = 0; u < Uses.size(); ++u) { 566 const Use *U = Uses[u]; 567 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) { 568 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd); 569 if (Found && AA.followUseInMBEC(A, U, UserI, State)) 570 for (const Use &Us : UserI->uses()) 571 Uses.insert(&Us); 572 } 573 } 574 } 575 576 /// Use the must-be-executed-context around \p I to add information into \p S. 577 /// The AAType class is required to have `followUseInMBEC` method with the 578 /// following signature and behaviour: 579 /// 580 /// bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I) 581 /// U - Underlying use. 582 /// I - The user of the \p U. 583 /// Returns true if the value should be tracked transitively. 584 /// 585 template <class AAType, typename StateType = typename AAType::StateType> 586 static void followUsesInMBEC(AAType &AA, Attributor &A, StateType &S, 587 Instruction &CtxI) { 588 589 // Container for (transitive) uses of the associated value. 590 SetVector<const Use *> Uses; 591 for (const Use &U : AA.getIRPosition().getAssociatedValue().uses()) 592 Uses.insert(&U); 593 594 MustBeExecutedContextExplorer &Explorer = 595 A.getInfoCache().getMustBeExecutedContextExplorer(); 596 597 followUsesInContext<AAType>(AA, A, Explorer, &CtxI, Uses, S); 598 599 if (S.isAtFixpoint()) 600 return; 601 602 SmallVector<const BranchInst *, 4> BrInsts; 603 auto Pred = [&](const Instruction *I) { 604 if (const BranchInst *Br = dyn_cast<BranchInst>(I)) 605 if (Br->isConditional()) 606 BrInsts.push_back(Br); 607 return true; 608 }; 609 610 // Here, accumulate conditional branch instructions in the context. We 611 // explore the child paths and collect the known states. The disjunction of 612 // those states can be merged to its own state. Let ParentState_i be a state 613 // to indicate the known information for an i-th branch instruction in the 614 // context. ChildStates are created for its successors respectively. 615 // 616 // ParentS_1 = ChildS_{1, 1} /\ ChildS_{1, 2} /\ ... /\ ChildS_{1, n_1} 617 // ParentS_2 = ChildS_{2, 1} /\ ChildS_{2, 2} /\ ... /\ ChildS_{2, n_2} 618 // ... 619 // ParentS_m = ChildS_{m, 1} /\ ChildS_{m, 2} /\ ... /\ ChildS_{m, n_m} 620 // 621 // Known State |= ParentS_1 \/ ParentS_2 \/... \/ ParentS_m 622 // 623 // FIXME: Currently, recursive branches are not handled. For example, we 624 // can't deduce that ptr must be dereferenced in below function. 625 // 626 // void f(int a, int c, int *ptr) { 627 // if(a) 628 // if (b) { 629 // *ptr = 0; 630 // } else { 631 // *ptr = 1; 632 // } 633 // else { 634 // if (b) { 635 // *ptr = 0; 636 // } else { 637 // *ptr = 1; 638 // } 639 // } 640 // } 641 642 Explorer.checkForAllContext(&CtxI, Pred); 643 for (const BranchInst *Br : BrInsts) { 644 StateType ParentState; 645 646 // The known state of the parent state is a conjunction of children's 647 // known states so it is initialized with a best state. 648 ParentState.indicateOptimisticFixpoint(); 649 650 for (const BasicBlock *BB : Br->successors()) { 651 StateType ChildState; 652 653 size_t BeforeSize = Uses.size(); 654 followUsesInContext(AA, A, Explorer, &BB->front(), Uses, ChildState); 655 656 // Erase uses which only appear in the child. 657 for (auto It = Uses.begin() + BeforeSize; It != Uses.end();) 658 It = Uses.erase(It); 659 660 ParentState &= ChildState; 661 } 662 663 // Use only known state. 664 S += ParentState; 665 } 666 } 667 } // namespace 668 669 /// ------------------------ PointerInfo --------------------------------------- 670 671 namespace llvm { 672 namespace AA { 673 namespace PointerInfo { 674 675 struct State; 676 677 } // namespace PointerInfo 678 } // namespace AA 679 680 /// Helper for AA::PointerInfo::Access DenseMap/Set usage. 681 template <> 682 struct DenseMapInfo<AAPointerInfo::Access> : DenseMapInfo<Instruction *> { 683 using Access = AAPointerInfo::Access; 684 static inline Access getEmptyKey(); 685 static inline Access getTombstoneKey(); 686 static unsigned getHashValue(const Access &A); 687 static bool isEqual(const Access &LHS, const Access &RHS); 688 }; 689 690 /// Helper that allows RangeTy as a key in a DenseMap. 691 template <> struct DenseMapInfo<AA::RangeTy> { 692 static inline AA::RangeTy getEmptyKey() { 693 auto EmptyKey = DenseMapInfo<int64_t>::getEmptyKey(); 694 return AA::RangeTy{EmptyKey, EmptyKey}; 695 } 696 697 static inline AA::RangeTy getTombstoneKey() { 698 auto TombstoneKey = DenseMapInfo<int64_t>::getTombstoneKey(); 699 return AA::RangeTy{TombstoneKey, TombstoneKey}; 700 } 701 702 static unsigned getHashValue(const AA::RangeTy &Range) { 703 return detail::combineHashValue( 704 DenseMapInfo<int64_t>::getHashValue(Range.Offset), 705 DenseMapInfo<int64_t>::getHashValue(Range.Size)); 706 } 707 708 static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B) { 709 return A == B; 710 } 711 }; 712 713 /// Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign 714 /// but the instruction 715 struct AccessAsInstructionInfo : DenseMapInfo<Instruction *> { 716 using Base = DenseMapInfo<Instruction *>; 717 using Access = AAPointerInfo::Access; 718 static inline Access getEmptyKey(); 719 static inline Access getTombstoneKey(); 720 static unsigned getHashValue(const Access &A); 721 static bool isEqual(const Access &LHS, const Access &RHS); 722 }; 723 724 } // namespace llvm 725 726 /// A type to track pointer/struct usage and accesses for AAPointerInfo. 727 struct AA::PointerInfo::State : public AbstractState { 728 /// Return the best possible representable state. 729 static State getBestState(const State &SIS) { return State(); } 730 731 /// Return the worst possible representable state. 732 static State getWorstState(const State &SIS) { 733 State R; 734 R.indicatePessimisticFixpoint(); 735 return R; 736 } 737 738 State() = default; 739 State(State &&SIS) = default; 740 741 const State &getAssumed() const { return *this; } 742 743 /// See AbstractState::isValidState(). 744 bool isValidState() const override { return BS.isValidState(); } 745 746 /// See AbstractState::isAtFixpoint(). 747 bool isAtFixpoint() const override { return BS.isAtFixpoint(); } 748 749 /// See AbstractState::indicateOptimisticFixpoint(). 750 ChangeStatus indicateOptimisticFixpoint() override { 751 BS.indicateOptimisticFixpoint(); 752 return ChangeStatus::UNCHANGED; 753 } 754 755 /// See AbstractState::indicatePessimisticFixpoint(). 756 ChangeStatus indicatePessimisticFixpoint() override { 757 BS.indicatePessimisticFixpoint(); 758 return ChangeStatus::CHANGED; 759 } 760 761 State &operator=(const State &R) { 762 if (this == &R) 763 return *this; 764 BS = R.BS; 765 AccessList = R.AccessList; 766 OffsetBins = R.OffsetBins; 767 RemoteIMap = R.RemoteIMap; 768 return *this; 769 } 770 771 State &operator=(State &&R) { 772 if (this == &R) 773 return *this; 774 std::swap(BS, R.BS); 775 std::swap(AccessList, R.AccessList); 776 std::swap(OffsetBins, R.OffsetBins); 777 std::swap(RemoteIMap, R.RemoteIMap); 778 return *this; 779 } 780 781 /// Add a new Access to the state at offset \p Offset and with size \p Size. 782 /// The access is associated with \p I, writes \p Content (if anything), and 783 /// is of kind \p Kind. If an Access already exists for the same \p I and same 784 /// \p RemoteI, the two are combined, potentially losing information about 785 /// offset and size. The resulting access must now be moved from its original 786 /// OffsetBin to the bin for its new offset. 787 /// 788 /// \Returns CHANGED, if the state changed, UNCHANGED otherwise. 789 ChangeStatus addAccess(Attributor &A, const AAPointerInfo::RangeList &Ranges, 790 Instruction &I, std::optional<Value *> Content, 791 AAPointerInfo::AccessKind Kind, Type *Ty, 792 Instruction *RemoteI = nullptr); 793 794 using OffsetBinsTy = DenseMap<RangeTy, SmallSet<unsigned, 4>>; 795 796 using const_bin_iterator = OffsetBinsTy::const_iterator; 797 const_bin_iterator begin() const { return OffsetBins.begin(); } 798 const_bin_iterator end() const { return OffsetBins.end(); } 799 800 const AAPointerInfo::Access &getAccess(unsigned Index) const { 801 return AccessList[Index]; 802 } 803 804 protected: 805 // Every memory instruction results in an Access object. We maintain a list of 806 // all Access objects that we own, along with the following maps: 807 // 808 // - OffsetBins: RangeTy -> { Access } 809 // - RemoteIMap: RemoteI x LocalI -> Access 810 // 811 // A RemoteI is any instruction that accesses memory. RemoteI is different 812 // from LocalI if and only if LocalI is a call; then RemoteI is some 813 // instruction in the callgraph starting from LocalI. Multiple paths in the 814 // callgraph from LocalI to RemoteI may produce multiple accesses, but these 815 // are all combined into a single Access object. This may result in loss of 816 // information in RangeTy in the Access object. 817 SmallVector<AAPointerInfo::Access> AccessList; 818 OffsetBinsTy OffsetBins; 819 DenseMap<const Instruction *, SmallVector<unsigned>> RemoteIMap; 820 821 /// See AAPointerInfo::forallInterferingAccesses. 822 bool forallInterferingAccesses( 823 AA::RangeTy Range, 824 function_ref<bool(const AAPointerInfo::Access &, bool)> CB) const { 825 if (!isValidState()) 826 return false; 827 828 for (const auto &It : OffsetBins) { 829 AA::RangeTy ItRange = It.getFirst(); 830 if (!Range.mayOverlap(ItRange)) 831 continue; 832 bool IsExact = Range == ItRange && !Range.offsetOrSizeAreUnknown(); 833 for (auto Index : It.getSecond()) { 834 auto &Access = AccessList[Index]; 835 if (!CB(Access, IsExact)) 836 return false; 837 } 838 } 839 return true; 840 } 841 842 /// See AAPointerInfo::forallInterferingAccesses. 843 bool forallInterferingAccesses( 844 Instruction &I, 845 function_ref<bool(const AAPointerInfo::Access &, bool)> CB, 846 AA::RangeTy &Range) const { 847 if (!isValidState()) 848 return false; 849 850 auto LocalList = RemoteIMap.find(&I); 851 if (LocalList == RemoteIMap.end()) { 852 return true; 853 } 854 855 for (unsigned Index : LocalList->getSecond()) { 856 for (auto &R : AccessList[Index]) { 857 Range &= R; 858 if (Range.offsetOrSizeAreUnknown()) 859 break; 860 } 861 } 862 return forallInterferingAccesses(Range, CB); 863 } 864 865 private: 866 /// State to track fixpoint and validity. 867 BooleanState BS; 868 }; 869 870 ChangeStatus AA::PointerInfo::State::addAccess( 871 Attributor &A, const AAPointerInfo::RangeList &Ranges, Instruction &I, 872 std::optional<Value *> Content, AAPointerInfo::AccessKind Kind, Type *Ty, 873 Instruction *RemoteI) { 874 RemoteI = RemoteI ? RemoteI : &I; 875 876 // Check if we have an access for this instruction, if not, simply add it. 877 auto &LocalList = RemoteIMap[RemoteI]; 878 bool AccExists = false; 879 unsigned AccIndex = AccessList.size(); 880 for (auto Index : LocalList) { 881 auto &A = AccessList[Index]; 882 if (A.getLocalInst() == &I) { 883 AccExists = true; 884 AccIndex = Index; 885 break; 886 } 887 } 888 889 auto AddToBins = [&](const AAPointerInfo::RangeList &ToAdd) { 890 LLVM_DEBUG( 891 if (ToAdd.size()) 892 dbgs() << "[AAPointerInfo] Inserting access in new offset bins\n"; 893 ); 894 895 for (auto Key : ToAdd) { 896 LLVM_DEBUG(dbgs() << " key " << Key << "\n"); 897 OffsetBins[Key].insert(AccIndex); 898 } 899 }; 900 901 if (!AccExists) { 902 AccessList.emplace_back(&I, RemoteI, Ranges, Content, Kind, Ty); 903 assert((AccessList.size() == AccIndex + 1) && 904 "New Access should have been at AccIndex"); 905 LocalList.push_back(AccIndex); 906 AddToBins(AccessList[AccIndex].getRanges()); 907 return ChangeStatus::CHANGED; 908 } 909 910 // Combine the new Access with the existing Access, and then update the 911 // mapping in the offset bins. 912 AAPointerInfo::Access Acc(&I, RemoteI, Ranges, Content, Kind, Ty); 913 auto &Current = AccessList[AccIndex]; 914 auto Before = Current; 915 Current &= Acc; 916 if (Current == Before) 917 return ChangeStatus::UNCHANGED; 918 919 auto &ExistingRanges = Before.getRanges(); 920 auto &NewRanges = Current.getRanges(); 921 922 // Ranges that are in the old access but not the new access need to be removed 923 // from the offset bins. 924 AAPointerInfo::RangeList ToRemove; 925 AAPointerInfo::RangeList::set_difference(ExistingRanges, NewRanges, ToRemove); 926 LLVM_DEBUG( 927 if (ToRemove.size()) 928 dbgs() << "[AAPointerInfo] Removing access from old offset bins\n"; 929 ); 930 931 for (auto Key : ToRemove) { 932 LLVM_DEBUG(dbgs() << " key " << Key << "\n"); 933 assert(OffsetBins.count(Key) && "Existing Access must be in some bin."); 934 auto &Bin = OffsetBins[Key]; 935 assert(Bin.count(AccIndex) && 936 "Expected bin to actually contain the Access."); 937 Bin.erase(AccIndex); 938 } 939 940 // Ranges that are in the new access but not the old access need to be added 941 // to the offset bins. 942 AAPointerInfo::RangeList ToAdd; 943 AAPointerInfo::RangeList::set_difference(NewRanges, ExistingRanges, ToAdd); 944 AddToBins(ToAdd); 945 return ChangeStatus::CHANGED; 946 } 947 948 namespace { 949 950 /// A helper containing a list of offsets computed for a Use. Ideally this 951 /// list should be strictly ascending, but we ensure that only when we 952 /// actually translate the list of offsets to a RangeList. 953 struct OffsetInfo { 954 using VecTy = SmallVector<int64_t>; 955 using const_iterator = VecTy::const_iterator; 956 VecTy Offsets; 957 958 const_iterator begin() const { return Offsets.begin(); } 959 const_iterator end() const { return Offsets.end(); } 960 961 bool operator==(const OffsetInfo &RHS) const { 962 return Offsets == RHS.Offsets; 963 } 964 965 bool operator!=(const OffsetInfo &RHS) const { return !(*this == RHS); } 966 967 void insert(int64_t Offset) { Offsets.push_back(Offset); } 968 bool isUnassigned() const { return Offsets.size() == 0; } 969 970 bool isUnknown() const { 971 if (isUnassigned()) 972 return false; 973 if (Offsets.size() == 1) 974 return Offsets.front() == AA::RangeTy::Unknown; 975 return false; 976 } 977 978 void setUnknown() { 979 Offsets.clear(); 980 Offsets.push_back(AA::RangeTy::Unknown); 981 } 982 983 void addToAll(int64_t Inc) { 984 for (auto &Offset : Offsets) { 985 Offset += Inc; 986 } 987 } 988 989 /// Copy offsets from \p R into the current list. 990 /// 991 /// Ideally all lists should be strictly ascending, but we defer that to the 992 /// actual use of the list. So we just blindly append here. 993 void merge(const OffsetInfo &R) { Offsets.append(R.Offsets); } 994 }; 995 996 #ifndef NDEBUG 997 static raw_ostream &operator<<(raw_ostream &OS, const OffsetInfo &OI) { 998 ListSeparator LS; 999 OS << "["; 1000 for (auto Offset : OI) { 1001 OS << LS << Offset; 1002 } 1003 OS << "]"; 1004 return OS; 1005 } 1006 #endif // NDEBUG 1007 1008 struct AAPointerInfoImpl 1009 : public StateWrapper<AA::PointerInfo::State, AAPointerInfo> { 1010 using BaseTy = StateWrapper<AA::PointerInfo::State, AAPointerInfo>; 1011 AAPointerInfoImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {} 1012 1013 /// See AbstractAttribute::getAsStr(). 1014 const std::string getAsStr() const override { 1015 return std::string("PointerInfo ") + 1016 (isValidState() ? (std::string("#") + 1017 std::to_string(OffsetBins.size()) + " bins") 1018 : "<invalid>"); 1019 } 1020 1021 /// See AbstractAttribute::manifest(...). 1022 ChangeStatus manifest(Attributor &A) override { 1023 return AAPointerInfo::manifest(A); 1024 } 1025 1026 bool forallInterferingAccesses( 1027 AA::RangeTy Range, 1028 function_ref<bool(const AAPointerInfo::Access &, bool)> CB) 1029 const override { 1030 return State::forallInterferingAccesses(Range, CB); 1031 } 1032 1033 bool forallInterferingAccesses( 1034 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I, 1035 function_ref<bool(const Access &, bool)> UserCB, bool &HasBeenWrittenTo, 1036 AA::RangeTy &Range) const override { 1037 HasBeenWrittenTo = false; 1038 1039 SmallPtrSet<const Access *, 8> DominatingWrites; 1040 SmallVector<std::pair<const Access *, bool>, 8> InterferingAccesses; 1041 1042 Function &Scope = *I.getFunction(); 1043 const auto &NoSyncAA = A.getAAFor<AANoSync>( 1044 QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL); 1045 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>( 1046 IRPosition::function(Scope), &QueryingAA, DepClassTy::NONE); 1047 bool AllInSameNoSyncFn = NoSyncAA.isAssumedNoSync(); 1048 bool InstIsExecutedByInitialThreadOnly = 1049 ExecDomainAA && ExecDomainAA->isExecutedByInitialThreadOnly(I); 1050 bool InstIsExecutedInAlignedRegion = 1051 ExecDomainAA && ExecDomainAA->isExecutedInAlignedRegion(A, I); 1052 if (InstIsExecutedInAlignedRegion || InstIsExecutedByInitialThreadOnly) 1053 A.recordDependence(*ExecDomainAA, QueryingAA, DepClassTy::OPTIONAL); 1054 1055 InformationCache &InfoCache = A.getInfoCache(); 1056 bool IsThreadLocalObj = 1057 AA::isAssumedThreadLocalObject(A, getAssociatedValue(), *this); 1058 1059 // Helper to determine if we need to consider threading, which we cannot 1060 // right now. However, if the function is (assumed) nosync or the thread 1061 // executing all instructions is the main thread only we can ignore 1062 // threading. Also, thread-local objects do not require threading reasoning. 1063 // Finally, we can ignore threading if either access is executed in an 1064 // aligned region. 1065 auto CanIgnoreThreadingForInst = [&](const Instruction &I) -> bool { 1066 if (IsThreadLocalObj || AllInSameNoSyncFn) 1067 return true; 1068 const auto *FnExecDomainAA = 1069 I.getFunction() == &Scope 1070 ? ExecDomainAA 1071 : A.lookupAAFor<AAExecutionDomain>( 1072 IRPosition::function(*I.getFunction()), &QueryingAA, 1073 DepClassTy::NONE); 1074 if (!FnExecDomainAA) 1075 return false; 1076 if (InstIsExecutedInAlignedRegion || 1077 FnExecDomainAA->isExecutedInAlignedRegion(A, I)) { 1078 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL); 1079 return true; 1080 } 1081 if (InstIsExecutedByInitialThreadOnly && 1082 FnExecDomainAA->isExecutedByInitialThreadOnly(I)) { 1083 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL); 1084 return true; 1085 } 1086 return false; 1087 }; 1088 1089 // Helper to determine if the access is executed by the same thread as the 1090 // given instruction, for now it is sufficient to avoid any potential 1091 // threading effects as we cannot deal with them anyway. 1092 auto CanIgnoreThreading = [&](const Access &Acc) -> bool { 1093 return CanIgnoreThreadingForInst(*Acc.getRemoteInst()) || 1094 (Acc.getRemoteInst() != Acc.getLocalInst() && 1095 CanIgnoreThreadingForInst(*Acc.getLocalInst())); 1096 }; 1097 1098 // TODO: Use inter-procedural reachability and dominance. 1099 const auto &NoRecurseAA = A.getAAFor<AANoRecurse>( 1100 QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL); 1101 1102 const bool FindInterferingWrites = I.mayReadFromMemory(); 1103 const bool FindInterferingReads = I.mayWriteToMemory(); 1104 const bool UseDominanceReasoning = 1105 FindInterferingWrites && NoRecurseAA.isKnownNoRecurse(); 1106 const DominatorTree *DT = 1107 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(Scope); 1108 1109 // Helper to check if a value has "kernel lifetime", that is it will not 1110 // outlive a GPU kernel. This is true for shared, constant, and local 1111 // globals on AMD and NVIDIA GPUs. 1112 auto HasKernelLifetime = [&](Value *V, Module &M) { 1113 Triple T(M.getTargetTriple()); 1114 if (!(T.isAMDGPU() || T.isNVPTX())) 1115 return false; 1116 switch (AA::GPUAddressSpace(V->getType()->getPointerAddressSpace())) { 1117 case AA::GPUAddressSpace::Shared: 1118 case AA::GPUAddressSpace::Constant: 1119 case AA::GPUAddressSpace::Local: 1120 return true; 1121 default: 1122 return false; 1123 }; 1124 }; 1125 1126 // The IsLiveInCalleeCB will be used by the AA::isPotentiallyReachable query 1127 // to determine if we should look at reachability from the callee. For 1128 // certain pointers we know the lifetime and we do not have to step into the 1129 // callee to determine reachability as the pointer would be dead in the 1130 // callee. See the conditional initialization below. 1131 std::function<bool(const Function &)> IsLiveInCalleeCB; 1132 1133 if (auto *AI = dyn_cast<AllocaInst>(&getAssociatedValue())) { 1134 // If the alloca containing function is not recursive the alloca 1135 // must be dead in the callee. 1136 const Function *AIFn = AI->getFunction(); 1137 const auto &NoRecurseAA = A.getAAFor<AANoRecurse>( 1138 *this, IRPosition::function(*AIFn), DepClassTy::OPTIONAL); 1139 if (NoRecurseAA.isAssumedNoRecurse()) { 1140 IsLiveInCalleeCB = [AIFn](const Function &Fn) { return AIFn != &Fn; }; 1141 } 1142 } else if (auto *GV = dyn_cast<GlobalValue>(&getAssociatedValue())) { 1143 // If the global has kernel lifetime we can stop if we reach a kernel 1144 // as it is "dead" in the (unknown) callees. 1145 if (HasKernelLifetime(GV, *GV->getParent())) 1146 IsLiveInCalleeCB = [](const Function &Fn) { 1147 return !Fn.hasFnAttribute("kernel"); 1148 }; 1149 } 1150 1151 // Set of accesses/instructions that will overwrite the result and are 1152 // therefore blockers in the reachability traversal. 1153 AA::InstExclusionSetTy ExclusionSet; 1154 1155 auto AccessCB = [&](const Access &Acc, bool Exact) { 1156 if (Exact && Acc.isMustAccess() && Acc.getRemoteInst() != &I) { 1157 if (Acc.isWrite() || (isa<LoadInst>(I) && Acc.isWriteOrAssumption())) 1158 ExclusionSet.insert(Acc.getRemoteInst()); 1159 } 1160 1161 if ((!FindInterferingWrites || !Acc.isWriteOrAssumption()) && 1162 (!FindInterferingReads || !Acc.isRead())) 1163 return true; 1164 1165 bool Dominates = FindInterferingWrites && DT && Exact && 1166 Acc.isMustAccess() && 1167 (Acc.getRemoteInst()->getFunction() == &Scope) && 1168 DT->dominates(Acc.getRemoteInst(), &I); 1169 if (Dominates) 1170 DominatingWrites.insert(&Acc); 1171 1172 // Track if all interesting accesses are in the same `nosync` function as 1173 // the given instruction. 1174 AllInSameNoSyncFn &= Acc.getRemoteInst()->getFunction() == &Scope; 1175 1176 InterferingAccesses.push_back({&Acc, Exact}); 1177 return true; 1178 }; 1179 if (!State::forallInterferingAccesses(I, AccessCB, Range)) 1180 return false; 1181 1182 HasBeenWrittenTo = !DominatingWrites.empty(); 1183 1184 // Dominating writes form a chain, find the least/lowest member. 1185 Instruction *LeastDominatingWriteInst = nullptr; 1186 for (const Access *Acc : DominatingWrites) { 1187 if (!LeastDominatingWriteInst) { 1188 LeastDominatingWriteInst = Acc->getRemoteInst(); 1189 } else if (DT->dominates(LeastDominatingWriteInst, 1190 Acc->getRemoteInst())) { 1191 LeastDominatingWriteInst = Acc->getRemoteInst(); 1192 } 1193 } 1194 1195 // Helper to determine if we can skip a specific write access. 1196 auto CanSkipAccess = [&](const Access &Acc, bool Exact) { 1197 if (!CanIgnoreThreading(Acc)) 1198 return false; 1199 1200 // Check read (RAW) dependences and write (WAR) dependences as necessary. 1201 // If we successfully excluded all effects we are interested in, the 1202 // access can be skipped. 1203 bool ReadChecked = !FindInterferingReads; 1204 bool WriteChecked = !FindInterferingWrites; 1205 1206 // If the instruction cannot reach the access, the former does not 1207 // interfere with what the access reads. 1208 if (!ReadChecked) { 1209 if (!AA::isPotentiallyReachable(A, I, *Acc.getRemoteInst(), QueryingAA, 1210 &ExclusionSet, IsLiveInCalleeCB)) 1211 ReadChecked = true; 1212 } 1213 // If the instruction cannot be reach from the access, the latter does not 1214 // interfere with what the instruction reads. 1215 if (!WriteChecked) { 1216 if (!AA::isPotentiallyReachable(A, *Acc.getRemoteInst(), I, QueryingAA, 1217 &ExclusionSet, IsLiveInCalleeCB)) 1218 WriteChecked = true; 1219 } 1220 1221 // If we still might be affected by the write of the access but there are 1222 // dominating writes in the function of the instruction 1223 // (HasBeenWrittenTo), we can try to reason that the access is overwritten 1224 // by them. This would have happend above if they are all in the same 1225 // function, so we only check the inter-procedural case. Effectively, we 1226 // want to show that there is no call after the dominting write that might 1227 // reach the access, and when it returns reach the instruction with the 1228 // updated value. To this end, we iterate all call sites, check if they 1229 // might reach the instruction without going through another access 1230 // (ExclusionSet) and at the same time might reach the access. However, 1231 // that is all part of AAInterFnReachability. 1232 if (!WriteChecked && HasBeenWrittenTo && 1233 Acc.getRemoteInst()->getFunction() != &Scope) { 1234 1235 const auto &FnReachabilityAA = A.getAAFor<AAInterFnReachability>( 1236 QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL); 1237 1238 // Without going backwards in the call tree, can we reach the access 1239 // from the least dominating write. Do not allow to pass the instruction 1240 // itself either. 1241 bool Inserted = ExclusionSet.insert(&I).second; 1242 1243 if (!FnReachabilityAA.instructionCanReach( 1244 A, *LeastDominatingWriteInst, 1245 *Acc.getRemoteInst()->getFunction(), &ExclusionSet)) 1246 WriteChecked = true; 1247 1248 if (Inserted) 1249 ExclusionSet.erase(&I); 1250 } 1251 1252 if (ReadChecked && WriteChecked) 1253 return true; 1254 1255 if (!DT || !UseDominanceReasoning) 1256 return false; 1257 if (!DominatingWrites.count(&Acc)) 1258 return false; 1259 return LeastDominatingWriteInst != Acc.getRemoteInst(); 1260 }; 1261 1262 // Run the user callback on all accesses we cannot skip and return if 1263 // that succeeded for all or not. 1264 for (auto &It : InterferingAccesses) { 1265 if ((!AllInSameNoSyncFn && !IsThreadLocalObj && !ExecDomainAA) || 1266 !CanSkipAccess(*It.first, It.second)) { 1267 if (!UserCB(*It.first, It.second)) 1268 return false; 1269 } 1270 } 1271 return true; 1272 } 1273 1274 ChangeStatus translateAndAddStateFromCallee(Attributor &A, 1275 const AAPointerInfo &OtherAA, 1276 CallBase &CB) { 1277 using namespace AA::PointerInfo; 1278 if (!OtherAA.getState().isValidState() || !isValidState()) 1279 return indicatePessimisticFixpoint(); 1280 1281 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA); 1282 bool IsByval = OtherAAImpl.getAssociatedArgument()->hasByValAttr(); 1283 1284 // Combine the accesses bin by bin. 1285 ChangeStatus Changed = ChangeStatus::UNCHANGED; 1286 const auto &State = OtherAAImpl.getState(); 1287 for (const auto &It : State) { 1288 for (auto Index : It.getSecond()) { 1289 const auto &RAcc = State.getAccess(Index); 1290 if (IsByval && !RAcc.isRead()) 1291 continue; 1292 bool UsedAssumedInformation = false; 1293 AccessKind AK = RAcc.getKind(); 1294 auto Content = A.translateArgumentToCallSiteContent( 1295 RAcc.getContent(), CB, *this, UsedAssumedInformation); 1296 AK = AccessKind(AK & (IsByval ? AccessKind::AK_R : AccessKind::AK_RW)); 1297 AK = AccessKind(AK | (RAcc.isMayAccess() ? AK_MAY : AK_MUST)); 1298 1299 Changed |= addAccess(A, RAcc.getRanges(), CB, Content, AK, 1300 RAcc.getType(), RAcc.getRemoteInst()); 1301 } 1302 } 1303 return Changed; 1304 } 1305 1306 ChangeStatus translateAndAddState(Attributor &A, const AAPointerInfo &OtherAA, 1307 const OffsetInfo &Offsets, CallBase &CB) { 1308 using namespace AA::PointerInfo; 1309 if (!OtherAA.getState().isValidState() || !isValidState()) 1310 return indicatePessimisticFixpoint(); 1311 1312 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA); 1313 1314 // Combine the accesses bin by bin. 1315 ChangeStatus Changed = ChangeStatus::UNCHANGED; 1316 const auto &State = OtherAAImpl.getState(); 1317 for (const auto &It : State) { 1318 for (auto Index : It.getSecond()) { 1319 const auto &RAcc = State.getAccess(Index); 1320 for (auto Offset : Offsets) { 1321 auto NewRanges = Offset == AA::RangeTy::Unknown 1322 ? AA::RangeTy::getUnknown() 1323 : RAcc.getRanges(); 1324 if (!NewRanges.isUnknown()) { 1325 NewRanges.addToAllOffsets(Offset); 1326 } 1327 Changed |= 1328 addAccess(A, NewRanges, CB, RAcc.getContent(), RAcc.getKind(), 1329 RAcc.getType(), RAcc.getRemoteInst()); 1330 } 1331 } 1332 } 1333 return Changed; 1334 } 1335 1336 /// Statistic tracking for all AAPointerInfo implementations. 1337 /// See AbstractAttribute::trackStatistics(). 1338 void trackPointerInfoStatistics(const IRPosition &IRP) const {} 1339 1340 /// Dump the state into \p O. 1341 void dumpState(raw_ostream &O) { 1342 for (auto &It : OffsetBins) { 1343 O << "[" << It.first.Offset << "-" << It.first.Offset + It.first.Size 1344 << "] : " << It.getSecond().size() << "\n"; 1345 for (auto AccIndex : It.getSecond()) { 1346 auto &Acc = AccessList[AccIndex]; 1347 O << " - " << Acc.getKind() << " - " << *Acc.getLocalInst() << "\n"; 1348 if (Acc.getLocalInst() != Acc.getRemoteInst()) 1349 O << " --> " << *Acc.getRemoteInst() 1350 << "\n"; 1351 if (!Acc.isWrittenValueYetUndetermined()) { 1352 if (Acc.getWrittenValue()) 1353 O << " - c: " << *Acc.getWrittenValue() << "\n"; 1354 else 1355 O << " - c: <unknown>\n"; 1356 } 1357 } 1358 } 1359 } 1360 }; 1361 1362 struct AAPointerInfoFloating : public AAPointerInfoImpl { 1363 using AccessKind = AAPointerInfo::AccessKind; 1364 AAPointerInfoFloating(const IRPosition &IRP, Attributor &A) 1365 : AAPointerInfoImpl(IRP, A) {} 1366 1367 /// Deal with an access and signal if it was handled successfully. 1368 bool handleAccess(Attributor &A, Instruction &I, 1369 std::optional<Value *> Content, AccessKind Kind, 1370 SmallVectorImpl<int64_t> &Offsets, ChangeStatus &Changed, 1371 Type &Ty) { 1372 using namespace AA::PointerInfo; 1373 auto Size = AA::RangeTy::Unknown; 1374 const DataLayout &DL = A.getDataLayout(); 1375 TypeSize AccessSize = DL.getTypeStoreSize(&Ty); 1376 if (!AccessSize.isScalable()) 1377 Size = AccessSize.getFixedValue(); 1378 1379 // Make a strictly ascending list of offsets as required by addAccess() 1380 llvm::sort(Offsets); 1381 auto *Last = std::unique(Offsets.begin(), Offsets.end()); 1382 Offsets.erase(Last, Offsets.end()); 1383 1384 VectorType *VT = dyn_cast<VectorType>(&Ty); 1385 if (!VT || VT->getElementCount().isScalable() || 1386 !Content.value_or(nullptr) || !isa<Constant>(*Content) || 1387 (*Content)->getType() != VT || 1388 DL.getTypeStoreSize(VT->getElementType()).isScalable()) { 1389 Changed = Changed | addAccess(A, {Offsets, Size}, I, Content, Kind, &Ty); 1390 } else { 1391 // Handle vector stores with constant content element-wise. 1392 // TODO: We could look for the elements or create instructions 1393 // representing them. 1394 // TODO: We need to push the Content into the range abstraction 1395 // (AA::RangeTy) to allow different content values for different 1396 // ranges. ranges. Hence, support vectors storing different values. 1397 Type *ElementType = VT->getElementType(); 1398 int64_t ElementSize = DL.getTypeStoreSize(ElementType).getFixedValue(); 1399 auto *ConstContent = cast<Constant>(*Content); 1400 Type *Int32Ty = Type::getInt32Ty(ElementType->getContext()); 1401 SmallVector<int64_t> ElementOffsets(Offsets.begin(), Offsets.end()); 1402 1403 for (int i = 0, e = VT->getElementCount().getFixedValue(); i != e; ++i) { 1404 Value *ElementContent = ConstantExpr::getExtractElement( 1405 ConstContent, ConstantInt::get(Int32Ty, i)); 1406 1407 // Add the element access. 1408 Changed = Changed | addAccess(A, {ElementOffsets, ElementSize}, I, 1409 ElementContent, Kind, ElementType); 1410 1411 // Advance the offsets for the next element. 1412 for (auto &ElementOffset : ElementOffsets) 1413 ElementOffset += ElementSize; 1414 } 1415 } 1416 return true; 1417 }; 1418 1419 /// See AbstractAttribute::updateImpl(...). 1420 ChangeStatus updateImpl(Attributor &A) override; 1421 1422 /// If the indices to \p GEP can be traced to constants, incorporate all 1423 /// of these into \p UsrOI. 1424 /// 1425 /// \return true iff \p UsrOI is updated. 1426 bool collectConstantsForGEP(Attributor &A, const DataLayout &DL, 1427 OffsetInfo &UsrOI, const OffsetInfo &PtrOI, 1428 const GEPOperator *GEP); 1429 1430 /// See AbstractAttribute::trackStatistics() 1431 void trackStatistics() const override { 1432 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition()); 1433 } 1434 }; 1435 1436 bool AAPointerInfoFloating::collectConstantsForGEP(Attributor &A, 1437 const DataLayout &DL, 1438 OffsetInfo &UsrOI, 1439 const OffsetInfo &PtrOI, 1440 const GEPOperator *GEP) { 1441 unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType()); 1442 MapVector<Value *, APInt> VariableOffsets; 1443 APInt ConstantOffset(BitWidth, 0); 1444 1445 assert(!UsrOI.isUnknown() && !PtrOI.isUnknown() && 1446 "Don't look for constant values if the offset has already been " 1447 "determined to be unknown."); 1448 1449 if (!GEP->collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset)) { 1450 UsrOI.setUnknown(); 1451 return true; 1452 } 1453 1454 LLVM_DEBUG(dbgs() << "[AAPointerInfo] GEP offset is " 1455 << (VariableOffsets.empty() ? "" : "not") << " constant " 1456 << *GEP << "\n"); 1457 1458 auto Union = PtrOI; 1459 Union.addToAll(ConstantOffset.getSExtValue()); 1460 1461 // Each VI in VariableOffsets has a set of potential constant values. Every 1462 // combination of elements, picked one each from these sets, is separately 1463 // added to the original set of offsets, thus resulting in more offsets. 1464 for (const auto &VI : VariableOffsets) { 1465 auto &PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>( 1466 *this, IRPosition::value(*VI.first), DepClassTy::OPTIONAL); 1467 if (!PotentialConstantsAA.isValidState()) { 1468 UsrOI.setUnknown(); 1469 return true; 1470 } 1471 1472 // UndefValue is treated as a zero, which leaves Union as is. 1473 if (PotentialConstantsAA.undefIsContained()) 1474 continue; 1475 1476 // We need at least one constant in every set to compute an actual offset. 1477 // Otherwise, we end up pessimizing AAPointerInfo by respecting offsets that 1478 // don't actually exist. In other words, the absence of constant values 1479 // implies that the operation can be assumed dead for now. 1480 auto &AssumedSet = PotentialConstantsAA.getAssumedSet(); 1481 if (AssumedSet.empty()) 1482 return false; 1483 1484 OffsetInfo Product; 1485 for (const auto &ConstOffset : AssumedSet) { 1486 auto CopyPerOffset = Union; 1487 CopyPerOffset.addToAll(ConstOffset.getSExtValue() * 1488 VI.second.getZExtValue()); 1489 Product.merge(CopyPerOffset); 1490 } 1491 Union = Product; 1492 } 1493 1494 UsrOI = std::move(Union); 1495 return true; 1496 } 1497 1498 ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) { 1499 using namespace AA::PointerInfo; 1500 ChangeStatus Changed = ChangeStatus::UNCHANGED; 1501 const DataLayout &DL = A.getDataLayout(); 1502 Value &AssociatedValue = getAssociatedValue(); 1503 1504 DenseMap<Value *, OffsetInfo> OffsetInfoMap; 1505 OffsetInfoMap[&AssociatedValue].insert(0); 1506 1507 auto HandlePassthroughUser = [&](Value *Usr, Value *CurPtr, bool &Follow) { 1508 // One does not simply walk into a map and assign a reference to a possibly 1509 // new location. That can cause an invalidation before the assignment 1510 // happens, like so: 1511 // 1512 // OffsetInfoMap[Usr] = OffsetInfoMap[CurPtr]; /* bad idea! */ 1513 // 1514 // The RHS is a reference that may be invalidated by an insertion caused by 1515 // the LHS. So we ensure that the side-effect of the LHS happens first. 1516 auto &UsrOI = OffsetInfoMap[Usr]; 1517 auto &PtrOI = OffsetInfoMap[CurPtr]; 1518 assert(!PtrOI.isUnassigned() && 1519 "Cannot pass through if the input Ptr was not visited!"); 1520 UsrOI = PtrOI; 1521 Follow = true; 1522 return true; 1523 }; 1524 1525 const auto *F = getAnchorScope(); 1526 const auto *CI = 1527 F ? A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(*F) 1528 : nullptr; 1529 const auto *TLI = 1530 F ? A.getInfoCache().getTargetLibraryInfoForFunction(*F) : nullptr; 1531 1532 auto UsePred = [&](const Use &U, bool &Follow) -> bool { 1533 Value *CurPtr = U.get(); 1534 User *Usr = U.getUser(); 1535 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Analyze " << *CurPtr << " in " << *Usr 1536 << "\n"); 1537 assert(OffsetInfoMap.count(CurPtr) && 1538 "The current pointer offset should have been seeded!"); 1539 1540 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Usr)) { 1541 if (CE->isCast()) 1542 return HandlePassthroughUser(Usr, CurPtr, Follow); 1543 if (CE->isCompare()) 1544 return true; 1545 if (!isa<GEPOperator>(CE)) { 1546 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled constant user " << *CE 1547 << "\n"); 1548 return false; 1549 } 1550 } 1551 if (auto *GEP = dyn_cast<GEPOperator>(Usr)) { 1552 // Note the order here, the Usr access might change the map, CurPtr is 1553 // already in it though. 1554 auto &UsrOI = OffsetInfoMap[Usr]; 1555 auto &PtrOI = OffsetInfoMap[CurPtr]; 1556 1557 if (UsrOI.isUnknown()) 1558 return true; 1559 1560 if (PtrOI.isUnknown()) { 1561 Follow = true; 1562 UsrOI.setUnknown(); 1563 return true; 1564 } 1565 1566 Follow = collectConstantsForGEP(A, DL, UsrOI, PtrOI, GEP); 1567 return true; 1568 } 1569 if (isa<PtrToIntInst>(Usr)) 1570 return false; 1571 if (isa<CastInst>(Usr) || isa<SelectInst>(Usr) || isa<ReturnInst>(Usr)) 1572 return HandlePassthroughUser(Usr, CurPtr, Follow); 1573 1574 // For PHIs we need to take care of the recurrence explicitly as the value 1575 // might change while we iterate through a loop. For now, we give up if 1576 // the PHI is not invariant. 1577 if (isa<PHINode>(Usr)) { 1578 // Note the order here, the Usr access might change the map, CurPtr is 1579 // already in it though. 1580 bool IsFirstPHIUser = !OffsetInfoMap.count(Usr); 1581 auto &UsrOI = OffsetInfoMap[Usr]; 1582 auto &PtrOI = OffsetInfoMap[CurPtr]; 1583 1584 // Check if the PHI operand has already an unknown offset as we can't 1585 // improve on that anymore. 1586 if (PtrOI.isUnknown()) { 1587 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand offset unknown " 1588 << *CurPtr << " in " << *Usr << "\n"); 1589 Follow = !UsrOI.isUnknown(); 1590 UsrOI.setUnknown(); 1591 return true; 1592 } 1593 1594 // Check if the PHI is invariant (so far). 1595 if (UsrOI == PtrOI) { 1596 assert(!PtrOI.isUnassigned() && 1597 "Cannot assign if the current Ptr was not visited!"); 1598 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant (so far)"); 1599 return true; 1600 } 1601 1602 // Check if the PHI operand can be traced back to AssociatedValue. 1603 APInt Offset( 1604 DL.getIndexSizeInBits(CurPtr->getType()->getPointerAddressSpace()), 1605 0); 1606 Value *CurPtrBase = CurPtr->stripAndAccumulateConstantOffsets( 1607 DL, Offset, /* AllowNonInbounds */ true); 1608 auto It = OffsetInfoMap.find(CurPtrBase); 1609 if (It == OffsetInfoMap.end()) { 1610 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand is too complex " 1611 << *CurPtr << " in " << *Usr << "\n"); 1612 UsrOI.setUnknown(); 1613 Follow = true; 1614 return true; 1615 } 1616 1617 auto mayBeInCycleHeader = [](const CycleInfo *CI, const Instruction *I) { 1618 if (!CI) 1619 return true; 1620 auto *BB = I->getParent(); 1621 auto *C = CI->getCycle(BB); 1622 if (!C) 1623 return false; 1624 return BB == C->getHeader(); 1625 }; 1626 1627 // Check if the PHI operand is not dependent on the PHI itself. Every 1628 // recurrence is a cyclic net of PHIs in the data flow, and has an 1629 // equivalent Cycle in the control flow. One of those PHIs must be in the 1630 // header of that control flow Cycle. This is independent of the choice of 1631 // Cycles reported by CycleInfo. It is sufficient to check the PHIs in 1632 // every Cycle header; if such a node is marked unknown, this will 1633 // eventually propagate through the whole net of PHIs in the recurrence. 1634 if (mayBeInCycleHeader(CI, cast<Instruction>(Usr))) { 1635 auto BaseOI = It->getSecond(); 1636 BaseOI.addToAll(Offset.getZExtValue()); 1637 if (IsFirstPHIUser || BaseOI == UsrOI) { 1638 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant " << *CurPtr 1639 << " in " << *Usr << "\n"); 1640 return HandlePassthroughUser(Usr, CurPtr, Follow); 1641 } 1642 1643 LLVM_DEBUG( 1644 dbgs() << "[AAPointerInfo] PHI operand pointer offset mismatch " 1645 << *CurPtr << " in " << *Usr << "\n"); 1646 UsrOI.setUnknown(); 1647 Follow = true; 1648 return true; 1649 } 1650 1651 UsrOI.merge(PtrOI); 1652 Follow = true; 1653 return true; 1654 } 1655 1656 if (auto *LoadI = dyn_cast<LoadInst>(Usr)) { 1657 // If the access is to a pointer that may or may not be the associated 1658 // value, e.g. due to a PHI, we cannot assume it will be read. 1659 AccessKind AK = AccessKind::AK_R; 1660 if (getUnderlyingObject(CurPtr) == &AssociatedValue) 1661 AK = AccessKind(AK | AccessKind::AK_MUST); 1662 else 1663 AK = AccessKind(AK | AccessKind::AK_MAY); 1664 if (!handleAccess(A, *LoadI, /* Content */ nullptr, AK, 1665 OffsetInfoMap[CurPtr].Offsets, Changed, 1666 *LoadI->getType())) 1667 return false; 1668 1669 auto IsAssumption = [](Instruction &I) { 1670 if (auto *II = dyn_cast<IntrinsicInst>(&I)) 1671 return II->isAssumeLikeIntrinsic(); 1672 return false; 1673 }; 1674 1675 auto IsImpactedInRange = [&](Instruction *FromI, Instruction *ToI) { 1676 // Check if the assumption and the load are executed together without 1677 // memory modification. 1678 do { 1679 if (FromI->mayWriteToMemory() && !IsAssumption(*FromI)) 1680 return true; 1681 FromI = FromI->getNextNonDebugInstruction(); 1682 } while (FromI && FromI != ToI); 1683 return false; 1684 }; 1685 1686 BasicBlock *BB = LoadI->getParent(); 1687 auto IsValidAssume = [&](IntrinsicInst &IntrI) { 1688 if (IntrI.getIntrinsicID() != Intrinsic::assume) 1689 return false; 1690 BasicBlock *IntrBB = IntrI.getParent(); 1691 if (IntrI.getParent() == BB) { 1692 if (IsImpactedInRange(LoadI->getNextNonDebugInstruction(), &IntrI)) 1693 return false; 1694 } else { 1695 auto PredIt = pred_begin(IntrBB); 1696 if ((*PredIt) != BB) 1697 return false; 1698 if (++PredIt != pred_end(IntrBB)) 1699 return false; 1700 for (auto *SuccBB : successors(BB)) { 1701 if (SuccBB == IntrBB) 1702 continue; 1703 if (isa<UnreachableInst>(SuccBB->getTerminator())) 1704 continue; 1705 return false; 1706 } 1707 if (IsImpactedInRange(LoadI->getNextNonDebugInstruction(), 1708 BB->getTerminator())) 1709 return false; 1710 if (IsImpactedInRange(&IntrBB->front(), &IntrI)) 1711 return false; 1712 } 1713 return true; 1714 }; 1715 1716 std::pair<Value *, IntrinsicInst *> Assumption; 1717 for (const Use &LoadU : LoadI->uses()) { 1718 if (auto *CmpI = dyn_cast<CmpInst>(LoadU.getUser())) { 1719 if (!CmpI->isEquality() || !CmpI->isTrueWhenEqual()) 1720 continue; 1721 for (const Use &CmpU : CmpI->uses()) { 1722 if (auto *IntrI = dyn_cast<IntrinsicInst>(CmpU.getUser())) { 1723 if (!IsValidAssume(*IntrI)) 1724 continue; 1725 int Idx = CmpI->getOperandUse(0) == LoadU; 1726 Assumption = {CmpI->getOperand(Idx), IntrI}; 1727 break; 1728 } 1729 } 1730 } 1731 if (Assumption.first) 1732 break; 1733 } 1734 1735 // Check if we found an assumption associated with this load. 1736 if (!Assumption.first || !Assumption.second) 1737 return true; 1738 1739 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Assumption found " 1740 << *Assumption.second << ": " << *LoadI 1741 << " == " << *Assumption.first << "\n"); 1742 1743 return handleAccess( 1744 A, *Assumption.second, Assumption.first, AccessKind::AK_ASSUMPTION, 1745 OffsetInfoMap[CurPtr].Offsets, Changed, *LoadI->getType()); 1746 } 1747 1748 auto HandleStoreLike = [&](Instruction &I, Value *ValueOp, Type &ValueTy, 1749 ArrayRef<Value *> OtherOps, AccessKind AK) { 1750 for (auto *OtherOp : OtherOps) { 1751 if (OtherOp == CurPtr) { 1752 LLVM_DEBUG( 1753 dbgs() 1754 << "[AAPointerInfo] Escaping use in store like instruction " << I 1755 << "\n"); 1756 return false; 1757 } 1758 } 1759 1760 // If the access is to a pointer that may or may not be the associated 1761 // value, e.g. due to a PHI, we cannot assume it will be written. 1762 if (getUnderlyingObject(CurPtr) == &AssociatedValue) 1763 AK = AccessKind(AK | AccessKind::AK_MUST); 1764 else 1765 AK = AccessKind(AK | AccessKind::AK_MAY); 1766 bool UsedAssumedInformation = false; 1767 std::optional<Value *> Content = nullptr; 1768 if (ValueOp) 1769 Content = A.getAssumedSimplified( 1770 *ValueOp, *this, UsedAssumedInformation, AA::Interprocedural); 1771 return handleAccess(A, I, Content, AK, OffsetInfoMap[CurPtr].Offsets, 1772 Changed, ValueTy); 1773 }; 1774 1775 if (auto *StoreI = dyn_cast<StoreInst>(Usr)) 1776 return HandleStoreLike(*StoreI, StoreI->getValueOperand(), 1777 *StoreI->getValueOperand()->getType(), 1778 {StoreI->getValueOperand()}, AccessKind::AK_W); 1779 if (auto *RMWI = dyn_cast<AtomicRMWInst>(Usr)) 1780 return HandleStoreLike(*RMWI, nullptr, *RMWI->getValOperand()->getType(), 1781 {RMWI->getValOperand()}, AccessKind::AK_RW); 1782 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(Usr)) 1783 return HandleStoreLike( 1784 *CXI, nullptr, *CXI->getNewValOperand()->getType(), 1785 {CXI->getCompareOperand(), CXI->getNewValOperand()}, 1786 AccessKind::AK_RW); 1787 1788 if (auto *CB = dyn_cast<CallBase>(Usr)) { 1789 if (CB->isLifetimeStartOrEnd()) 1790 return true; 1791 if (getFreedOperand(CB, TLI) == U) 1792 return true; 1793 if (CB->isArgOperand(&U)) { 1794 unsigned ArgNo = CB->getArgOperandNo(&U); 1795 const auto &CSArgPI = A.getAAFor<AAPointerInfo>( 1796 *this, IRPosition::callsite_argument(*CB, ArgNo), 1797 DepClassTy::REQUIRED); 1798 Changed = translateAndAddState(A, CSArgPI, OffsetInfoMap[CurPtr], *CB) | 1799 Changed; 1800 return isValidState(); 1801 } 1802 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB 1803 << "\n"); 1804 // TODO: Allow some call uses 1805 return false; 1806 } 1807 1808 LLVM_DEBUG(dbgs() << "[AAPointerInfo] User not handled " << *Usr << "\n"); 1809 return false; 1810 }; 1811 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) { 1812 assert(OffsetInfoMap.count(OldU) && "Old use should be known already!"); 1813 if (OffsetInfoMap.count(NewU)) { 1814 LLVM_DEBUG({ 1815 if (!(OffsetInfoMap[NewU] == OffsetInfoMap[OldU])) { 1816 dbgs() << "[AAPointerInfo] Equivalent use callback failed: " 1817 << OffsetInfoMap[NewU] << " vs " << OffsetInfoMap[OldU] 1818 << "\n"; 1819 } 1820 }); 1821 return OffsetInfoMap[NewU] == OffsetInfoMap[OldU]; 1822 } 1823 OffsetInfoMap[NewU] = OffsetInfoMap[OldU]; 1824 return true; 1825 }; 1826 if (!A.checkForAllUses(UsePred, *this, AssociatedValue, 1827 /* CheckBBLivenessOnly */ true, DepClassTy::OPTIONAL, 1828 /* IgnoreDroppableUses */ true, EquivalentUseCB)) { 1829 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Check for all uses failed, abort!\n"); 1830 return indicatePessimisticFixpoint(); 1831 } 1832 1833 LLVM_DEBUG({ 1834 dbgs() << "Accesses by bin after update:\n"; 1835 dumpState(dbgs()); 1836 }); 1837 1838 return Changed; 1839 } 1840 1841 struct AAPointerInfoReturned final : AAPointerInfoImpl { 1842 AAPointerInfoReturned(const IRPosition &IRP, Attributor &A) 1843 : AAPointerInfoImpl(IRP, A) {} 1844 1845 /// See AbstractAttribute::updateImpl(...). 1846 ChangeStatus updateImpl(Attributor &A) override { 1847 return indicatePessimisticFixpoint(); 1848 } 1849 1850 /// See AbstractAttribute::trackStatistics() 1851 void trackStatistics() const override { 1852 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition()); 1853 } 1854 }; 1855 1856 struct AAPointerInfoArgument final : AAPointerInfoFloating { 1857 AAPointerInfoArgument(const IRPosition &IRP, Attributor &A) 1858 : AAPointerInfoFloating(IRP, A) {} 1859 1860 /// See AbstractAttribute::initialize(...). 1861 void initialize(Attributor &A) override { 1862 AAPointerInfoFloating::initialize(A); 1863 if (getAnchorScope()->isDeclaration()) 1864 indicatePessimisticFixpoint(); 1865 } 1866 1867 /// See AbstractAttribute::trackStatistics() 1868 void trackStatistics() const override { 1869 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition()); 1870 } 1871 }; 1872 1873 struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating { 1874 AAPointerInfoCallSiteArgument(const IRPosition &IRP, Attributor &A) 1875 : AAPointerInfoFloating(IRP, A) {} 1876 1877 /// See AbstractAttribute::updateImpl(...). 1878 ChangeStatus updateImpl(Attributor &A) override { 1879 using namespace AA::PointerInfo; 1880 // We handle memory intrinsics explicitly, at least the first (= 1881 // destination) and second (=source) arguments as we know how they are 1882 // accessed. 1883 if (auto *MI = dyn_cast_or_null<MemIntrinsic>(getCtxI())) { 1884 ConstantInt *Length = dyn_cast<ConstantInt>(MI->getLength()); 1885 int64_t LengthVal = AA::RangeTy::Unknown; 1886 if (Length) 1887 LengthVal = Length->getSExtValue(); 1888 unsigned ArgNo = getIRPosition().getCallSiteArgNo(); 1889 ChangeStatus Changed = ChangeStatus::UNCHANGED; 1890 if (ArgNo > 1) { 1891 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled memory intrinsic " 1892 << *MI << "\n"); 1893 return indicatePessimisticFixpoint(); 1894 } else { 1895 auto Kind = 1896 ArgNo == 0 ? AccessKind::AK_MUST_WRITE : AccessKind::AK_MUST_READ; 1897 Changed = 1898 Changed | addAccess(A, {0, LengthVal}, *MI, nullptr, Kind, nullptr); 1899 } 1900 LLVM_DEBUG({ 1901 dbgs() << "Accesses by bin after update:\n"; 1902 dumpState(dbgs()); 1903 }); 1904 1905 return Changed; 1906 } 1907 1908 // TODO: Once we have call site specific value information we can provide 1909 // call site specific liveness information and then it makes 1910 // sense to specialize attributes for call sites arguments instead of 1911 // redirecting requests to the callee argument. 1912 Argument *Arg = getAssociatedArgument(); 1913 if (Arg) { 1914 const IRPosition &ArgPos = IRPosition::argument(*Arg); 1915 auto &ArgAA = 1916 A.getAAFor<AAPointerInfo>(*this, ArgPos, DepClassTy::REQUIRED); 1917 if (ArgAA.getState().isValidState()) 1918 return translateAndAddStateFromCallee(A, ArgAA, 1919 *cast<CallBase>(getCtxI())); 1920 if (!Arg->getParent()->isDeclaration()) 1921 return indicatePessimisticFixpoint(); 1922 } 1923 1924 const auto &NoCaptureAA = 1925 A.getAAFor<AANoCapture>(*this, getIRPosition(), DepClassTy::OPTIONAL); 1926 1927 if (!NoCaptureAA.isAssumedNoCapture()) 1928 return indicatePessimisticFixpoint(); 1929 1930 bool IsKnown = false; 1931 if (AA::isAssumedReadNone(A, getIRPosition(), *this, IsKnown)) 1932 return ChangeStatus::UNCHANGED; 1933 bool ReadOnly = AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown); 1934 auto Kind = 1935 ReadOnly ? AccessKind::AK_MAY_READ : AccessKind::AK_MAY_READ_WRITE; 1936 return addAccess(A, AA::RangeTy::getUnknown(), *getCtxI(), nullptr, Kind, 1937 nullptr); 1938 } 1939 1940 /// See AbstractAttribute::trackStatistics() 1941 void trackStatistics() const override { 1942 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition()); 1943 } 1944 }; 1945 1946 struct AAPointerInfoCallSiteReturned final : AAPointerInfoFloating { 1947 AAPointerInfoCallSiteReturned(const IRPosition &IRP, Attributor &A) 1948 : AAPointerInfoFloating(IRP, A) {} 1949 1950 /// See AbstractAttribute::trackStatistics() 1951 void trackStatistics() const override { 1952 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition()); 1953 } 1954 }; 1955 } // namespace 1956 1957 /// -----------------------NoUnwind Function Attribute-------------------------- 1958 1959 namespace { 1960 struct AANoUnwindImpl : AANoUnwind { 1961 AANoUnwindImpl(const IRPosition &IRP, Attributor &A) : AANoUnwind(IRP, A) {} 1962 1963 const std::string getAsStr() const override { 1964 return getAssumed() ? "nounwind" : "may-unwind"; 1965 } 1966 1967 /// See AbstractAttribute::updateImpl(...). 1968 ChangeStatus updateImpl(Attributor &A) override { 1969 auto Opcodes = { 1970 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr, 1971 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet, 1972 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume}; 1973 1974 auto CheckForNoUnwind = [&](Instruction &I) { 1975 if (!I.mayThrow()) 1976 return true; 1977 1978 if (const auto *CB = dyn_cast<CallBase>(&I)) { 1979 const auto &NoUnwindAA = A.getAAFor<AANoUnwind>( 1980 *this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED); 1981 return NoUnwindAA.isAssumedNoUnwind(); 1982 } 1983 return false; 1984 }; 1985 1986 bool UsedAssumedInformation = false; 1987 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes, 1988 UsedAssumedInformation)) 1989 return indicatePessimisticFixpoint(); 1990 1991 return ChangeStatus::UNCHANGED; 1992 } 1993 }; 1994 1995 struct AANoUnwindFunction final : public AANoUnwindImpl { 1996 AANoUnwindFunction(const IRPosition &IRP, Attributor &A) 1997 : AANoUnwindImpl(IRP, A) {} 1998 1999 /// See AbstractAttribute::trackStatistics() 2000 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) } 2001 }; 2002 2003 /// NoUnwind attribute deduction for a call sites. 2004 struct AANoUnwindCallSite final : AANoUnwindImpl { 2005 AANoUnwindCallSite(const IRPosition &IRP, Attributor &A) 2006 : AANoUnwindImpl(IRP, A) {} 2007 2008 /// See AbstractAttribute::initialize(...). 2009 void initialize(Attributor &A) override { 2010 AANoUnwindImpl::initialize(A); 2011 Function *F = getAssociatedFunction(); 2012 if (!F || F->isDeclaration()) 2013 indicatePessimisticFixpoint(); 2014 } 2015 2016 /// See AbstractAttribute::updateImpl(...). 2017 ChangeStatus updateImpl(Attributor &A) override { 2018 // TODO: Once we have call site specific value information we can provide 2019 // call site specific liveness information and then it makes 2020 // sense to specialize attributes for call sites arguments instead of 2021 // redirecting requests to the callee argument. 2022 Function *F = getAssociatedFunction(); 2023 const IRPosition &FnPos = IRPosition::function(*F); 2024 auto &FnAA = A.getAAFor<AANoUnwind>(*this, FnPos, DepClassTy::REQUIRED); 2025 return clampStateAndIndicateChange(getState(), FnAA.getState()); 2026 } 2027 2028 /// See AbstractAttribute::trackStatistics() 2029 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); } 2030 }; 2031 } // namespace 2032 2033 /// --------------------- Function Return Values ------------------------------- 2034 2035 namespace { 2036 /// "Attribute" that collects all potential returned values and the return 2037 /// instructions that they arise from. 2038 /// 2039 /// If there is a unique returned value R, the manifest method will: 2040 /// - mark R with the "returned" attribute, if R is an argument. 2041 class AAReturnedValuesImpl : public AAReturnedValues, public AbstractState { 2042 2043 /// Mapping of values potentially returned by the associated function to the 2044 /// return instructions that might return them. 2045 MapVector<Value *, SmallSetVector<ReturnInst *, 4>> ReturnedValues; 2046 2047 /// State flags 2048 /// 2049 ///{ 2050 bool IsFixed = false; 2051 bool IsValidState = true; 2052 ///} 2053 2054 public: 2055 AAReturnedValuesImpl(const IRPosition &IRP, Attributor &A) 2056 : AAReturnedValues(IRP, A) {} 2057 2058 /// See AbstractAttribute::initialize(...). 2059 void initialize(Attributor &A) override { 2060 // Reset the state. 2061 IsFixed = false; 2062 IsValidState = true; 2063 ReturnedValues.clear(); 2064 2065 Function *F = getAssociatedFunction(); 2066 if (!F || F->isDeclaration()) { 2067 indicatePessimisticFixpoint(); 2068 return; 2069 } 2070 assert(!F->getReturnType()->isVoidTy() && 2071 "Did not expect a void return type!"); 2072 2073 // The map from instruction opcodes to those instructions in the function. 2074 auto &OpcodeInstMap = A.getInfoCache().getOpcodeInstMapForFunction(*F); 2075 2076 // Look through all arguments, if one is marked as returned we are done. 2077 for (Argument &Arg : F->args()) { 2078 if (Arg.hasReturnedAttr()) { 2079 auto &ReturnInstSet = ReturnedValues[&Arg]; 2080 if (auto *Insts = OpcodeInstMap.lookup(Instruction::Ret)) 2081 for (Instruction *RI : *Insts) 2082 ReturnInstSet.insert(cast<ReturnInst>(RI)); 2083 2084 indicateOptimisticFixpoint(); 2085 return; 2086 } 2087 } 2088 2089 if (!A.isFunctionIPOAmendable(*F)) 2090 indicatePessimisticFixpoint(); 2091 } 2092 2093 /// See AbstractAttribute::manifest(...). 2094 ChangeStatus manifest(Attributor &A) override; 2095 2096 /// See AbstractAttribute::getState(...). 2097 AbstractState &getState() override { return *this; } 2098 2099 /// See AbstractAttribute::getState(...). 2100 const AbstractState &getState() const override { return *this; } 2101 2102 /// See AbstractAttribute::updateImpl(Attributor &A). 2103 ChangeStatus updateImpl(Attributor &A) override; 2104 2105 llvm::iterator_range<iterator> returned_values() override { 2106 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end()); 2107 } 2108 2109 llvm::iterator_range<const_iterator> returned_values() const override { 2110 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end()); 2111 } 2112 2113 /// Return the number of potential return values, -1 if unknown. 2114 size_t getNumReturnValues() const override { 2115 return isValidState() ? ReturnedValues.size() : -1; 2116 } 2117 2118 /// Return an assumed unique return value if a single candidate is found. If 2119 /// there cannot be one, return a nullptr. If it is not clear yet, return 2120 /// std::nullopt. 2121 std::optional<Value *> getAssumedUniqueReturnValue(Attributor &A) const; 2122 2123 /// See AbstractState::checkForAllReturnedValues(...). 2124 bool checkForAllReturnedValuesAndReturnInsts( 2125 function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)> Pred) 2126 const override; 2127 2128 /// Pretty print the attribute similar to the IR representation. 2129 const std::string getAsStr() const override; 2130 2131 /// See AbstractState::isAtFixpoint(). 2132 bool isAtFixpoint() const override { return IsFixed; } 2133 2134 /// See AbstractState::isValidState(). 2135 bool isValidState() const override { return IsValidState; } 2136 2137 /// See AbstractState::indicateOptimisticFixpoint(...). 2138 ChangeStatus indicateOptimisticFixpoint() override { 2139 IsFixed = true; 2140 return ChangeStatus::UNCHANGED; 2141 } 2142 2143 ChangeStatus indicatePessimisticFixpoint() override { 2144 IsFixed = true; 2145 IsValidState = false; 2146 return ChangeStatus::CHANGED; 2147 } 2148 }; 2149 2150 ChangeStatus AAReturnedValuesImpl::manifest(Attributor &A) { 2151 ChangeStatus Changed = ChangeStatus::UNCHANGED; 2152 2153 // Bookkeeping. 2154 assert(isValidState()); 2155 STATS_DECLTRACK(KnownReturnValues, FunctionReturn, 2156 "Number of function with known return values"); 2157 2158 // Check if we have an assumed unique return value that we could manifest. 2159 std::optional<Value *> UniqueRV = getAssumedUniqueReturnValue(A); 2160 2161 if (!UniqueRV || !*UniqueRV) 2162 return Changed; 2163 2164 // Bookkeeping. 2165 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn, 2166 "Number of function with unique return"); 2167 // If the assumed unique return value is an argument, annotate it. 2168 if (auto *UniqueRVArg = dyn_cast<Argument>(*UniqueRV)) { 2169 if (UniqueRVArg->getType()->canLosslesslyBitCastTo( 2170 getAssociatedFunction()->getReturnType())) { 2171 getIRPosition() = IRPosition::argument(*UniqueRVArg); 2172 Changed = IRAttribute::manifest(A); 2173 } 2174 } 2175 return Changed; 2176 } 2177 2178 const std::string AAReturnedValuesImpl::getAsStr() const { 2179 return (isAtFixpoint() ? "returns(#" : "may-return(#") + 2180 (isValidState() ? std::to_string(getNumReturnValues()) : "?") + ")"; 2181 } 2182 2183 std::optional<Value *> 2184 AAReturnedValuesImpl::getAssumedUniqueReturnValue(Attributor &A) const { 2185 // If checkForAllReturnedValues provides a unique value, ignoring potential 2186 // undef values that can also be present, it is assumed to be the actual 2187 // return value and forwarded to the caller of this method. If there are 2188 // multiple, a nullptr is returned indicating there cannot be a unique 2189 // returned value. 2190 std::optional<Value *> UniqueRV; 2191 Type *Ty = getAssociatedFunction()->getReturnType(); 2192 2193 auto Pred = [&](Value &RV) -> bool { 2194 UniqueRV = AA::combineOptionalValuesInAAValueLatice(UniqueRV, &RV, Ty); 2195 return UniqueRV != std::optional<Value *>(nullptr); 2196 }; 2197 2198 if (!A.checkForAllReturnedValues(Pred, *this)) 2199 UniqueRV = nullptr; 2200 2201 return UniqueRV; 2202 } 2203 2204 bool AAReturnedValuesImpl::checkForAllReturnedValuesAndReturnInsts( 2205 function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)> Pred) 2206 const { 2207 if (!isValidState()) 2208 return false; 2209 2210 // Check all returned values but ignore call sites as long as we have not 2211 // encountered an overdefined one during an update. 2212 for (const auto &It : ReturnedValues) { 2213 Value *RV = It.first; 2214 if (!Pred(*RV, It.second)) 2215 return false; 2216 } 2217 2218 return true; 2219 } 2220 2221 ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) { 2222 ChangeStatus Changed = ChangeStatus::UNCHANGED; 2223 2224 SmallVector<AA::ValueAndContext> Values; 2225 bool UsedAssumedInformation = false; 2226 auto ReturnInstCB = [&](Instruction &I) { 2227 ReturnInst &Ret = cast<ReturnInst>(I); 2228 Values.clear(); 2229 if (!A.getAssumedSimplifiedValues(IRPosition::value(*Ret.getReturnValue()), 2230 *this, Values, AA::Intraprocedural, 2231 UsedAssumedInformation)) 2232 Values.push_back({*Ret.getReturnValue(), Ret}); 2233 2234 for (auto &VAC : Values) { 2235 assert(AA::isValidInScope(*VAC.getValue(), Ret.getFunction()) && 2236 "Assumed returned value should be valid in function scope!"); 2237 if (ReturnedValues[VAC.getValue()].insert(&Ret)) 2238 Changed = ChangeStatus::CHANGED; 2239 } 2240 return true; 2241 }; 2242 2243 // Discover returned values from all live returned instructions in the 2244 // associated function. 2245 if (!A.checkForAllInstructions(ReturnInstCB, *this, {Instruction::Ret}, 2246 UsedAssumedInformation)) 2247 return indicatePessimisticFixpoint(); 2248 return Changed; 2249 } 2250 2251 struct AAReturnedValuesFunction final : public AAReturnedValuesImpl { 2252 AAReturnedValuesFunction(const IRPosition &IRP, Attributor &A) 2253 : AAReturnedValuesImpl(IRP, A) {} 2254 2255 /// See AbstractAttribute::trackStatistics() 2256 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(returned) } 2257 }; 2258 2259 /// Returned values information for a call sites. 2260 struct AAReturnedValuesCallSite final : AAReturnedValuesImpl { 2261 AAReturnedValuesCallSite(const IRPosition &IRP, Attributor &A) 2262 : AAReturnedValuesImpl(IRP, A) {} 2263 2264 /// See AbstractAttribute::initialize(...). 2265 void initialize(Attributor &A) override { 2266 // TODO: Once we have call site specific value information we can provide 2267 // call site specific liveness information and then it makes 2268 // sense to specialize attributes for call sites instead of 2269 // redirecting requests to the callee. 2270 llvm_unreachable("Abstract attributes for returned values are not " 2271 "supported for call sites yet!"); 2272 } 2273 2274 /// See AbstractAttribute::updateImpl(...). 2275 ChangeStatus updateImpl(Attributor &A) override { 2276 return indicatePessimisticFixpoint(); 2277 } 2278 2279 /// See AbstractAttribute::trackStatistics() 2280 void trackStatistics() const override {} 2281 }; 2282 } // namespace 2283 2284 /// ------------------------ NoSync Function Attribute ------------------------- 2285 2286 bool AANoSync::isAlignedBarrier(const CallBase &CB, bool ExecutedAligned) { 2287 switch (CB.getIntrinsicID()) { 2288 case Intrinsic::nvvm_barrier0: 2289 case Intrinsic::nvvm_barrier0_and: 2290 case Intrinsic::nvvm_barrier0_or: 2291 case Intrinsic::nvvm_barrier0_popc: 2292 return true; 2293 case Intrinsic::amdgcn_s_barrier: 2294 if (ExecutedAligned) 2295 return true; 2296 break; 2297 default: 2298 break; 2299 } 2300 return hasAssumption(CB, KnownAssumptionString("ompx_aligned_barrier")); 2301 } 2302 2303 bool AANoSync::isNonRelaxedAtomic(const Instruction *I) { 2304 if (!I->isAtomic()) 2305 return false; 2306 2307 if (auto *FI = dyn_cast<FenceInst>(I)) 2308 // All legal orderings for fence are stronger than monotonic. 2309 return FI->getSyncScopeID() != SyncScope::SingleThread; 2310 if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) { 2311 // Unordered is not a legal ordering for cmpxchg. 2312 return (AI->getSuccessOrdering() != AtomicOrdering::Monotonic || 2313 AI->getFailureOrdering() != AtomicOrdering::Monotonic); 2314 } 2315 2316 AtomicOrdering Ordering; 2317 switch (I->getOpcode()) { 2318 case Instruction::AtomicRMW: 2319 Ordering = cast<AtomicRMWInst>(I)->getOrdering(); 2320 break; 2321 case Instruction::Store: 2322 Ordering = cast<StoreInst>(I)->getOrdering(); 2323 break; 2324 case Instruction::Load: 2325 Ordering = cast<LoadInst>(I)->getOrdering(); 2326 break; 2327 default: 2328 llvm_unreachable( 2329 "New atomic operations need to be known in the attributor."); 2330 } 2331 2332 return (Ordering != AtomicOrdering::Unordered && 2333 Ordering != AtomicOrdering::Monotonic); 2334 } 2335 2336 /// Return true if this intrinsic is nosync. This is only used for intrinsics 2337 /// which would be nosync except that they have a volatile flag. All other 2338 /// intrinsics are simply annotated with the nosync attribute in Intrinsics.td. 2339 bool AANoSync::isNoSyncIntrinsic(const Instruction *I) { 2340 if (auto *MI = dyn_cast<MemIntrinsic>(I)) 2341 return !MI->isVolatile(); 2342 return false; 2343 } 2344 2345 namespace { 2346 struct AANoSyncImpl : AANoSync { 2347 AANoSyncImpl(const IRPosition &IRP, Attributor &A) : AANoSync(IRP, A) {} 2348 2349 const std::string getAsStr() const override { 2350 return getAssumed() ? "nosync" : "may-sync"; 2351 } 2352 2353 /// See AbstractAttribute::updateImpl(...). 2354 ChangeStatus updateImpl(Attributor &A) override; 2355 }; 2356 2357 ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) { 2358 2359 auto CheckRWInstForNoSync = [&](Instruction &I) { 2360 return AA::isNoSyncInst(A, I, *this); 2361 }; 2362 2363 auto CheckForNoSync = [&](Instruction &I) { 2364 // At this point we handled all read/write effects and they are all 2365 // nosync, so they can be skipped. 2366 if (I.mayReadOrWriteMemory()) 2367 return true; 2368 2369 // non-convergent and readnone imply nosync. 2370 return !cast<CallBase>(I).isConvergent(); 2371 }; 2372 2373 bool UsedAssumedInformation = false; 2374 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this, 2375 UsedAssumedInformation) || 2376 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this, 2377 UsedAssumedInformation)) 2378 return indicatePessimisticFixpoint(); 2379 2380 return ChangeStatus::UNCHANGED; 2381 } 2382 2383 struct AANoSyncFunction final : public AANoSyncImpl { 2384 AANoSyncFunction(const IRPosition &IRP, Attributor &A) 2385 : AANoSyncImpl(IRP, A) {} 2386 2387 /// See AbstractAttribute::trackStatistics() 2388 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) } 2389 }; 2390 2391 /// NoSync attribute deduction for a call sites. 2392 struct AANoSyncCallSite final : AANoSyncImpl { 2393 AANoSyncCallSite(const IRPosition &IRP, Attributor &A) 2394 : AANoSyncImpl(IRP, A) {} 2395 2396 /// See AbstractAttribute::initialize(...). 2397 void initialize(Attributor &A) override { 2398 AANoSyncImpl::initialize(A); 2399 Function *F = getAssociatedFunction(); 2400 if (!F || F->isDeclaration()) 2401 indicatePessimisticFixpoint(); 2402 } 2403 2404 /// See AbstractAttribute::updateImpl(...). 2405 ChangeStatus updateImpl(Attributor &A) override { 2406 // TODO: Once we have call site specific value information we can provide 2407 // call site specific liveness information and then it makes 2408 // sense to specialize attributes for call sites arguments instead of 2409 // redirecting requests to the callee argument. 2410 Function *F = getAssociatedFunction(); 2411 const IRPosition &FnPos = IRPosition::function(*F); 2412 auto &FnAA = A.getAAFor<AANoSync>(*this, FnPos, DepClassTy::REQUIRED); 2413 return clampStateAndIndicateChange(getState(), FnAA.getState()); 2414 } 2415 2416 /// See AbstractAttribute::trackStatistics() 2417 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); } 2418 }; 2419 } // namespace 2420 2421 /// ------------------------ No-Free Attributes ---------------------------- 2422 2423 namespace { 2424 struct AANoFreeImpl : public AANoFree { 2425 AANoFreeImpl(const IRPosition &IRP, Attributor &A) : AANoFree(IRP, A) {} 2426 2427 /// See AbstractAttribute::updateImpl(...). 2428 ChangeStatus updateImpl(Attributor &A) override { 2429 auto CheckForNoFree = [&](Instruction &I) { 2430 const auto &CB = cast<CallBase>(I); 2431 if (CB.hasFnAttr(Attribute::NoFree)) 2432 return true; 2433 2434 const auto &NoFreeAA = A.getAAFor<AANoFree>( 2435 *this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED); 2436 return NoFreeAA.isAssumedNoFree(); 2437 }; 2438 2439 bool UsedAssumedInformation = false; 2440 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this, 2441 UsedAssumedInformation)) 2442 return indicatePessimisticFixpoint(); 2443 return ChangeStatus::UNCHANGED; 2444 } 2445 2446 /// See AbstractAttribute::getAsStr(). 2447 const std::string getAsStr() const override { 2448 return getAssumed() ? "nofree" : "may-free"; 2449 } 2450 }; 2451 2452 struct AANoFreeFunction final : public AANoFreeImpl { 2453 AANoFreeFunction(const IRPosition &IRP, Attributor &A) 2454 : AANoFreeImpl(IRP, A) {} 2455 2456 /// See AbstractAttribute::trackStatistics() 2457 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) } 2458 }; 2459 2460 /// NoFree attribute deduction for a call sites. 2461 struct AANoFreeCallSite final : AANoFreeImpl { 2462 AANoFreeCallSite(const IRPosition &IRP, Attributor &A) 2463 : AANoFreeImpl(IRP, A) {} 2464 2465 /// See AbstractAttribute::initialize(...). 2466 void initialize(Attributor &A) override { 2467 AANoFreeImpl::initialize(A); 2468 Function *F = getAssociatedFunction(); 2469 if (!F || F->isDeclaration()) 2470 indicatePessimisticFixpoint(); 2471 } 2472 2473 /// See AbstractAttribute::updateImpl(...). 2474 ChangeStatus updateImpl(Attributor &A) override { 2475 // TODO: Once we have call site specific value information we can provide 2476 // call site specific liveness information and then it makes 2477 // sense to specialize attributes for call sites arguments instead of 2478 // redirecting requests to the callee argument. 2479 Function *F = getAssociatedFunction(); 2480 const IRPosition &FnPos = IRPosition::function(*F); 2481 auto &FnAA = A.getAAFor<AANoFree>(*this, FnPos, DepClassTy::REQUIRED); 2482 return clampStateAndIndicateChange(getState(), FnAA.getState()); 2483 } 2484 2485 /// See AbstractAttribute::trackStatistics() 2486 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); } 2487 }; 2488 2489 /// NoFree attribute for floating values. 2490 struct AANoFreeFloating : AANoFreeImpl { 2491 AANoFreeFloating(const IRPosition &IRP, Attributor &A) 2492 : AANoFreeImpl(IRP, A) {} 2493 2494 /// See AbstractAttribute::trackStatistics() 2495 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)} 2496 2497 /// See Abstract Attribute::updateImpl(...). 2498 ChangeStatus updateImpl(Attributor &A) override { 2499 const IRPosition &IRP = getIRPosition(); 2500 2501 const auto &NoFreeAA = A.getAAFor<AANoFree>( 2502 *this, IRPosition::function_scope(IRP), DepClassTy::OPTIONAL); 2503 if (NoFreeAA.isAssumedNoFree()) 2504 return ChangeStatus::UNCHANGED; 2505 2506 Value &AssociatedValue = getIRPosition().getAssociatedValue(); 2507 auto Pred = [&](const Use &U, bool &Follow) -> bool { 2508 Instruction *UserI = cast<Instruction>(U.getUser()); 2509 if (auto *CB = dyn_cast<CallBase>(UserI)) { 2510 if (CB->isBundleOperand(&U)) 2511 return false; 2512 if (!CB->isArgOperand(&U)) 2513 return true; 2514 unsigned ArgNo = CB->getArgOperandNo(&U); 2515 2516 const auto &NoFreeArg = A.getAAFor<AANoFree>( 2517 *this, IRPosition::callsite_argument(*CB, ArgNo), 2518 DepClassTy::REQUIRED); 2519 return NoFreeArg.isAssumedNoFree(); 2520 } 2521 2522 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) || 2523 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) { 2524 Follow = true; 2525 return true; 2526 } 2527 if (isa<StoreInst>(UserI) || isa<LoadInst>(UserI) || 2528 isa<ReturnInst>(UserI)) 2529 return true; 2530 2531 // Unknown user. 2532 return false; 2533 }; 2534 if (!A.checkForAllUses(Pred, *this, AssociatedValue)) 2535 return indicatePessimisticFixpoint(); 2536 2537 return ChangeStatus::UNCHANGED; 2538 } 2539 }; 2540 2541 /// NoFree attribute for a call site argument. 2542 struct AANoFreeArgument final : AANoFreeFloating { 2543 AANoFreeArgument(const IRPosition &IRP, Attributor &A) 2544 : AANoFreeFloating(IRP, A) {} 2545 2546 /// See AbstractAttribute::trackStatistics() 2547 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) } 2548 }; 2549 2550 /// NoFree attribute for call site arguments. 2551 struct AANoFreeCallSiteArgument final : AANoFreeFloating { 2552 AANoFreeCallSiteArgument(const IRPosition &IRP, Attributor &A) 2553 : AANoFreeFloating(IRP, A) {} 2554 2555 /// See AbstractAttribute::updateImpl(...). 2556 ChangeStatus updateImpl(Attributor &A) override { 2557 // TODO: Once we have call site specific value information we can provide 2558 // call site specific liveness information and then it makes 2559 // sense to specialize attributes for call sites arguments instead of 2560 // redirecting requests to the callee argument. 2561 Argument *Arg = getAssociatedArgument(); 2562 if (!Arg) 2563 return indicatePessimisticFixpoint(); 2564 const IRPosition &ArgPos = IRPosition::argument(*Arg); 2565 auto &ArgAA = A.getAAFor<AANoFree>(*this, ArgPos, DepClassTy::REQUIRED); 2566 return clampStateAndIndicateChange(getState(), ArgAA.getState()); 2567 } 2568 2569 /// See AbstractAttribute::trackStatistics() 2570 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nofree)}; 2571 }; 2572 2573 /// NoFree attribute for function return value. 2574 struct AANoFreeReturned final : AANoFreeFloating { 2575 AANoFreeReturned(const IRPosition &IRP, Attributor &A) 2576 : AANoFreeFloating(IRP, A) { 2577 llvm_unreachable("NoFree is not applicable to function returns!"); 2578 } 2579 2580 /// See AbstractAttribute::initialize(...). 2581 void initialize(Attributor &A) override { 2582 llvm_unreachable("NoFree is not applicable to function returns!"); 2583 } 2584 2585 /// See AbstractAttribute::updateImpl(...). 2586 ChangeStatus updateImpl(Attributor &A) override { 2587 llvm_unreachable("NoFree is not applicable to function returns!"); 2588 } 2589 2590 /// See AbstractAttribute::trackStatistics() 2591 void trackStatistics() const override {} 2592 }; 2593 2594 /// NoFree attribute deduction for a call site return value. 2595 struct AANoFreeCallSiteReturned final : AANoFreeFloating { 2596 AANoFreeCallSiteReturned(const IRPosition &IRP, Attributor &A) 2597 : AANoFreeFloating(IRP, A) {} 2598 2599 ChangeStatus manifest(Attributor &A) override { 2600 return ChangeStatus::UNCHANGED; 2601 } 2602 /// See AbstractAttribute::trackStatistics() 2603 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) } 2604 }; 2605 } // namespace 2606 2607 /// ------------------------ NonNull Argument Attribute ------------------------ 2608 namespace { 2609 static int64_t getKnownNonNullAndDerefBytesForUse( 2610 Attributor &A, const AbstractAttribute &QueryingAA, Value &AssociatedValue, 2611 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) { 2612 TrackUse = false; 2613 2614 const Value *UseV = U->get(); 2615 if (!UseV->getType()->isPointerTy()) 2616 return 0; 2617 2618 // We need to follow common pointer manipulation uses to the accesses they 2619 // feed into. We can try to be smart to avoid looking through things we do not 2620 // like for now, e.g., non-inbounds GEPs. 2621 if (isa<CastInst>(I)) { 2622 TrackUse = true; 2623 return 0; 2624 } 2625 2626 if (isa<GetElementPtrInst>(I)) { 2627 TrackUse = true; 2628 return 0; 2629 } 2630 2631 Type *PtrTy = UseV->getType(); 2632 const Function *F = I->getFunction(); 2633 bool NullPointerIsDefined = 2634 F ? llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace()) : true; 2635 const DataLayout &DL = A.getInfoCache().getDL(); 2636 if (const auto *CB = dyn_cast<CallBase>(I)) { 2637 if (CB->isBundleOperand(U)) { 2638 if (RetainedKnowledge RK = getKnowledgeFromUse( 2639 U, {Attribute::NonNull, Attribute::Dereferenceable})) { 2640 IsNonNull |= 2641 (RK.AttrKind == Attribute::NonNull || !NullPointerIsDefined); 2642 return RK.ArgValue; 2643 } 2644 return 0; 2645 } 2646 2647 if (CB->isCallee(U)) { 2648 IsNonNull |= !NullPointerIsDefined; 2649 return 0; 2650 } 2651 2652 unsigned ArgNo = CB->getArgOperandNo(U); 2653 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo); 2654 // As long as we only use known information there is no need to track 2655 // dependences here. 2656 auto &DerefAA = 2657 A.getAAFor<AADereferenceable>(QueryingAA, IRP, DepClassTy::NONE); 2658 IsNonNull |= DerefAA.isKnownNonNull(); 2659 return DerefAA.getKnownDereferenceableBytes(); 2660 } 2661 2662 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I); 2663 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile()) 2664 return 0; 2665 2666 int64_t Offset; 2667 const Value *Base = 2668 getMinimalBaseOfPointer(A, QueryingAA, Loc->Ptr, Offset, DL); 2669 if (Base && Base == &AssociatedValue) { 2670 int64_t DerefBytes = Loc->Size.getValue() + Offset; 2671 IsNonNull |= !NullPointerIsDefined; 2672 return std::max(int64_t(0), DerefBytes); 2673 } 2674 2675 /// Corner case when an offset is 0. 2676 Base = GetPointerBaseWithConstantOffset(Loc->Ptr, Offset, DL, 2677 /*AllowNonInbounds*/ true); 2678 if (Base && Base == &AssociatedValue && Offset == 0) { 2679 int64_t DerefBytes = Loc->Size.getValue(); 2680 IsNonNull |= !NullPointerIsDefined; 2681 return std::max(int64_t(0), DerefBytes); 2682 } 2683 2684 return 0; 2685 } 2686 2687 struct AANonNullImpl : AANonNull { 2688 AANonNullImpl(const IRPosition &IRP, Attributor &A) 2689 : AANonNull(IRP, A), 2690 NullIsDefined(NullPointerIsDefined( 2691 getAnchorScope(), 2692 getAssociatedValue().getType()->getPointerAddressSpace())) {} 2693 2694 /// See AbstractAttribute::initialize(...). 2695 void initialize(Attributor &A) override { 2696 Value &V = *getAssociatedValue().stripPointerCasts(); 2697 if (!NullIsDefined && 2698 hasAttr({Attribute::NonNull, Attribute::Dereferenceable}, 2699 /* IgnoreSubsumingPositions */ false, &A)) { 2700 indicateOptimisticFixpoint(); 2701 return; 2702 } 2703 2704 if (isa<ConstantPointerNull>(V)) { 2705 indicatePessimisticFixpoint(); 2706 return; 2707 } 2708 2709 AANonNull::initialize(A); 2710 2711 bool CanBeNull, CanBeFreed; 2712 if (V.getPointerDereferenceableBytes(A.getDataLayout(), CanBeNull, 2713 CanBeFreed)) { 2714 if (!CanBeNull) { 2715 indicateOptimisticFixpoint(); 2716 return; 2717 } 2718 } 2719 2720 if (isa<GlobalValue>(V)) { 2721 indicatePessimisticFixpoint(); 2722 return; 2723 } 2724 2725 if (Instruction *CtxI = getCtxI()) 2726 followUsesInMBEC(*this, A, getState(), *CtxI); 2727 } 2728 2729 /// See followUsesInMBEC 2730 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I, 2731 AANonNull::StateType &State) { 2732 bool IsNonNull = false; 2733 bool TrackUse = false; 2734 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I, 2735 IsNonNull, TrackUse); 2736 State.setKnown(IsNonNull); 2737 return TrackUse; 2738 } 2739 2740 /// See AbstractAttribute::getAsStr(). 2741 const std::string getAsStr() const override { 2742 return getAssumed() ? "nonnull" : "may-null"; 2743 } 2744 2745 /// Flag to determine if the underlying value can be null and still allow 2746 /// valid accesses. 2747 const bool NullIsDefined; 2748 }; 2749 2750 /// NonNull attribute for a floating value. 2751 struct AANonNullFloating : public AANonNullImpl { 2752 AANonNullFloating(const IRPosition &IRP, Attributor &A) 2753 : AANonNullImpl(IRP, A) {} 2754 2755 /// See AbstractAttribute::updateImpl(...). 2756 ChangeStatus updateImpl(Attributor &A) override { 2757 const DataLayout &DL = A.getDataLayout(); 2758 2759 bool Stripped; 2760 bool UsedAssumedInformation = false; 2761 SmallVector<AA::ValueAndContext> Values; 2762 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values, 2763 AA::AnyScope, UsedAssumedInformation)) { 2764 Values.push_back({getAssociatedValue(), getCtxI()}); 2765 Stripped = false; 2766 } else { 2767 Stripped = Values.size() != 1 || 2768 Values.front().getValue() != &getAssociatedValue(); 2769 } 2770 2771 DominatorTree *DT = nullptr; 2772 AssumptionCache *AC = nullptr; 2773 InformationCache &InfoCache = A.getInfoCache(); 2774 if (const Function *Fn = getAnchorScope()) { 2775 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*Fn); 2776 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*Fn); 2777 } 2778 2779 AANonNull::StateType T; 2780 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool { 2781 const auto &AA = A.getAAFor<AANonNull>(*this, IRPosition::value(V), 2782 DepClassTy::REQUIRED); 2783 if (!Stripped && this == &AA) { 2784 if (!isKnownNonZero(&V, DL, 0, AC, CtxI, DT)) 2785 T.indicatePessimisticFixpoint(); 2786 } else { 2787 // Use abstract attribute information. 2788 const AANonNull::StateType &NS = AA.getState(); 2789 T ^= NS; 2790 } 2791 return T.isValidState(); 2792 }; 2793 2794 for (const auto &VAC : Values) 2795 if (!VisitValueCB(*VAC.getValue(), VAC.getCtxI())) 2796 return indicatePessimisticFixpoint(); 2797 2798 return clampStateAndIndicateChange(getState(), T); 2799 } 2800 2801 /// See AbstractAttribute::trackStatistics() 2802 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) } 2803 }; 2804 2805 /// NonNull attribute for function return value. 2806 struct AANonNullReturned final 2807 : AAReturnedFromReturnedValues<AANonNull, AANonNull> { 2808 AANonNullReturned(const IRPosition &IRP, Attributor &A) 2809 : AAReturnedFromReturnedValues<AANonNull, AANonNull>(IRP, A) {} 2810 2811 /// See AbstractAttribute::getAsStr(). 2812 const std::string getAsStr() const override { 2813 return getAssumed() ? "nonnull" : "may-null"; 2814 } 2815 2816 /// See AbstractAttribute::trackStatistics() 2817 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) } 2818 }; 2819 2820 /// NonNull attribute for function argument. 2821 struct AANonNullArgument final 2822 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl> { 2823 AANonNullArgument(const IRPosition &IRP, Attributor &A) 2824 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl>(IRP, A) {} 2825 2826 /// See AbstractAttribute::trackStatistics() 2827 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) } 2828 }; 2829 2830 struct AANonNullCallSiteArgument final : AANonNullFloating { 2831 AANonNullCallSiteArgument(const IRPosition &IRP, Attributor &A) 2832 : AANonNullFloating(IRP, A) {} 2833 2834 /// See AbstractAttribute::trackStatistics() 2835 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) } 2836 }; 2837 2838 /// NonNull attribute for a call site return position. 2839 struct AANonNullCallSiteReturned final 2840 : AACallSiteReturnedFromReturned<AANonNull, AANonNullImpl> { 2841 AANonNullCallSiteReturned(const IRPosition &IRP, Attributor &A) 2842 : AACallSiteReturnedFromReturned<AANonNull, AANonNullImpl>(IRP, A) {} 2843 2844 /// See AbstractAttribute::trackStatistics() 2845 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) } 2846 }; 2847 } // namespace 2848 2849 /// ------------------------ No-Recurse Attributes ---------------------------- 2850 2851 namespace { 2852 struct AANoRecurseImpl : public AANoRecurse { 2853 AANoRecurseImpl(const IRPosition &IRP, Attributor &A) : AANoRecurse(IRP, A) {} 2854 2855 /// See AbstractAttribute::getAsStr() 2856 const std::string getAsStr() const override { 2857 return getAssumed() ? "norecurse" : "may-recurse"; 2858 } 2859 }; 2860 2861 struct AANoRecurseFunction final : AANoRecurseImpl { 2862 AANoRecurseFunction(const IRPosition &IRP, Attributor &A) 2863 : AANoRecurseImpl(IRP, A) {} 2864 2865 /// See AbstractAttribute::updateImpl(...). 2866 ChangeStatus updateImpl(Attributor &A) override { 2867 2868 // If all live call sites are known to be no-recurse, we are as well. 2869 auto CallSitePred = [&](AbstractCallSite ACS) { 2870 const auto &NoRecurseAA = A.getAAFor<AANoRecurse>( 2871 *this, IRPosition::function(*ACS.getInstruction()->getFunction()), 2872 DepClassTy::NONE); 2873 return NoRecurseAA.isKnownNoRecurse(); 2874 }; 2875 bool UsedAssumedInformation = false; 2876 if (A.checkForAllCallSites(CallSitePred, *this, true, 2877 UsedAssumedInformation)) { 2878 // If we know all call sites and all are known no-recurse, we are done. 2879 // If all known call sites, which might not be all that exist, are known 2880 // to be no-recurse, we are not done but we can continue to assume 2881 // no-recurse. If one of the call sites we have not visited will become 2882 // live, another update is triggered. 2883 if (!UsedAssumedInformation) 2884 indicateOptimisticFixpoint(); 2885 return ChangeStatus::UNCHANGED; 2886 } 2887 2888 const AAInterFnReachability &EdgeReachability = 2889 A.getAAFor<AAInterFnReachability>(*this, getIRPosition(), 2890 DepClassTy::REQUIRED); 2891 if (EdgeReachability.canReach(A, *getAnchorScope())) 2892 return indicatePessimisticFixpoint(); 2893 return ChangeStatus::UNCHANGED; 2894 } 2895 2896 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) } 2897 }; 2898 2899 /// NoRecurse attribute deduction for a call sites. 2900 struct AANoRecurseCallSite final : AANoRecurseImpl { 2901 AANoRecurseCallSite(const IRPosition &IRP, Attributor &A) 2902 : AANoRecurseImpl(IRP, A) {} 2903 2904 /// See AbstractAttribute::initialize(...). 2905 void initialize(Attributor &A) override { 2906 AANoRecurseImpl::initialize(A); 2907 Function *F = getAssociatedFunction(); 2908 if (!F || F->isDeclaration()) 2909 indicatePessimisticFixpoint(); 2910 } 2911 2912 /// See AbstractAttribute::updateImpl(...). 2913 ChangeStatus updateImpl(Attributor &A) override { 2914 // TODO: Once we have call site specific value information we can provide 2915 // call site specific liveness information and then it makes 2916 // sense to specialize attributes for call sites arguments instead of 2917 // redirecting requests to the callee argument. 2918 Function *F = getAssociatedFunction(); 2919 const IRPosition &FnPos = IRPosition::function(*F); 2920 auto &FnAA = A.getAAFor<AANoRecurse>(*this, FnPos, DepClassTy::REQUIRED); 2921 return clampStateAndIndicateChange(getState(), FnAA.getState()); 2922 } 2923 2924 /// See AbstractAttribute::trackStatistics() 2925 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); } 2926 }; 2927 } // namespace 2928 2929 /// -------------------- Undefined-Behavior Attributes ------------------------ 2930 2931 namespace { 2932 struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { 2933 AAUndefinedBehaviorImpl(const IRPosition &IRP, Attributor &A) 2934 : AAUndefinedBehavior(IRP, A) {} 2935 2936 /// See AbstractAttribute::updateImpl(...). 2937 // through a pointer (i.e. also branches etc.) 2938 ChangeStatus updateImpl(Attributor &A) override { 2939 const size_t UBPrevSize = KnownUBInsts.size(); 2940 const size_t NoUBPrevSize = AssumedNoUBInsts.size(); 2941 2942 auto InspectMemAccessInstForUB = [&](Instruction &I) { 2943 // Lang ref now states volatile store is not UB, let's skip them. 2944 if (I.isVolatile() && I.mayWriteToMemory()) 2945 return true; 2946 2947 // Skip instructions that are already saved. 2948 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I)) 2949 return true; 2950 2951 // If we reach here, we know we have an instruction 2952 // that accesses memory through a pointer operand, 2953 // for which getPointerOperand() should give it to us. 2954 Value *PtrOp = 2955 const_cast<Value *>(getPointerOperand(&I, /* AllowVolatile */ true)); 2956 assert(PtrOp && 2957 "Expected pointer operand of memory accessing instruction"); 2958 2959 // Either we stopped and the appropriate action was taken, 2960 // or we got back a simplified value to continue. 2961 std::optional<Value *> SimplifiedPtrOp = 2962 stopOnUndefOrAssumed(A, PtrOp, &I); 2963 if (!SimplifiedPtrOp || !*SimplifiedPtrOp) 2964 return true; 2965 const Value *PtrOpVal = *SimplifiedPtrOp; 2966 2967 // A memory access through a pointer is considered UB 2968 // only if the pointer has constant null value. 2969 // TODO: Expand it to not only check constant values. 2970 if (!isa<ConstantPointerNull>(PtrOpVal)) { 2971 AssumedNoUBInsts.insert(&I); 2972 return true; 2973 } 2974 const Type *PtrTy = PtrOpVal->getType(); 2975 2976 // Because we only consider instructions inside functions, 2977 // assume that a parent function exists. 2978 const Function *F = I.getFunction(); 2979 2980 // A memory access using constant null pointer is only considered UB 2981 // if null pointer is _not_ defined for the target platform. 2982 if (llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace())) 2983 AssumedNoUBInsts.insert(&I); 2984 else 2985 KnownUBInsts.insert(&I); 2986 return true; 2987 }; 2988 2989 auto InspectBrInstForUB = [&](Instruction &I) { 2990 // A conditional branch instruction is considered UB if it has `undef` 2991 // condition. 2992 2993 // Skip instructions that are already saved. 2994 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I)) 2995 return true; 2996 2997 // We know we have a branch instruction. 2998 auto *BrInst = cast<BranchInst>(&I); 2999 3000 // Unconditional branches are never considered UB. 3001 if (BrInst->isUnconditional()) 3002 return true; 3003 3004 // Either we stopped and the appropriate action was taken, 3005 // or we got back a simplified value to continue. 3006 std::optional<Value *> SimplifiedCond = 3007 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst); 3008 if (!SimplifiedCond || !*SimplifiedCond) 3009 return true; 3010 AssumedNoUBInsts.insert(&I); 3011 return true; 3012 }; 3013 3014 auto InspectCallSiteForUB = [&](Instruction &I) { 3015 // Check whether a callsite always cause UB or not 3016 3017 // Skip instructions that are already saved. 3018 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I)) 3019 return true; 3020 3021 // Check nonnull and noundef argument attribute violation for each 3022 // callsite. 3023 CallBase &CB = cast<CallBase>(I); 3024 Function *Callee = CB.getCalledFunction(); 3025 if (!Callee) 3026 return true; 3027 for (unsigned idx = 0; idx < CB.arg_size(); idx++) { 3028 // If current argument is known to be simplified to null pointer and the 3029 // corresponding argument position is known to have nonnull attribute, 3030 // the argument is poison. Furthermore, if the argument is poison and 3031 // the position is known to have noundef attriubte, this callsite is 3032 // considered UB. 3033 if (idx >= Callee->arg_size()) 3034 break; 3035 Value *ArgVal = CB.getArgOperand(idx); 3036 if (!ArgVal) 3037 continue; 3038 // Here, we handle three cases. 3039 // (1) Not having a value means it is dead. (we can replace the value 3040 // with undef) 3041 // (2) Simplified to undef. The argument violate noundef attriubte. 3042 // (3) Simplified to null pointer where known to be nonnull. 3043 // The argument is a poison value and violate noundef attribute. 3044 IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx); 3045 auto &NoUndefAA = 3046 A.getAAFor<AANoUndef>(*this, CalleeArgumentIRP, DepClassTy::NONE); 3047 if (!NoUndefAA.isKnownNoUndef()) 3048 continue; 3049 bool UsedAssumedInformation = false; 3050 std::optional<Value *> SimplifiedVal = 3051 A.getAssumedSimplified(IRPosition::value(*ArgVal), *this, 3052 UsedAssumedInformation, AA::Interprocedural); 3053 if (UsedAssumedInformation) 3054 continue; 3055 if (SimplifiedVal && !*SimplifiedVal) 3056 return true; 3057 if (!SimplifiedVal || isa<UndefValue>(**SimplifiedVal)) { 3058 KnownUBInsts.insert(&I); 3059 continue; 3060 } 3061 if (!ArgVal->getType()->isPointerTy() || 3062 !isa<ConstantPointerNull>(**SimplifiedVal)) 3063 continue; 3064 auto &NonNullAA = 3065 A.getAAFor<AANonNull>(*this, CalleeArgumentIRP, DepClassTy::NONE); 3066 if (NonNullAA.isKnownNonNull()) 3067 KnownUBInsts.insert(&I); 3068 } 3069 return true; 3070 }; 3071 3072 auto InspectReturnInstForUB = [&](Instruction &I) { 3073 auto &RI = cast<ReturnInst>(I); 3074 // Either we stopped and the appropriate action was taken, 3075 // or we got back a simplified return value to continue. 3076 std::optional<Value *> SimplifiedRetValue = 3077 stopOnUndefOrAssumed(A, RI.getReturnValue(), &I); 3078 if (!SimplifiedRetValue || !*SimplifiedRetValue) 3079 return true; 3080 3081 // Check if a return instruction always cause UB or not 3082 // Note: It is guaranteed that the returned position of the anchor 3083 // scope has noundef attribute when this is called. 3084 // We also ensure the return position is not "assumed dead" 3085 // because the returned value was then potentially simplified to 3086 // `undef` in AAReturnedValues without removing the `noundef` 3087 // attribute yet. 3088 3089 // When the returned position has noundef attriubte, UB occurs in the 3090 // following cases. 3091 // (1) Returned value is known to be undef. 3092 // (2) The value is known to be a null pointer and the returned 3093 // position has nonnull attribute (because the returned value is 3094 // poison). 3095 if (isa<ConstantPointerNull>(*SimplifiedRetValue)) { 3096 auto &NonNullAA = A.getAAFor<AANonNull>( 3097 *this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE); 3098 if (NonNullAA.isKnownNonNull()) 3099 KnownUBInsts.insert(&I); 3100 } 3101 3102 return true; 3103 }; 3104 3105 bool UsedAssumedInformation = false; 3106 A.checkForAllInstructions(InspectMemAccessInstForUB, *this, 3107 {Instruction::Load, Instruction::Store, 3108 Instruction::AtomicCmpXchg, 3109 Instruction::AtomicRMW}, 3110 UsedAssumedInformation, 3111 /* CheckBBLivenessOnly */ true); 3112 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::Br}, 3113 UsedAssumedInformation, 3114 /* CheckBBLivenessOnly */ true); 3115 A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this, 3116 UsedAssumedInformation); 3117 3118 // If the returned position of the anchor scope has noundef attriubte, check 3119 // all returned instructions. 3120 if (!getAnchorScope()->getReturnType()->isVoidTy()) { 3121 const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope()); 3122 if (!A.isAssumedDead(ReturnIRP, this, nullptr, UsedAssumedInformation)) { 3123 auto &RetPosNoUndefAA = 3124 A.getAAFor<AANoUndef>(*this, ReturnIRP, DepClassTy::NONE); 3125 if (RetPosNoUndefAA.isKnownNoUndef()) 3126 A.checkForAllInstructions(InspectReturnInstForUB, *this, 3127 {Instruction::Ret}, UsedAssumedInformation, 3128 /* CheckBBLivenessOnly */ true); 3129 } 3130 } 3131 3132 if (NoUBPrevSize != AssumedNoUBInsts.size() || 3133 UBPrevSize != KnownUBInsts.size()) 3134 return ChangeStatus::CHANGED; 3135 return ChangeStatus::UNCHANGED; 3136 } 3137 3138 bool isKnownToCauseUB(Instruction *I) const override { 3139 return KnownUBInsts.count(I); 3140 } 3141 3142 bool isAssumedToCauseUB(Instruction *I) const override { 3143 // In simple words, if an instruction is not in the assumed to _not_ 3144 // cause UB, then it is assumed UB (that includes those 3145 // in the KnownUBInsts set). The rest is boilerplate 3146 // is to ensure that it is one of the instructions we test 3147 // for UB. 3148 3149 switch (I->getOpcode()) { 3150 case Instruction::Load: 3151 case Instruction::Store: 3152 case Instruction::AtomicCmpXchg: 3153 case Instruction::AtomicRMW: 3154 return !AssumedNoUBInsts.count(I); 3155 case Instruction::Br: { 3156 auto *BrInst = cast<BranchInst>(I); 3157 if (BrInst->isUnconditional()) 3158 return false; 3159 return !AssumedNoUBInsts.count(I); 3160 } break; 3161 default: 3162 return false; 3163 } 3164 return false; 3165 } 3166 3167 ChangeStatus manifest(Attributor &A) override { 3168 if (KnownUBInsts.empty()) 3169 return ChangeStatus::UNCHANGED; 3170 for (Instruction *I : KnownUBInsts) 3171 A.changeToUnreachableAfterManifest(I); 3172 return ChangeStatus::CHANGED; 3173 } 3174 3175 /// See AbstractAttribute::getAsStr() 3176 const std::string getAsStr() const override { 3177 return getAssumed() ? "undefined-behavior" : "no-ub"; 3178 } 3179 3180 /// Note: The correctness of this analysis depends on the fact that the 3181 /// following 2 sets will stop changing after some point. 3182 /// "Change" here means that their size changes. 3183 /// The size of each set is monotonically increasing 3184 /// (we only add items to them) and it is upper bounded by the number of 3185 /// instructions in the processed function (we can never save more 3186 /// elements in either set than this number). Hence, at some point, 3187 /// they will stop increasing. 3188 /// Consequently, at some point, both sets will have stopped 3189 /// changing, effectively making the analysis reach a fixpoint. 3190 3191 /// Note: These 2 sets are disjoint and an instruction can be considered 3192 /// one of 3 things: 3193 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in 3194 /// the KnownUBInsts set. 3195 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior 3196 /// has a reason to assume it). 3197 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior 3198 /// could not find a reason to assume or prove that it can cause UB, 3199 /// hence it assumes it doesn't. We have a set for these instructions 3200 /// so that we don't reprocess them in every update. 3201 /// Note however that instructions in this set may cause UB. 3202 3203 protected: 3204 /// A set of all live instructions _known_ to cause UB. 3205 SmallPtrSet<Instruction *, 8> KnownUBInsts; 3206 3207 private: 3208 /// A set of all the (live) instructions that are assumed to _not_ cause UB. 3209 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts; 3210 3211 // Should be called on updates in which if we're processing an instruction 3212 // \p I that depends on a value \p V, one of the following has to happen: 3213 // - If the value is assumed, then stop. 3214 // - If the value is known but undef, then consider it UB. 3215 // - Otherwise, do specific processing with the simplified value. 3216 // We return std::nullopt in the first 2 cases to signify that an appropriate 3217 // action was taken and the caller should stop. 3218 // Otherwise, we return the simplified value that the caller should 3219 // use for specific processing. 3220 std::optional<Value *> stopOnUndefOrAssumed(Attributor &A, Value *V, 3221 Instruction *I) { 3222 bool UsedAssumedInformation = false; 3223 std::optional<Value *> SimplifiedV = 3224 A.getAssumedSimplified(IRPosition::value(*V), *this, 3225 UsedAssumedInformation, AA::Interprocedural); 3226 if (!UsedAssumedInformation) { 3227 // Don't depend on assumed values. 3228 if (!SimplifiedV) { 3229 // If it is known (which we tested above) but it doesn't have a value, 3230 // then we can assume `undef` and hence the instruction is UB. 3231 KnownUBInsts.insert(I); 3232 return std::nullopt; 3233 } 3234 if (!*SimplifiedV) 3235 return nullptr; 3236 V = *SimplifiedV; 3237 } 3238 if (isa<UndefValue>(V)) { 3239 KnownUBInsts.insert(I); 3240 return std::nullopt; 3241 } 3242 return V; 3243 } 3244 }; 3245 3246 struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl { 3247 AAUndefinedBehaviorFunction(const IRPosition &IRP, Attributor &A) 3248 : AAUndefinedBehaviorImpl(IRP, A) {} 3249 3250 /// See AbstractAttribute::trackStatistics() 3251 void trackStatistics() const override { 3252 STATS_DECL(UndefinedBehaviorInstruction, Instruction, 3253 "Number of instructions known to have UB"); 3254 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) += 3255 KnownUBInsts.size(); 3256 } 3257 }; 3258 } // namespace 3259 3260 /// ------------------------ Will-Return Attributes ---------------------------- 3261 3262 namespace { 3263 // Helper function that checks whether a function has any cycle which we don't 3264 // know if it is bounded or not. 3265 // Loops with maximum trip count are considered bounded, any other cycle not. 3266 static bool mayContainUnboundedCycle(Function &F, Attributor &A) { 3267 ScalarEvolution *SE = 3268 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(F); 3269 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(F); 3270 // If either SCEV or LoopInfo is not available for the function then we assume 3271 // any cycle to be unbounded cycle. 3272 // We use scc_iterator which uses Tarjan algorithm to find all the maximal 3273 // SCCs.To detect if there's a cycle, we only need to find the maximal ones. 3274 if (!SE || !LI) { 3275 for (scc_iterator<Function *> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI) 3276 if (SCCI.hasCycle()) 3277 return true; 3278 return false; 3279 } 3280 3281 // If there's irreducible control, the function may contain non-loop cycles. 3282 if (mayContainIrreducibleControl(F, LI)) 3283 return true; 3284 3285 // Any loop that does not have a max trip count is considered unbounded cycle. 3286 for (auto *L : LI->getLoopsInPreorder()) { 3287 if (!SE->getSmallConstantMaxTripCount(L)) 3288 return true; 3289 } 3290 return false; 3291 } 3292 3293 struct AAWillReturnImpl : public AAWillReturn { 3294 AAWillReturnImpl(const IRPosition &IRP, Attributor &A) 3295 : AAWillReturn(IRP, A) {} 3296 3297 /// See AbstractAttribute::initialize(...). 3298 void initialize(Attributor &A) override { 3299 AAWillReturn::initialize(A); 3300 3301 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ true)) { 3302 indicateOptimisticFixpoint(); 3303 return; 3304 } 3305 } 3306 3307 /// Check for `mustprogress` and `readonly` as they imply `willreturn`. 3308 bool isImpliedByMustprogressAndReadonly(Attributor &A, bool KnownOnly) { 3309 // Check for `mustprogress` in the scope and the associated function which 3310 // might be different if this is a call site. 3311 if ((!getAnchorScope() || !getAnchorScope()->mustProgress()) && 3312 (!getAssociatedFunction() || !getAssociatedFunction()->mustProgress())) 3313 return false; 3314 3315 bool IsKnown; 3316 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown)) 3317 return IsKnown || !KnownOnly; 3318 return false; 3319 } 3320 3321 /// See AbstractAttribute::updateImpl(...). 3322 ChangeStatus updateImpl(Attributor &A) override { 3323 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false)) 3324 return ChangeStatus::UNCHANGED; 3325 3326 auto CheckForWillReturn = [&](Instruction &I) { 3327 IRPosition IPos = IRPosition::callsite_function(cast<CallBase>(I)); 3328 const auto &WillReturnAA = 3329 A.getAAFor<AAWillReturn>(*this, IPos, DepClassTy::REQUIRED); 3330 if (WillReturnAA.isKnownWillReturn()) 3331 return true; 3332 if (!WillReturnAA.isAssumedWillReturn()) 3333 return false; 3334 const auto &NoRecurseAA = 3335 A.getAAFor<AANoRecurse>(*this, IPos, DepClassTy::REQUIRED); 3336 return NoRecurseAA.isAssumedNoRecurse(); 3337 }; 3338 3339 bool UsedAssumedInformation = false; 3340 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this, 3341 UsedAssumedInformation)) 3342 return indicatePessimisticFixpoint(); 3343 3344 return ChangeStatus::UNCHANGED; 3345 } 3346 3347 /// See AbstractAttribute::getAsStr() 3348 const std::string getAsStr() const override { 3349 return getAssumed() ? "willreturn" : "may-noreturn"; 3350 } 3351 }; 3352 3353 struct AAWillReturnFunction final : AAWillReturnImpl { 3354 AAWillReturnFunction(const IRPosition &IRP, Attributor &A) 3355 : AAWillReturnImpl(IRP, A) {} 3356 3357 /// See AbstractAttribute::initialize(...). 3358 void initialize(Attributor &A) override { 3359 AAWillReturnImpl::initialize(A); 3360 3361 Function *F = getAnchorScope(); 3362 if (!F || F->isDeclaration() || mayContainUnboundedCycle(*F, A)) 3363 indicatePessimisticFixpoint(); 3364 } 3365 3366 /// See AbstractAttribute::trackStatistics() 3367 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) } 3368 }; 3369 3370 /// WillReturn attribute deduction for a call sites. 3371 struct AAWillReturnCallSite final : AAWillReturnImpl { 3372 AAWillReturnCallSite(const IRPosition &IRP, Attributor &A) 3373 : AAWillReturnImpl(IRP, A) {} 3374 3375 /// See AbstractAttribute::initialize(...). 3376 void initialize(Attributor &A) override { 3377 AAWillReturnImpl::initialize(A); 3378 Function *F = getAssociatedFunction(); 3379 if (!F || !A.isFunctionIPOAmendable(*F)) 3380 indicatePessimisticFixpoint(); 3381 } 3382 3383 /// See AbstractAttribute::updateImpl(...). 3384 ChangeStatus updateImpl(Attributor &A) override { 3385 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false)) 3386 return ChangeStatus::UNCHANGED; 3387 3388 // TODO: Once we have call site specific value information we can provide 3389 // call site specific liveness information and then it makes 3390 // sense to specialize attributes for call sites arguments instead of 3391 // redirecting requests to the callee argument. 3392 Function *F = getAssociatedFunction(); 3393 const IRPosition &FnPos = IRPosition::function(*F); 3394 auto &FnAA = A.getAAFor<AAWillReturn>(*this, FnPos, DepClassTy::REQUIRED); 3395 return clampStateAndIndicateChange(getState(), FnAA.getState()); 3396 } 3397 3398 /// See AbstractAttribute::trackStatistics() 3399 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); } 3400 }; 3401 } // namespace 3402 3403 /// -------------------AAIntraFnReachability Attribute-------------------------- 3404 3405 /// All information associated with a reachability query. This boilerplate code 3406 /// is used by both AAIntraFnReachability and AAInterFnReachability, with 3407 /// different \p ToTy values. 3408 template <typename ToTy> struct ReachabilityQueryInfo { 3409 enum class Reachable { 3410 No, 3411 Yes, 3412 }; 3413 3414 /// Start here, 3415 const Instruction *From = nullptr; 3416 /// reach this place, 3417 const ToTy *To = nullptr; 3418 /// without going through any of these instructions, 3419 const AA::InstExclusionSetTy *ExclusionSet = nullptr; 3420 /// and remember if it worked: 3421 Reachable Result = Reachable::No; 3422 3423 ReachabilityQueryInfo(const Instruction *From, const ToTy *To) 3424 : From(From), To(To) {} 3425 3426 /// Constructor replacement to ensure unique and stable sets are used for the 3427 /// cache. 3428 ReachabilityQueryInfo(Attributor &A, const Instruction &From, const ToTy &To, 3429 const AA::InstExclusionSetTy *ES) 3430 : From(&From), To(&To), ExclusionSet(ES) { 3431 3432 if (ExclusionSet && !ExclusionSet->empty()) { 3433 ExclusionSet = 3434 A.getInfoCache().getOrCreateUniqueBlockExecutionSet(ExclusionSet); 3435 } else { 3436 ExclusionSet = nullptr; 3437 } 3438 } 3439 3440 ReachabilityQueryInfo(const ReachabilityQueryInfo &RQI) 3441 : From(RQI.From), To(RQI.To), ExclusionSet(RQI.ExclusionSet) { 3442 assert(RQI.Result == Reachable::No && 3443 "Didn't expect to copy an explored RQI!"); 3444 } 3445 }; 3446 3447 namespace llvm { 3448 template <typename ToTy> struct DenseMapInfo<ReachabilityQueryInfo<ToTy> *> { 3449 using InstSetDMI = DenseMapInfo<const AA::InstExclusionSetTy *>; 3450 using PairDMI = DenseMapInfo<std::pair<const Instruction *, const ToTy *>>; 3451 3452 static ReachabilityQueryInfo<ToTy> EmptyKey; 3453 static ReachabilityQueryInfo<ToTy> TombstoneKey; 3454 3455 static inline ReachabilityQueryInfo<ToTy> *getEmptyKey() { return &EmptyKey; } 3456 static inline ReachabilityQueryInfo<ToTy> *getTombstoneKey() { 3457 return &TombstoneKey; 3458 } 3459 static unsigned getHashValue(const ReachabilityQueryInfo<ToTy> *RQI) { 3460 unsigned H = PairDMI ::getHashValue({RQI->From, RQI->To}); 3461 H += InstSetDMI::getHashValue(RQI->ExclusionSet); 3462 return H; 3463 } 3464 static bool isEqual(const ReachabilityQueryInfo<ToTy> *LHS, 3465 const ReachabilityQueryInfo<ToTy> *RHS) { 3466 if (!PairDMI::isEqual({LHS->From, LHS->To}, {RHS->From, RHS->To})) 3467 return false; 3468 return InstSetDMI::isEqual(LHS->ExclusionSet, RHS->ExclusionSet); 3469 } 3470 }; 3471 3472 #define DefineKeys(ToTy) \ 3473 template <> \ 3474 ReachabilityQueryInfo<ToTy> \ 3475 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::EmptyKey = \ 3476 ReachabilityQueryInfo<ToTy>( \ 3477 DenseMapInfo<const Instruction *>::getEmptyKey(), \ 3478 DenseMapInfo<const ToTy *>::getEmptyKey()); \ 3479 template <> \ 3480 ReachabilityQueryInfo<ToTy> \ 3481 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::TombstoneKey = \ 3482 ReachabilityQueryInfo<ToTy>( \ 3483 DenseMapInfo<const Instruction *>::getTombstoneKey(), \ 3484 DenseMapInfo<const ToTy *>::getTombstoneKey()); 3485 3486 DefineKeys(Instruction) DefineKeys(Function) 3487 #undef DefineKeys 3488 3489 } // namespace llvm 3490 3491 namespace { 3492 3493 template <typename BaseTy, typename ToTy> 3494 struct CachedReachabilityAA : public BaseTy { 3495 using RQITy = ReachabilityQueryInfo<ToTy>; 3496 3497 CachedReachabilityAA<BaseTy, ToTy>(const IRPosition &IRP, Attributor &A) 3498 : BaseTy(IRP, A) {} 3499 3500 /// See AbstractAttribute::isQueryAA. 3501 bool isQueryAA() const override { return true; } 3502 3503 /// See AbstractAttribute::updateImpl(...). 3504 ChangeStatus updateImpl(Attributor &A) override { 3505 ChangeStatus Changed = ChangeStatus::UNCHANGED; 3506 InUpdate = true; 3507 for (RQITy *RQI : QueryVector) { 3508 if (RQI->Result == RQITy::Reachable::No && isReachableImpl(A, *RQI)) 3509 Changed = ChangeStatus::CHANGED; 3510 } 3511 InUpdate = false; 3512 return Changed; 3513 } 3514 3515 virtual bool isReachableImpl(Attributor &A, RQITy &RQI) = 0; 3516 3517 bool rememberResult(Attributor &A, typename RQITy::Reachable Result, 3518 RQITy &RQI) { 3519 if (Result == RQITy::Reachable::No) { 3520 if (!InUpdate) 3521 A.registerForUpdate(*this); 3522 return false; 3523 } 3524 assert(RQI.Result == RQITy::Reachable::No && "Already reachable?"); 3525 RQI.Result = Result; 3526 return true; 3527 } 3528 3529 const std::string getAsStr() const override { 3530 // TODO: Return the number of reachable queries. 3531 return "#queries(" + std::to_string(QueryVector.size()) + ")"; 3532 } 3533 3534 RQITy *checkQueryCache(Attributor &A, RQITy &StackRQI, 3535 typename RQITy::Reachable &Result) { 3536 if (!this->getState().isValidState()) { 3537 Result = RQITy::Reachable::Yes; 3538 return nullptr; 3539 } 3540 3541 auto It = QueryCache.find(&StackRQI); 3542 if (It != QueryCache.end()) { 3543 Result = (*It)->Result; 3544 return nullptr; 3545 } 3546 3547 RQITy *RQIPtr = new (A.Allocator) RQITy(StackRQI); 3548 QueryVector.push_back(RQIPtr); 3549 QueryCache.insert(RQIPtr); 3550 return RQIPtr; 3551 } 3552 3553 private: 3554 bool InUpdate = false; 3555 SmallVector<RQITy *> QueryVector; 3556 DenseSet<RQITy *> QueryCache; 3557 }; 3558 3559 struct AAIntraFnReachabilityFunction final 3560 : public CachedReachabilityAA<AAIntraFnReachability, Instruction> { 3561 AAIntraFnReachabilityFunction(const IRPosition &IRP, Attributor &A) 3562 : CachedReachabilityAA<AAIntraFnReachability, Instruction>(IRP, A) {} 3563 3564 bool isAssumedReachable( 3565 Attributor &A, const Instruction &From, const Instruction &To, 3566 const AA::InstExclusionSetTy *ExclusionSet) const override { 3567 auto *NonConstThis = const_cast<AAIntraFnReachabilityFunction *>(this); 3568 if (&From == &To) 3569 return true; 3570 3571 RQITy StackRQI(A, From, To, ExclusionSet); 3572 typename RQITy::Reachable Result; 3573 if (RQITy *RQIPtr = NonConstThis->checkQueryCache(A, StackRQI, Result)) { 3574 return NonConstThis->isReachableImpl(A, *RQIPtr); 3575 } 3576 return Result == RQITy::Reachable::Yes; 3577 } 3578 3579 bool isReachableImpl(Attributor &A, RQITy &RQI) override { 3580 const Instruction *Origin = RQI.From; 3581 3582 auto WillReachInBlock = [=](const Instruction &From, const Instruction &To, 3583 const AA::InstExclusionSetTy *ExclusionSet) { 3584 const Instruction *IP = &From; 3585 while (IP && IP != &To) { 3586 if (ExclusionSet && IP != Origin && ExclusionSet->count(IP)) 3587 break; 3588 IP = IP->getNextNode(); 3589 } 3590 return IP == &To; 3591 }; 3592 3593 const BasicBlock *FromBB = RQI.From->getParent(); 3594 const BasicBlock *ToBB = RQI.To->getParent(); 3595 assert(FromBB->getParent() == ToBB->getParent() && 3596 "Not an intra-procedural query!"); 3597 3598 // Check intra-block reachability, however, other reaching paths are still 3599 // possible. 3600 if (FromBB == ToBB && 3601 WillReachInBlock(*RQI.From, *RQI.To, RQI.ExclusionSet)) 3602 return rememberResult(A, RQITy::Reachable::Yes, RQI); 3603 3604 SmallPtrSet<const BasicBlock *, 16> ExclusionBlocks; 3605 if (RQI.ExclusionSet) 3606 for (auto *I : *RQI.ExclusionSet) 3607 ExclusionBlocks.insert(I->getParent()); 3608 3609 // Check if we make it out of the FromBB block at all. 3610 if (ExclusionBlocks.count(FromBB) && 3611 !WillReachInBlock(*RQI.From, *FromBB->getTerminator(), 3612 RQI.ExclusionSet)) 3613 return rememberResult(A, RQITy::Reachable::No, RQI); 3614 3615 SmallPtrSet<const BasicBlock *, 16> Visited; 3616 SmallVector<const BasicBlock *, 16> Worklist; 3617 Worklist.push_back(FromBB); 3618 3619 auto &LivenessAA = 3620 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL); 3621 while (!Worklist.empty()) { 3622 const BasicBlock *BB = Worklist.pop_back_val(); 3623 if (!Visited.insert(BB).second) 3624 continue; 3625 for (const BasicBlock *SuccBB : successors(BB)) { 3626 if (LivenessAA.isEdgeDead(BB, SuccBB)) 3627 continue; 3628 if (SuccBB == ToBB && 3629 WillReachInBlock(SuccBB->front(), *RQI.To, RQI.ExclusionSet)) 3630 return rememberResult(A, RQITy::Reachable::Yes, RQI); 3631 if (ExclusionBlocks.count(SuccBB)) 3632 continue; 3633 Worklist.push_back(SuccBB); 3634 } 3635 } 3636 3637 return rememberResult(A, RQITy::Reachable::No, RQI); 3638 } 3639 3640 /// See AbstractAttribute::trackStatistics() 3641 void trackStatistics() const override {} 3642 }; 3643 } // namespace 3644 3645 /// ------------------------ NoAlias Argument Attribute ------------------------ 3646 3647 namespace { 3648 struct AANoAliasImpl : AANoAlias { 3649 AANoAliasImpl(const IRPosition &IRP, Attributor &A) : AANoAlias(IRP, A) { 3650 assert(getAssociatedType()->isPointerTy() && 3651 "Noalias is a pointer attribute"); 3652 } 3653 3654 const std::string getAsStr() const override { 3655 return getAssumed() ? "noalias" : "may-alias"; 3656 } 3657 }; 3658 3659 /// NoAlias attribute for a floating value. 3660 struct AANoAliasFloating final : AANoAliasImpl { 3661 AANoAliasFloating(const IRPosition &IRP, Attributor &A) 3662 : AANoAliasImpl(IRP, A) {} 3663 3664 /// See AbstractAttribute::initialize(...). 3665 void initialize(Attributor &A) override { 3666 AANoAliasImpl::initialize(A); 3667 Value *Val = &getAssociatedValue(); 3668 do { 3669 CastInst *CI = dyn_cast<CastInst>(Val); 3670 if (!CI) 3671 break; 3672 Value *Base = CI->getOperand(0); 3673 if (!Base->hasOneUse()) 3674 break; 3675 Val = Base; 3676 } while (true); 3677 3678 if (!Val->getType()->isPointerTy()) { 3679 indicatePessimisticFixpoint(); 3680 return; 3681 } 3682 3683 if (isa<AllocaInst>(Val)) 3684 indicateOptimisticFixpoint(); 3685 else if (isa<ConstantPointerNull>(Val) && 3686 !NullPointerIsDefined(getAnchorScope(), 3687 Val->getType()->getPointerAddressSpace())) 3688 indicateOptimisticFixpoint(); 3689 else if (Val != &getAssociatedValue()) { 3690 const auto &ValNoAliasAA = A.getAAFor<AANoAlias>( 3691 *this, IRPosition::value(*Val), DepClassTy::OPTIONAL); 3692 if (ValNoAliasAA.isKnownNoAlias()) 3693 indicateOptimisticFixpoint(); 3694 } 3695 } 3696 3697 /// See AbstractAttribute::updateImpl(...). 3698 ChangeStatus updateImpl(Attributor &A) override { 3699 // TODO: Implement this. 3700 return indicatePessimisticFixpoint(); 3701 } 3702 3703 /// See AbstractAttribute::trackStatistics() 3704 void trackStatistics() const override { 3705 STATS_DECLTRACK_FLOATING_ATTR(noalias) 3706 } 3707 }; 3708 3709 /// NoAlias attribute for an argument. 3710 struct AANoAliasArgument final 3711 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> { 3712 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>; 3713 AANoAliasArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {} 3714 3715 /// See AbstractAttribute::initialize(...). 3716 void initialize(Attributor &A) override { 3717 Base::initialize(A); 3718 // See callsite argument attribute and callee argument attribute. 3719 if (hasAttr({Attribute::ByVal})) 3720 indicateOptimisticFixpoint(); 3721 } 3722 3723 /// See AbstractAttribute::update(...). 3724 ChangeStatus updateImpl(Attributor &A) override { 3725 // We have to make sure no-alias on the argument does not break 3726 // synchronization when this is a callback argument, see also [1] below. 3727 // If synchronization cannot be affected, we delegate to the base updateImpl 3728 // function, otherwise we give up for now. 3729 3730 // If the function is no-sync, no-alias cannot break synchronization. 3731 const auto &NoSyncAA = 3732 A.getAAFor<AANoSync>(*this, IRPosition::function_scope(getIRPosition()), 3733 DepClassTy::OPTIONAL); 3734 if (NoSyncAA.isAssumedNoSync()) 3735 return Base::updateImpl(A); 3736 3737 // If the argument is read-only, no-alias cannot break synchronization. 3738 bool IsKnown; 3739 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown)) 3740 return Base::updateImpl(A); 3741 3742 // If the argument is never passed through callbacks, no-alias cannot break 3743 // synchronization. 3744 bool UsedAssumedInformation = false; 3745 if (A.checkForAllCallSites( 3746 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this, 3747 true, UsedAssumedInformation)) 3748 return Base::updateImpl(A); 3749 3750 // TODO: add no-alias but make sure it doesn't break synchronization by 3751 // introducing fake uses. See: 3752 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel, 3753 // International Workshop on OpenMP 2018, 3754 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf 3755 3756 return indicatePessimisticFixpoint(); 3757 } 3758 3759 /// See AbstractAttribute::trackStatistics() 3760 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) } 3761 }; 3762 3763 struct AANoAliasCallSiteArgument final : AANoAliasImpl { 3764 AANoAliasCallSiteArgument(const IRPosition &IRP, Attributor &A) 3765 : AANoAliasImpl(IRP, A) {} 3766 3767 /// See AbstractAttribute::initialize(...). 3768 void initialize(Attributor &A) override { 3769 // See callsite argument attribute and callee argument attribute. 3770 const auto &CB = cast<CallBase>(getAnchorValue()); 3771 if (CB.paramHasAttr(getCallSiteArgNo(), Attribute::NoAlias)) 3772 indicateOptimisticFixpoint(); 3773 Value &Val = getAssociatedValue(); 3774 if (isa<ConstantPointerNull>(Val) && 3775 !NullPointerIsDefined(getAnchorScope(), 3776 Val.getType()->getPointerAddressSpace())) 3777 indicateOptimisticFixpoint(); 3778 } 3779 3780 /// Determine if the underlying value may alias with the call site argument 3781 /// \p OtherArgNo of \p ICS (= the underlying call site). 3782 bool mayAliasWithArgument(Attributor &A, AAResults *&AAR, 3783 const AAMemoryBehavior &MemBehaviorAA, 3784 const CallBase &CB, unsigned OtherArgNo) { 3785 // We do not need to worry about aliasing with the underlying IRP. 3786 if (this->getCalleeArgNo() == (int)OtherArgNo) 3787 return false; 3788 3789 // If it is not a pointer or pointer vector we do not alias. 3790 const Value *ArgOp = CB.getArgOperand(OtherArgNo); 3791 if (!ArgOp->getType()->isPtrOrPtrVectorTy()) 3792 return false; 3793 3794 auto &CBArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>( 3795 *this, IRPosition::callsite_argument(CB, OtherArgNo), DepClassTy::NONE); 3796 3797 // If the argument is readnone, there is no read-write aliasing. 3798 if (CBArgMemBehaviorAA.isAssumedReadNone()) { 3799 A.recordDependence(CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL); 3800 return false; 3801 } 3802 3803 // If the argument is readonly and the underlying value is readonly, there 3804 // is no read-write aliasing. 3805 bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly(); 3806 if (CBArgMemBehaviorAA.isAssumedReadOnly() && IsReadOnly) { 3807 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL); 3808 A.recordDependence(CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL); 3809 return false; 3810 } 3811 3812 // We have to utilize actual alias analysis queries so we need the object. 3813 if (!AAR) 3814 AAR = A.getInfoCache().getAAResultsForFunction(*getAnchorScope()); 3815 3816 // Try to rule it out at the call site. 3817 bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp); 3818 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between " 3819 "callsite arguments: " 3820 << getAssociatedValue() << " " << *ArgOp << " => " 3821 << (IsAliasing ? "" : "no-") << "alias \n"); 3822 3823 return IsAliasing; 3824 } 3825 3826 bool 3827 isKnownNoAliasDueToNoAliasPreservation(Attributor &A, AAResults *&AAR, 3828 const AAMemoryBehavior &MemBehaviorAA, 3829 const AANoAlias &NoAliasAA) { 3830 // We can deduce "noalias" if the following conditions hold. 3831 // (i) Associated value is assumed to be noalias in the definition. 3832 // (ii) Associated value is assumed to be no-capture in all the uses 3833 // possibly executed before this callsite. 3834 // (iii) There is no other pointer argument which could alias with the 3835 // value. 3836 3837 bool AssociatedValueIsNoAliasAtDef = NoAliasAA.isAssumedNoAlias(); 3838 if (!AssociatedValueIsNoAliasAtDef) { 3839 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue() 3840 << " is not no-alias at the definition\n"); 3841 return false; 3842 } 3843 3844 auto IsDereferenceableOrNull = [&](Value *O, const DataLayout &DL) { 3845 const auto &DerefAA = A.getAAFor<AADereferenceable>( 3846 *this, IRPosition::value(*O), DepClassTy::OPTIONAL); 3847 return DerefAA.getAssumedDereferenceableBytes(); 3848 }; 3849 3850 A.recordDependence(NoAliasAA, *this, DepClassTy::OPTIONAL); 3851 3852 const IRPosition &VIRP = IRPosition::value(getAssociatedValue()); 3853 const Function *ScopeFn = VIRP.getAnchorScope(); 3854 auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, VIRP, DepClassTy::NONE); 3855 // Check whether the value is captured in the scope using AANoCapture. 3856 // Look at CFG and check only uses possibly executed before this 3857 // callsite. 3858 auto UsePred = [&](const Use &U, bool &Follow) -> bool { 3859 Instruction *UserI = cast<Instruction>(U.getUser()); 3860 3861 // If UserI is the curr instruction and there is a single potential use of 3862 // the value in UserI we allow the use. 3863 // TODO: We should inspect the operands and allow those that cannot alias 3864 // with the value. 3865 if (UserI == getCtxI() && UserI->getNumOperands() == 1) 3866 return true; 3867 3868 if (ScopeFn) { 3869 if (auto *CB = dyn_cast<CallBase>(UserI)) { 3870 if (CB->isArgOperand(&U)) { 3871 3872 unsigned ArgNo = CB->getArgOperandNo(&U); 3873 3874 const auto &NoCaptureAA = A.getAAFor<AANoCapture>( 3875 *this, IRPosition::callsite_argument(*CB, ArgNo), 3876 DepClassTy::OPTIONAL); 3877 3878 if (NoCaptureAA.isAssumedNoCapture()) 3879 return true; 3880 } 3881 } 3882 3883 if (!AA::isPotentiallyReachable( 3884 A, *UserI, *getCtxI(), *this, /* ExclusionSet */ nullptr, 3885 [ScopeFn](const Function &Fn) { return &Fn != ScopeFn; })) 3886 return true; 3887 } 3888 3889 // TODO: We should track the capturing uses in AANoCapture but the problem 3890 // is CGSCC runs. For those we would need to "allow" AANoCapture for 3891 // a value in the module slice. 3892 switch (DetermineUseCaptureKind(U, IsDereferenceableOrNull)) { 3893 case UseCaptureKind::NO_CAPTURE: 3894 return true; 3895 case UseCaptureKind::MAY_CAPTURE: 3896 LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *UserI 3897 << "\n"); 3898 return false; 3899 case UseCaptureKind::PASSTHROUGH: 3900 Follow = true; 3901 return true; 3902 } 3903 llvm_unreachable("unknown UseCaptureKind"); 3904 }; 3905 3906 if (!NoCaptureAA.isAssumedNoCaptureMaybeReturned()) { 3907 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) { 3908 LLVM_DEBUG( 3909 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue() 3910 << " cannot be noalias as it is potentially captured\n"); 3911 return false; 3912 } 3913 } 3914 A.recordDependence(NoCaptureAA, *this, DepClassTy::OPTIONAL); 3915 3916 // Check there is no other pointer argument which could alias with the 3917 // value passed at this call site. 3918 // TODO: AbstractCallSite 3919 const auto &CB = cast<CallBase>(getAnchorValue()); 3920 for (unsigned OtherArgNo = 0; OtherArgNo < CB.arg_size(); OtherArgNo++) 3921 if (mayAliasWithArgument(A, AAR, MemBehaviorAA, CB, OtherArgNo)) 3922 return false; 3923 3924 return true; 3925 } 3926 3927 /// See AbstractAttribute::updateImpl(...). 3928 ChangeStatus updateImpl(Attributor &A) override { 3929 // If the argument is readnone we are done as there are no accesses via the 3930 // argument. 3931 auto &MemBehaviorAA = 3932 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE); 3933 if (MemBehaviorAA.isAssumedReadNone()) { 3934 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL); 3935 return ChangeStatus::UNCHANGED; 3936 } 3937 3938 const IRPosition &VIRP = IRPosition::value(getAssociatedValue()); 3939 const auto &NoAliasAA = 3940 A.getAAFor<AANoAlias>(*this, VIRP, DepClassTy::NONE); 3941 3942 AAResults *AAR = nullptr; 3943 if (isKnownNoAliasDueToNoAliasPreservation(A, AAR, MemBehaviorAA, 3944 NoAliasAA)) { 3945 LLVM_DEBUG( 3946 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n"); 3947 return ChangeStatus::UNCHANGED; 3948 } 3949 3950 return indicatePessimisticFixpoint(); 3951 } 3952 3953 /// See AbstractAttribute::trackStatistics() 3954 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) } 3955 }; 3956 3957 /// NoAlias attribute for function return value. 3958 struct AANoAliasReturned final : AANoAliasImpl { 3959 AANoAliasReturned(const IRPosition &IRP, Attributor &A) 3960 : AANoAliasImpl(IRP, A) {} 3961 3962 /// See AbstractAttribute::initialize(...). 3963 void initialize(Attributor &A) override { 3964 AANoAliasImpl::initialize(A); 3965 Function *F = getAssociatedFunction(); 3966 if (!F || F->isDeclaration()) 3967 indicatePessimisticFixpoint(); 3968 } 3969 3970 /// See AbstractAttribute::updateImpl(...). 3971 ChangeStatus updateImpl(Attributor &A) override { 3972 3973 auto CheckReturnValue = [&](Value &RV) -> bool { 3974 if (Constant *C = dyn_cast<Constant>(&RV)) 3975 if (C->isNullValue() || isa<UndefValue>(C)) 3976 return true; 3977 3978 /// For now, we can only deduce noalias if we have call sites. 3979 /// FIXME: add more support. 3980 if (!isa<CallBase>(&RV)) 3981 return false; 3982 3983 const IRPosition &RVPos = IRPosition::value(RV); 3984 const auto &NoAliasAA = 3985 A.getAAFor<AANoAlias>(*this, RVPos, DepClassTy::REQUIRED); 3986 if (!NoAliasAA.isAssumedNoAlias()) 3987 return false; 3988 3989 const auto &NoCaptureAA = 3990 A.getAAFor<AANoCapture>(*this, RVPos, DepClassTy::REQUIRED); 3991 return NoCaptureAA.isAssumedNoCaptureMaybeReturned(); 3992 }; 3993 3994 if (!A.checkForAllReturnedValues(CheckReturnValue, *this)) 3995 return indicatePessimisticFixpoint(); 3996 3997 return ChangeStatus::UNCHANGED; 3998 } 3999 4000 /// See AbstractAttribute::trackStatistics() 4001 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) } 4002 }; 4003 4004 /// NoAlias attribute deduction for a call site return value. 4005 struct AANoAliasCallSiteReturned final : AANoAliasImpl { 4006 AANoAliasCallSiteReturned(const IRPosition &IRP, Attributor &A) 4007 : AANoAliasImpl(IRP, A) {} 4008 4009 /// See AbstractAttribute::initialize(...). 4010 void initialize(Attributor &A) override { 4011 AANoAliasImpl::initialize(A); 4012 Function *F = getAssociatedFunction(); 4013 if (!F || F->isDeclaration()) 4014 indicatePessimisticFixpoint(); 4015 } 4016 4017 /// See AbstractAttribute::updateImpl(...). 4018 ChangeStatus updateImpl(Attributor &A) override { 4019 // TODO: Once we have call site specific value information we can provide 4020 // call site specific liveness information and then it makes 4021 // sense to specialize attributes for call sites arguments instead of 4022 // redirecting requests to the callee argument. 4023 Function *F = getAssociatedFunction(); 4024 const IRPosition &FnPos = IRPosition::returned(*F); 4025 auto &FnAA = A.getAAFor<AANoAlias>(*this, FnPos, DepClassTy::REQUIRED); 4026 return clampStateAndIndicateChange(getState(), FnAA.getState()); 4027 } 4028 4029 /// See AbstractAttribute::trackStatistics() 4030 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); } 4031 }; 4032 } // namespace 4033 4034 /// -------------------AAIsDead Function Attribute----------------------- 4035 4036 namespace { 4037 struct AAIsDeadValueImpl : public AAIsDead { 4038 AAIsDeadValueImpl(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {} 4039 4040 /// See AbstractAttribute::initialize(...). 4041 void initialize(Attributor &A) override { 4042 if (auto *Scope = getAnchorScope()) 4043 if (!A.isRunOn(*Scope)) 4044 indicatePessimisticFixpoint(); 4045 } 4046 4047 /// See AAIsDead::isAssumedDead(). 4048 bool isAssumedDead() const override { return isAssumed(IS_DEAD); } 4049 4050 /// See AAIsDead::isKnownDead(). 4051 bool isKnownDead() const override { return isKnown(IS_DEAD); } 4052 4053 /// See AAIsDead::isAssumedDead(BasicBlock *). 4054 bool isAssumedDead(const BasicBlock *BB) const override { return false; } 4055 4056 /// See AAIsDead::isKnownDead(BasicBlock *). 4057 bool isKnownDead(const BasicBlock *BB) const override { return false; } 4058 4059 /// See AAIsDead::isAssumedDead(Instruction *I). 4060 bool isAssumedDead(const Instruction *I) const override { 4061 return I == getCtxI() && isAssumedDead(); 4062 } 4063 4064 /// See AAIsDead::isKnownDead(Instruction *I). 4065 bool isKnownDead(const Instruction *I) const override { 4066 return isAssumedDead(I) && isKnownDead(); 4067 } 4068 4069 /// See AbstractAttribute::getAsStr(). 4070 const std::string getAsStr() const override { 4071 return isAssumedDead() ? "assumed-dead" : "assumed-live"; 4072 } 4073 4074 /// Check if all uses are assumed dead. 4075 bool areAllUsesAssumedDead(Attributor &A, Value &V) { 4076 // Callers might not check the type, void has no uses. 4077 if (V.getType()->isVoidTy() || V.use_empty()) 4078 return true; 4079 4080 // If we replace a value with a constant there are no uses left afterwards. 4081 if (!isa<Constant>(V)) { 4082 if (auto *I = dyn_cast<Instruction>(&V)) 4083 if (!A.isRunOn(*I->getFunction())) 4084 return false; 4085 bool UsedAssumedInformation = false; 4086 std::optional<Constant *> C = 4087 A.getAssumedConstant(V, *this, UsedAssumedInformation); 4088 if (!C || *C) 4089 return true; 4090 } 4091 4092 auto UsePred = [&](const Use &U, bool &Follow) { return false; }; 4093 // Explicitly set the dependence class to required because we want a long 4094 // chain of N dependent instructions to be considered live as soon as one is 4095 // without going through N update cycles. This is not required for 4096 // correctness. 4097 return A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ false, 4098 DepClassTy::REQUIRED, 4099 /* IgnoreDroppableUses */ false); 4100 } 4101 4102 /// Determine if \p I is assumed to be side-effect free. 4103 bool isAssumedSideEffectFree(Attributor &A, Instruction *I) { 4104 if (!I || wouldInstructionBeTriviallyDead(I)) 4105 return true; 4106 4107 auto *CB = dyn_cast<CallBase>(I); 4108 if (!CB || isa<IntrinsicInst>(CB)) 4109 return false; 4110 4111 const IRPosition &CallIRP = IRPosition::callsite_function(*CB); 4112 const auto &NoUnwindAA = 4113 A.getAndUpdateAAFor<AANoUnwind>(*this, CallIRP, DepClassTy::NONE); 4114 if (!NoUnwindAA.isAssumedNoUnwind()) 4115 return false; 4116 if (!NoUnwindAA.isKnownNoUnwind()) 4117 A.recordDependence(NoUnwindAA, *this, DepClassTy::OPTIONAL); 4118 4119 bool IsKnown; 4120 return AA::isAssumedReadOnly(A, CallIRP, *this, IsKnown); 4121 } 4122 }; 4123 4124 struct AAIsDeadFloating : public AAIsDeadValueImpl { 4125 AAIsDeadFloating(const IRPosition &IRP, Attributor &A) 4126 : AAIsDeadValueImpl(IRP, A) {} 4127 4128 /// See AbstractAttribute::initialize(...). 4129 void initialize(Attributor &A) override { 4130 AAIsDeadValueImpl::initialize(A); 4131 4132 if (isa<UndefValue>(getAssociatedValue())) { 4133 indicatePessimisticFixpoint(); 4134 return; 4135 } 4136 4137 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()); 4138 if (!isAssumedSideEffectFree(A, I)) { 4139 if (!isa_and_nonnull<StoreInst>(I)) 4140 indicatePessimisticFixpoint(); 4141 else 4142 removeAssumedBits(HAS_NO_EFFECT); 4143 } 4144 } 4145 4146 bool isDeadStore(Attributor &A, StoreInst &SI, 4147 SmallSetVector<Instruction *, 8> *AssumeOnlyInst = nullptr) { 4148 // Lang ref now states volatile store is not UB/dead, let's skip them. 4149 if (SI.isVolatile()) 4150 return false; 4151 4152 // If we are collecting assumes to be deleted we are in the manifest stage. 4153 // It's problematic to collect the potential copies again now so we use the 4154 // cached ones. 4155 bool UsedAssumedInformation = false; 4156 if (!AssumeOnlyInst) { 4157 PotentialCopies.clear(); 4158 if (!AA::getPotentialCopiesOfStoredValue(A, SI, PotentialCopies, *this, 4159 UsedAssumedInformation)) { 4160 LLVM_DEBUG( 4161 dbgs() 4162 << "[AAIsDead] Could not determine potential copies of store!\n"); 4163 return false; 4164 } 4165 } 4166 LLVM_DEBUG(dbgs() << "[AAIsDead] Store has " << PotentialCopies.size() 4167 << " potential copies.\n"); 4168 4169 InformationCache &InfoCache = A.getInfoCache(); 4170 return llvm::all_of(PotentialCopies, [&](Value *V) { 4171 if (A.isAssumedDead(IRPosition::value(*V), this, nullptr, 4172 UsedAssumedInformation)) 4173 return true; 4174 if (auto *LI = dyn_cast<LoadInst>(V)) { 4175 if (llvm::all_of(LI->uses(), [&](const Use &U) { 4176 auto &UserI = cast<Instruction>(*U.getUser()); 4177 if (InfoCache.isOnlyUsedByAssume(UserI)) { 4178 if (AssumeOnlyInst) 4179 AssumeOnlyInst->insert(&UserI); 4180 return true; 4181 } 4182 return A.isAssumedDead(U, this, nullptr, UsedAssumedInformation); 4183 })) { 4184 return true; 4185 } 4186 } 4187 LLVM_DEBUG(dbgs() << "[AAIsDead] Potential copy " << *V 4188 << " is assumed live!\n"); 4189 return false; 4190 }); 4191 } 4192 4193 /// See AbstractAttribute::getAsStr(). 4194 const std::string getAsStr() const override { 4195 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()); 4196 if (isa_and_nonnull<StoreInst>(I)) 4197 if (isValidState()) 4198 return "assumed-dead-store"; 4199 return AAIsDeadValueImpl::getAsStr(); 4200 } 4201 4202 /// See AbstractAttribute::updateImpl(...). 4203 ChangeStatus updateImpl(Attributor &A) override { 4204 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()); 4205 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) { 4206 if (!isDeadStore(A, *SI)) 4207 return indicatePessimisticFixpoint(); 4208 } else { 4209 if (!isAssumedSideEffectFree(A, I)) 4210 return indicatePessimisticFixpoint(); 4211 if (!areAllUsesAssumedDead(A, getAssociatedValue())) 4212 return indicatePessimisticFixpoint(); 4213 } 4214 return ChangeStatus::UNCHANGED; 4215 } 4216 4217 bool isRemovableStore() const override { 4218 return isAssumed(IS_REMOVABLE) && isa<StoreInst>(&getAssociatedValue()); 4219 } 4220 4221 /// See AbstractAttribute::manifest(...). 4222 ChangeStatus manifest(Attributor &A) override { 4223 Value &V = getAssociatedValue(); 4224 if (auto *I = dyn_cast<Instruction>(&V)) { 4225 // If we get here we basically know the users are all dead. We check if 4226 // isAssumedSideEffectFree returns true here again because it might not be 4227 // the case and only the users are dead but the instruction (=call) is 4228 // still needed. 4229 if (auto *SI = dyn_cast<StoreInst>(I)) { 4230 SmallSetVector<Instruction *, 8> AssumeOnlyInst; 4231 bool IsDead = isDeadStore(A, *SI, &AssumeOnlyInst); 4232 (void)IsDead; 4233 assert(IsDead && "Store was assumed to be dead!"); 4234 A.deleteAfterManifest(*I); 4235 for (size_t i = 0; i < AssumeOnlyInst.size(); ++i) { 4236 Instruction *AOI = AssumeOnlyInst[i]; 4237 for (auto *Usr : AOI->users()) 4238 AssumeOnlyInst.insert(cast<Instruction>(Usr)); 4239 A.deleteAfterManifest(*AOI); 4240 } 4241 return ChangeStatus::CHANGED; 4242 } 4243 if (isAssumedSideEffectFree(A, I) && !isa<InvokeInst>(I)) { 4244 A.deleteAfterManifest(*I); 4245 return ChangeStatus::CHANGED; 4246 } 4247 } 4248 return ChangeStatus::UNCHANGED; 4249 } 4250 4251 /// See AbstractAttribute::trackStatistics() 4252 void trackStatistics() const override { 4253 STATS_DECLTRACK_FLOATING_ATTR(IsDead) 4254 } 4255 4256 private: 4257 // The potential copies of a dead store, used for deletion during manifest. 4258 SmallSetVector<Value *, 4> PotentialCopies; 4259 }; 4260 4261 struct AAIsDeadArgument : public AAIsDeadFloating { 4262 AAIsDeadArgument(const IRPosition &IRP, Attributor &A) 4263 : AAIsDeadFloating(IRP, A) {} 4264 4265 /// See AbstractAttribute::initialize(...). 4266 void initialize(Attributor &A) override { 4267 AAIsDeadFloating::initialize(A); 4268 if (!A.isFunctionIPOAmendable(*getAnchorScope())) 4269 indicatePessimisticFixpoint(); 4270 } 4271 4272 /// See AbstractAttribute::manifest(...). 4273 ChangeStatus manifest(Attributor &A) override { 4274 Argument &Arg = *getAssociatedArgument(); 4275 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {})) 4276 if (A.registerFunctionSignatureRewrite( 4277 Arg, /* ReplacementTypes */ {}, 4278 Attributor::ArgumentReplacementInfo::CalleeRepairCBTy{}, 4279 Attributor::ArgumentReplacementInfo::ACSRepairCBTy{})) { 4280 return ChangeStatus::CHANGED; 4281 } 4282 return ChangeStatus::UNCHANGED; 4283 } 4284 4285 /// See AbstractAttribute::trackStatistics() 4286 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) } 4287 }; 4288 4289 struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl { 4290 AAIsDeadCallSiteArgument(const IRPosition &IRP, Attributor &A) 4291 : AAIsDeadValueImpl(IRP, A) {} 4292 4293 /// See AbstractAttribute::initialize(...). 4294 void initialize(Attributor &A) override { 4295 AAIsDeadValueImpl::initialize(A); 4296 if (isa<UndefValue>(getAssociatedValue())) 4297 indicatePessimisticFixpoint(); 4298 } 4299 4300 /// See AbstractAttribute::updateImpl(...). 4301 ChangeStatus updateImpl(Attributor &A) override { 4302 // TODO: Once we have call site specific value information we can provide 4303 // call site specific liveness information and then it makes 4304 // sense to specialize attributes for call sites arguments instead of 4305 // redirecting requests to the callee argument. 4306 Argument *Arg = getAssociatedArgument(); 4307 if (!Arg) 4308 return indicatePessimisticFixpoint(); 4309 const IRPosition &ArgPos = IRPosition::argument(*Arg); 4310 auto &ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos, DepClassTy::REQUIRED); 4311 return clampStateAndIndicateChange(getState(), ArgAA.getState()); 4312 } 4313 4314 /// See AbstractAttribute::manifest(...). 4315 ChangeStatus manifest(Attributor &A) override { 4316 CallBase &CB = cast<CallBase>(getAnchorValue()); 4317 Use &U = CB.getArgOperandUse(getCallSiteArgNo()); 4318 assert(!isa<UndefValue>(U.get()) && 4319 "Expected undef values to be filtered out!"); 4320 UndefValue &UV = *UndefValue::get(U->getType()); 4321 if (A.changeUseAfterManifest(U, UV)) 4322 return ChangeStatus::CHANGED; 4323 return ChangeStatus::UNCHANGED; 4324 } 4325 4326 /// See AbstractAttribute::trackStatistics() 4327 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) } 4328 }; 4329 4330 struct AAIsDeadCallSiteReturned : public AAIsDeadFloating { 4331 AAIsDeadCallSiteReturned(const IRPosition &IRP, Attributor &A) 4332 : AAIsDeadFloating(IRP, A) {} 4333 4334 /// See AAIsDead::isAssumedDead(). 4335 bool isAssumedDead() const override { 4336 return AAIsDeadFloating::isAssumedDead() && IsAssumedSideEffectFree; 4337 } 4338 4339 /// See AbstractAttribute::initialize(...). 4340 void initialize(Attributor &A) override { 4341 AAIsDeadFloating::initialize(A); 4342 if (isa<UndefValue>(getAssociatedValue())) { 4343 indicatePessimisticFixpoint(); 4344 return; 4345 } 4346 4347 // We track this separately as a secondary state. 4348 IsAssumedSideEffectFree = isAssumedSideEffectFree(A, getCtxI()); 4349 } 4350 4351 /// See AbstractAttribute::updateImpl(...). 4352 ChangeStatus updateImpl(Attributor &A) override { 4353 ChangeStatus Changed = ChangeStatus::UNCHANGED; 4354 if (IsAssumedSideEffectFree && !isAssumedSideEffectFree(A, getCtxI())) { 4355 IsAssumedSideEffectFree = false; 4356 Changed = ChangeStatus::CHANGED; 4357 } 4358 if (!areAllUsesAssumedDead(A, getAssociatedValue())) 4359 return indicatePessimisticFixpoint(); 4360 return Changed; 4361 } 4362 4363 /// See AbstractAttribute::trackStatistics() 4364 void trackStatistics() const override { 4365 if (IsAssumedSideEffectFree) 4366 STATS_DECLTRACK_CSRET_ATTR(IsDead) 4367 else 4368 STATS_DECLTRACK_CSRET_ATTR(UnusedResult) 4369 } 4370 4371 /// See AbstractAttribute::getAsStr(). 4372 const std::string getAsStr() const override { 4373 return isAssumedDead() 4374 ? "assumed-dead" 4375 : (getAssumed() ? "assumed-dead-users" : "assumed-live"); 4376 } 4377 4378 private: 4379 bool IsAssumedSideEffectFree = true; 4380 }; 4381 4382 struct AAIsDeadReturned : public AAIsDeadValueImpl { 4383 AAIsDeadReturned(const IRPosition &IRP, Attributor &A) 4384 : AAIsDeadValueImpl(IRP, A) {} 4385 4386 /// See AbstractAttribute::updateImpl(...). 4387 ChangeStatus updateImpl(Attributor &A) override { 4388 4389 bool UsedAssumedInformation = false; 4390 A.checkForAllInstructions([](Instruction &) { return true; }, *this, 4391 {Instruction::Ret}, UsedAssumedInformation); 4392 4393 auto PredForCallSite = [&](AbstractCallSite ACS) { 4394 if (ACS.isCallbackCall() || !ACS.getInstruction()) 4395 return false; 4396 return areAllUsesAssumedDead(A, *ACS.getInstruction()); 4397 }; 4398 4399 if (!A.checkForAllCallSites(PredForCallSite, *this, true, 4400 UsedAssumedInformation)) 4401 return indicatePessimisticFixpoint(); 4402 4403 return ChangeStatus::UNCHANGED; 4404 } 4405 4406 /// See AbstractAttribute::manifest(...). 4407 ChangeStatus manifest(Attributor &A) override { 4408 // TODO: Rewrite the signature to return void? 4409 bool AnyChange = false; 4410 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType()); 4411 auto RetInstPred = [&](Instruction &I) { 4412 ReturnInst &RI = cast<ReturnInst>(I); 4413 if (!isa<UndefValue>(RI.getReturnValue())) 4414 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV); 4415 return true; 4416 }; 4417 bool UsedAssumedInformation = false; 4418 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret}, 4419 UsedAssumedInformation); 4420 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 4421 } 4422 4423 /// See AbstractAttribute::trackStatistics() 4424 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) } 4425 }; 4426 4427 struct AAIsDeadFunction : public AAIsDead { 4428 AAIsDeadFunction(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {} 4429 4430 /// See AbstractAttribute::initialize(...). 4431 void initialize(Attributor &A) override { 4432 Function *F = getAnchorScope(); 4433 if (!F || F->isDeclaration() || !A.isRunOn(*F)) { 4434 indicatePessimisticFixpoint(); 4435 return; 4436 } 4437 if (!isAssumedDeadInternalFunction(A)) { 4438 ToBeExploredFrom.insert(&F->getEntryBlock().front()); 4439 assumeLive(A, F->getEntryBlock()); 4440 } 4441 } 4442 4443 bool isAssumedDeadInternalFunction(Attributor &A) { 4444 if (!getAnchorScope()->hasLocalLinkage()) 4445 return false; 4446 bool UsedAssumedInformation = false; 4447 return A.checkForAllCallSites([](AbstractCallSite) { return false; }, *this, 4448 true, UsedAssumedInformation); 4449 } 4450 4451 /// See AbstractAttribute::getAsStr(). 4452 const std::string getAsStr() const override { 4453 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" + 4454 std::to_string(getAnchorScope()->size()) + "][#TBEP " + 4455 std::to_string(ToBeExploredFrom.size()) + "][#KDE " + 4456 std::to_string(KnownDeadEnds.size()) + "]"; 4457 } 4458 4459 /// See AbstractAttribute::manifest(...). 4460 ChangeStatus manifest(Attributor &A) override { 4461 assert(getState().isValidState() && 4462 "Attempted to manifest an invalid state!"); 4463 4464 ChangeStatus HasChanged = ChangeStatus::UNCHANGED; 4465 Function &F = *getAnchorScope(); 4466 4467 if (AssumedLiveBlocks.empty()) { 4468 A.deleteAfterManifest(F); 4469 return ChangeStatus::CHANGED; 4470 } 4471 4472 // Flag to determine if we can change an invoke to a call assuming the 4473 // callee is nounwind. This is not possible if the personality of the 4474 // function allows to catch asynchronous exceptions. 4475 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F); 4476 4477 KnownDeadEnds.set_union(ToBeExploredFrom); 4478 for (const Instruction *DeadEndI : KnownDeadEnds) { 4479 auto *CB = dyn_cast<CallBase>(DeadEndI); 4480 if (!CB) 4481 continue; 4482 const auto &NoReturnAA = A.getAndUpdateAAFor<AANoReturn>( 4483 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL); 4484 bool MayReturn = !NoReturnAA.isAssumedNoReturn(); 4485 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB))) 4486 continue; 4487 4488 if (auto *II = dyn_cast<InvokeInst>(DeadEndI)) 4489 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II)); 4490 else 4491 A.changeToUnreachableAfterManifest( 4492 const_cast<Instruction *>(DeadEndI->getNextNode())); 4493 HasChanged = ChangeStatus::CHANGED; 4494 } 4495 4496 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted."); 4497 for (BasicBlock &BB : F) 4498 if (!AssumedLiveBlocks.count(&BB)) { 4499 A.deleteAfterManifest(BB); 4500 ++BUILD_STAT_NAME(AAIsDead, BasicBlock); 4501 HasChanged = ChangeStatus::CHANGED; 4502 } 4503 4504 return HasChanged; 4505 } 4506 4507 /// See AbstractAttribute::updateImpl(...). 4508 ChangeStatus updateImpl(Attributor &A) override; 4509 4510 bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const override { 4511 assert(From->getParent() == getAnchorScope() && 4512 To->getParent() == getAnchorScope() && 4513 "Used AAIsDead of the wrong function"); 4514 return isValidState() && !AssumedLiveEdges.count(std::make_pair(From, To)); 4515 } 4516 4517 /// See AbstractAttribute::trackStatistics() 4518 void trackStatistics() const override {} 4519 4520 /// Returns true if the function is assumed dead. 4521 bool isAssumedDead() const override { return false; } 4522 4523 /// See AAIsDead::isKnownDead(). 4524 bool isKnownDead() const override { return false; } 4525 4526 /// See AAIsDead::isAssumedDead(BasicBlock *). 4527 bool isAssumedDead(const BasicBlock *BB) const override { 4528 assert(BB->getParent() == getAnchorScope() && 4529 "BB must be in the same anchor scope function."); 4530 4531 if (!getAssumed()) 4532 return false; 4533 return !AssumedLiveBlocks.count(BB); 4534 } 4535 4536 /// See AAIsDead::isKnownDead(BasicBlock *). 4537 bool isKnownDead(const BasicBlock *BB) const override { 4538 return getKnown() && isAssumedDead(BB); 4539 } 4540 4541 /// See AAIsDead::isAssumed(Instruction *I). 4542 bool isAssumedDead(const Instruction *I) const override { 4543 assert(I->getParent()->getParent() == getAnchorScope() && 4544 "Instruction must be in the same anchor scope function."); 4545 4546 if (!getAssumed()) 4547 return false; 4548 4549 // If it is not in AssumedLiveBlocks then it for sure dead. 4550 // Otherwise, it can still be after noreturn call in a live block. 4551 if (!AssumedLiveBlocks.count(I->getParent())) 4552 return true; 4553 4554 // If it is not after a liveness barrier it is live. 4555 const Instruction *PrevI = I->getPrevNode(); 4556 while (PrevI) { 4557 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI)) 4558 return true; 4559 PrevI = PrevI->getPrevNode(); 4560 } 4561 return false; 4562 } 4563 4564 /// See AAIsDead::isKnownDead(Instruction *I). 4565 bool isKnownDead(const Instruction *I) const override { 4566 return getKnown() && isAssumedDead(I); 4567 } 4568 4569 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A 4570 /// that internal function called from \p BB should now be looked at. 4571 bool assumeLive(Attributor &A, const BasicBlock &BB) { 4572 if (!AssumedLiveBlocks.insert(&BB).second) 4573 return false; 4574 4575 // We assume that all of BB is (probably) live now and if there are calls to 4576 // internal functions we will assume that those are now live as well. This 4577 // is a performance optimization for blocks with calls to a lot of internal 4578 // functions. It can however cause dead functions to be treated as live. 4579 for (const Instruction &I : BB) 4580 if (const auto *CB = dyn_cast<CallBase>(&I)) 4581 if (const Function *F = CB->getCalledFunction()) 4582 if (F->hasLocalLinkage()) 4583 A.markLiveInternalFunction(*F); 4584 return true; 4585 } 4586 4587 /// Collection of instructions that need to be explored again, e.g., we 4588 /// did assume they do not transfer control to (one of their) successors. 4589 SmallSetVector<const Instruction *, 8> ToBeExploredFrom; 4590 4591 /// Collection of instructions that are known to not transfer control. 4592 SmallSetVector<const Instruction *, 8> KnownDeadEnds; 4593 4594 /// Collection of all assumed live edges 4595 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> AssumedLiveEdges; 4596 4597 /// Collection of all assumed live BasicBlocks. 4598 DenseSet<const BasicBlock *> AssumedLiveBlocks; 4599 }; 4600 4601 static bool 4602 identifyAliveSuccessors(Attributor &A, const CallBase &CB, 4603 AbstractAttribute &AA, 4604 SmallVectorImpl<const Instruction *> &AliveSuccessors) { 4605 const IRPosition &IPos = IRPosition::callsite_function(CB); 4606 4607 const auto &NoReturnAA = 4608 A.getAndUpdateAAFor<AANoReturn>(AA, IPos, DepClassTy::OPTIONAL); 4609 if (NoReturnAA.isAssumedNoReturn()) 4610 return !NoReturnAA.isKnownNoReturn(); 4611 if (CB.isTerminator()) 4612 AliveSuccessors.push_back(&CB.getSuccessor(0)->front()); 4613 else 4614 AliveSuccessors.push_back(CB.getNextNode()); 4615 return false; 4616 } 4617 4618 static bool 4619 identifyAliveSuccessors(Attributor &A, const InvokeInst &II, 4620 AbstractAttribute &AA, 4621 SmallVectorImpl<const Instruction *> &AliveSuccessors) { 4622 bool UsedAssumedInformation = 4623 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors); 4624 4625 // First, determine if we can change an invoke to a call assuming the 4626 // callee is nounwind. This is not possible if the personality of the 4627 // function allows to catch asynchronous exceptions. 4628 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) { 4629 AliveSuccessors.push_back(&II.getUnwindDest()->front()); 4630 } else { 4631 const IRPosition &IPos = IRPosition::callsite_function(II); 4632 const auto &AANoUnw = 4633 A.getAndUpdateAAFor<AANoUnwind>(AA, IPos, DepClassTy::OPTIONAL); 4634 if (AANoUnw.isAssumedNoUnwind()) { 4635 UsedAssumedInformation |= !AANoUnw.isKnownNoUnwind(); 4636 } else { 4637 AliveSuccessors.push_back(&II.getUnwindDest()->front()); 4638 } 4639 } 4640 return UsedAssumedInformation; 4641 } 4642 4643 static bool 4644 identifyAliveSuccessors(Attributor &A, const BranchInst &BI, 4645 AbstractAttribute &AA, 4646 SmallVectorImpl<const Instruction *> &AliveSuccessors) { 4647 bool UsedAssumedInformation = false; 4648 if (BI.getNumSuccessors() == 1) { 4649 AliveSuccessors.push_back(&BI.getSuccessor(0)->front()); 4650 } else { 4651 std::optional<Constant *> C = 4652 A.getAssumedConstant(*BI.getCondition(), AA, UsedAssumedInformation); 4653 if (!C || isa_and_nonnull<UndefValue>(*C)) { 4654 // No value yet, assume both edges are dead. 4655 } else if (isa_and_nonnull<ConstantInt>(*C)) { 4656 const BasicBlock *SuccBB = 4657 BI.getSuccessor(1 - cast<ConstantInt>(*C)->getValue().getZExtValue()); 4658 AliveSuccessors.push_back(&SuccBB->front()); 4659 } else { 4660 AliveSuccessors.push_back(&BI.getSuccessor(0)->front()); 4661 AliveSuccessors.push_back(&BI.getSuccessor(1)->front()); 4662 UsedAssumedInformation = false; 4663 } 4664 } 4665 return UsedAssumedInformation; 4666 } 4667 4668 static bool 4669 identifyAliveSuccessors(Attributor &A, const SwitchInst &SI, 4670 AbstractAttribute &AA, 4671 SmallVectorImpl<const Instruction *> &AliveSuccessors) { 4672 bool UsedAssumedInformation = false; 4673 std::optional<Constant *> C = 4674 A.getAssumedConstant(*SI.getCondition(), AA, UsedAssumedInformation); 4675 if (!C || isa_and_nonnull<UndefValue>(*C)) { 4676 // No value yet, assume all edges are dead. 4677 } else if (isa_and_nonnull<ConstantInt>(*C)) { 4678 for (const auto &CaseIt : SI.cases()) { 4679 if (CaseIt.getCaseValue() == *C) { 4680 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front()); 4681 return UsedAssumedInformation; 4682 } 4683 } 4684 AliveSuccessors.push_back(&SI.getDefaultDest()->front()); 4685 return UsedAssumedInformation; 4686 } else { 4687 for (const BasicBlock *SuccBB : successors(SI.getParent())) 4688 AliveSuccessors.push_back(&SuccBB->front()); 4689 } 4690 return UsedAssumedInformation; 4691 } 4692 4693 ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) { 4694 ChangeStatus Change = ChangeStatus::UNCHANGED; 4695 4696 if (AssumedLiveBlocks.empty()) { 4697 if (isAssumedDeadInternalFunction(A)) 4698 return ChangeStatus::UNCHANGED; 4699 4700 Function *F = getAnchorScope(); 4701 ToBeExploredFrom.insert(&F->getEntryBlock().front()); 4702 assumeLive(A, F->getEntryBlock()); 4703 Change = ChangeStatus::CHANGED; 4704 } 4705 4706 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/" 4707 << getAnchorScope()->size() << "] BBs and " 4708 << ToBeExploredFrom.size() << " exploration points and " 4709 << KnownDeadEnds.size() << " known dead ends\n"); 4710 4711 // Copy and clear the list of instructions we need to explore from. It is 4712 // refilled with instructions the next update has to look at. 4713 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(), 4714 ToBeExploredFrom.end()); 4715 decltype(ToBeExploredFrom) NewToBeExploredFrom; 4716 4717 SmallVector<const Instruction *, 8> AliveSuccessors; 4718 while (!Worklist.empty()) { 4719 const Instruction *I = Worklist.pop_back_val(); 4720 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n"); 4721 4722 // Fast forward for uninteresting instructions. We could look for UB here 4723 // though. 4724 while (!I->isTerminator() && !isa<CallBase>(I)) 4725 I = I->getNextNode(); 4726 4727 AliveSuccessors.clear(); 4728 4729 bool UsedAssumedInformation = false; 4730 switch (I->getOpcode()) { 4731 // TODO: look for (assumed) UB to backwards propagate "deadness". 4732 default: 4733 assert(I->isTerminator() && 4734 "Expected non-terminators to be handled already!"); 4735 for (const BasicBlock *SuccBB : successors(I->getParent())) 4736 AliveSuccessors.push_back(&SuccBB->front()); 4737 break; 4738 case Instruction::Call: 4739 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I), 4740 *this, AliveSuccessors); 4741 break; 4742 case Instruction::Invoke: 4743 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I), 4744 *this, AliveSuccessors); 4745 break; 4746 case Instruction::Br: 4747 UsedAssumedInformation = identifyAliveSuccessors(A, cast<BranchInst>(*I), 4748 *this, AliveSuccessors); 4749 break; 4750 case Instruction::Switch: 4751 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I), 4752 *this, AliveSuccessors); 4753 break; 4754 } 4755 4756 if (UsedAssumedInformation) { 4757 NewToBeExploredFrom.insert(I); 4758 } else if (AliveSuccessors.empty() || 4759 (I->isTerminator() && 4760 AliveSuccessors.size() < I->getNumSuccessors())) { 4761 if (KnownDeadEnds.insert(I)) 4762 Change = ChangeStatus::CHANGED; 4763 } 4764 4765 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: " 4766 << AliveSuccessors.size() << " UsedAssumedInformation: " 4767 << UsedAssumedInformation << "\n"); 4768 4769 for (const Instruction *AliveSuccessor : AliveSuccessors) { 4770 if (!I->isTerminator()) { 4771 assert(AliveSuccessors.size() == 1 && 4772 "Non-terminator expected to have a single successor!"); 4773 Worklist.push_back(AliveSuccessor); 4774 } else { 4775 // record the assumed live edge 4776 auto Edge = std::make_pair(I->getParent(), AliveSuccessor->getParent()); 4777 if (AssumedLiveEdges.insert(Edge).second) 4778 Change = ChangeStatus::CHANGED; 4779 if (assumeLive(A, *AliveSuccessor->getParent())) 4780 Worklist.push_back(AliveSuccessor); 4781 } 4782 } 4783 } 4784 4785 // Check if the content of ToBeExploredFrom changed, ignore the order. 4786 if (NewToBeExploredFrom.size() != ToBeExploredFrom.size() || 4787 llvm::any_of(NewToBeExploredFrom, [&](const Instruction *I) { 4788 return !ToBeExploredFrom.count(I); 4789 })) { 4790 Change = ChangeStatus::CHANGED; 4791 ToBeExploredFrom = std::move(NewToBeExploredFrom); 4792 } 4793 4794 // If we know everything is live there is no need to query for liveness. 4795 // Instead, indicating a pessimistic fixpoint will cause the state to be 4796 // "invalid" and all queries to be answered conservatively without lookups. 4797 // To be in this state we have to (1) finished the exploration and (3) not 4798 // discovered any non-trivial dead end and (2) not ruled unreachable code 4799 // dead. 4800 if (ToBeExploredFrom.empty() && 4801 getAnchorScope()->size() == AssumedLiveBlocks.size() && 4802 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) { 4803 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0; 4804 })) 4805 return indicatePessimisticFixpoint(); 4806 return Change; 4807 } 4808 4809 /// Liveness information for a call sites. 4810 struct AAIsDeadCallSite final : AAIsDeadFunction { 4811 AAIsDeadCallSite(const IRPosition &IRP, Attributor &A) 4812 : AAIsDeadFunction(IRP, A) {} 4813 4814 /// See AbstractAttribute::initialize(...). 4815 void initialize(Attributor &A) override { 4816 // TODO: Once we have call site specific value information we can provide 4817 // call site specific liveness information and then it makes 4818 // sense to specialize attributes for call sites instead of 4819 // redirecting requests to the callee. 4820 llvm_unreachable("Abstract attributes for liveness are not " 4821 "supported for call sites yet!"); 4822 } 4823 4824 /// See AbstractAttribute::updateImpl(...). 4825 ChangeStatus updateImpl(Attributor &A) override { 4826 return indicatePessimisticFixpoint(); 4827 } 4828 4829 /// See AbstractAttribute::trackStatistics() 4830 void trackStatistics() const override {} 4831 }; 4832 } // namespace 4833 4834 /// -------------------- Dereferenceable Argument Attribute -------------------- 4835 4836 namespace { 4837 struct AADereferenceableImpl : AADereferenceable { 4838 AADereferenceableImpl(const IRPosition &IRP, Attributor &A) 4839 : AADereferenceable(IRP, A) {} 4840 using StateType = DerefState; 4841 4842 /// See AbstractAttribute::initialize(...). 4843 void initialize(Attributor &A) override { 4844 Value &V = *getAssociatedValue().stripPointerCasts(); 4845 SmallVector<Attribute, 4> Attrs; 4846 getAttrs({Attribute::Dereferenceable, Attribute::DereferenceableOrNull}, 4847 Attrs, /* IgnoreSubsumingPositions */ false, &A); 4848 for (const Attribute &Attr : Attrs) 4849 takeKnownDerefBytesMaximum(Attr.getValueAsInt()); 4850 4851 const IRPosition &IRP = this->getIRPosition(); 4852 NonNullAA = &A.getAAFor<AANonNull>(*this, IRP, DepClassTy::NONE); 4853 4854 bool CanBeNull, CanBeFreed; 4855 takeKnownDerefBytesMaximum(V.getPointerDereferenceableBytes( 4856 A.getDataLayout(), CanBeNull, CanBeFreed)); 4857 4858 bool IsFnInterface = IRP.isFnInterfaceKind(); 4859 Function *FnScope = IRP.getAnchorScope(); 4860 if (IsFnInterface && (!FnScope || !A.isFunctionIPOAmendable(*FnScope))) { 4861 indicatePessimisticFixpoint(); 4862 return; 4863 } 4864 4865 if (Instruction *CtxI = getCtxI()) 4866 followUsesInMBEC(*this, A, getState(), *CtxI); 4867 } 4868 4869 /// See AbstractAttribute::getState() 4870 /// { 4871 StateType &getState() override { return *this; } 4872 const StateType &getState() const override { return *this; } 4873 /// } 4874 4875 /// Helper function for collecting accessed bytes in must-be-executed-context 4876 void addAccessedBytesForUse(Attributor &A, const Use *U, const Instruction *I, 4877 DerefState &State) { 4878 const Value *UseV = U->get(); 4879 if (!UseV->getType()->isPointerTy()) 4880 return; 4881 4882 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I); 4883 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile()) 4884 return; 4885 4886 int64_t Offset; 4887 const Value *Base = GetPointerBaseWithConstantOffset( 4888 Loc->Ptr, Offset, A.getDataLayout(), /*AllowNonInbounds*/ true); 4889 if (Base && Base == &getAssociatedValue()) 4890 State.addAccessedBytes(Offset, Loc->Size.getValue()); 4891 } 4892 4893 /// See followUsesInMBEC 4894 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I, 4895 AADereferenceable::StateType &State) { 4896 bool IsNonNull = false; 4897 bool TrackUse = false; 4898 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse( 4899 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse); 4900 LLVM_DEBUG(dbgs() << "[AADereferenceable] Deref bytes: " << DerefBytes 4901 << " for instruction " << *I << "\n"); 4902 4903 addAccessedBytesForUse(A, U, I, State); 4904 State.takeKnownDerefBytesMaximum(DerefBytes); 4905 return TrackUse; 4906 } 4907 4908 /// See AbstractAttribute::manifest(...). 4909 ChangeStatus manifest(Attributor &A) override { 4910 ChangeStatus Change = AADereferenceable::manifest(A); 4911 if (isAssumedNonNull() && hasAttr(Attribute::DereferenceableOrNull)) { 4912 removeAttrs({Attribute::DereferenceableOrNull}); 4913 return ChangeStatus::CHANGED; 4914 } 4915 return Change; 4916 } 4917 4918 void getDeducedAttributes(LLVMContext &Ctx, 4919 SmallVectorImpl<Attribute> &Attrs) const override { 4920 // TODO: Add *_globally support 4921 if (isAssumedNonNull()) 4922 Attrs.emplace_back(Attribute::getWithDereferenceableBytes( 4923 Ctx, getAssumedDereferenceableBytes())); 4924 else 4925 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes( 4926 Ctx, getAssumedDereferenceableBytes())); 4927 } 4928 4929 /// See AbstractAttribute::getAsStr(). 4930 const std::string getAsStr() const override { 4931 if (!getAssumedDereferenceableBytes()) 4932 return "unknown-dereferenceable"; 4933 return std::string("dereferenceable") + 4934 (isAssumedNonNull() ? "" : "_or_null") + 4935 (isAssumedGlobal() ? "_globally" : "") + "<" + 4936 std::to_string(getKnownDereferenceableBytes()) + "-" + 4937 std::to_string(getAssumedDereferenceableBytes()) + ">"; 4938 } 4939 }; 4940 4941 /// Dereferenceable attribute for a floating value. 4942 struct AADereferenceableFloating : AADereferenceableImpl { 4943 AADereferenceableFloating(const IRPosition &IRP, Attributor &A) 4944 : AADereferenceableImpl(IRP, A) {} 4945 4946 /// See AbstractAttribute::updateImpl(...). 4947 ChangeStatus updateImpl(Attributor &A) override { 4948 4949 bool Stripped; 4950 bool UsedAssumedInformation = false; 4951 SmallVector<AA::ValueAndContext> Values; 4952 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values, 4953 AA::AnyScope, UsedAssumedInformation)) { 4954 Values.push_back({getAssociatedValue(), getCtxI()}); 4955 Stripped = false; 4956 } else { 4957 Stripped = Values.size() != 1 || 4958 Values.front().getValue() != &getAssociatedValue(); 4959 } 4960 4961 const DataLayout &DL = A.getDataLayout(); 4962 DerefState T; 4963 4964 auto VisitValueCB = [&](const Value &V) -> bool { 4965 unsigned IdxWidth = 4966 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace()); 4967 APInt Offset(IdxWidth, 0); 4968 const Value *Base = stripAndAccumulateOffsets( 4969 A, *this, &V, DL, Offset, /* GetMinOffset */ false, 4970 /* AllowNonInbounds */ true); 4971 4972 const auto &AA = A.getAAFor<AADereferenceable>( 4973 *this, IRPosition::value(*Base), DepClassTy::REQUIRED); 4974 int64_t DerefBytes = 0; 4975 if (!Stripped && this == &AA) { 4976 // Use IR information if we did not strip anything. 4977 // TODO: track globally. 4978 bool CanBeNull, CanBeFreed; 4979 DerefBytes = 4980 Base->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed); 4981 T.GlobalState.indicatePessimisticFixpoint(); 4982 } else { 4983 const DerefState &DS = AA.getState(); 4984 DerefBytes = DS.DerefBytesState.getAssumed(); 4985 T.GlobalState &= DS.GlobalState; 4986 } 4987 4988 // For now we do not try to "increase" dereferenceability due to negative 4989 // indices as we first have to come up with code to deal with loops and 4990 // for overflows of the dereferenceable bytes. 4991 int64_t OffsetSExt = Offset.getSExtValue(); 4992 if (OffsetSExt < 0) 4993 OffsetSExt = 0; 4994 4995 T.takeAssumedDerefBytesMinimum( 4996 std::max(int64_t(0), DerefBytes - OffsetSExt)); 4997 4998 if (this == &AA) { 4999 if (!Stripped) { 5000 // If nothing was stripped IR information is all we got. 5001 T.takeKnownDerefBytesMaximum( 5002 std::max(int64_t(0), DerefBytes - OffsetSExt)); 5003 T.indicatePessimisticFixpoint(); 5004 } else if (OffsetSExt > 0) { 5005 // If something was stripped but there is circular reasoning we look 5006 // for the offset. If it is positive we basically decrease the 5007 // dereferenceable bytes in a circular loop now, which will simply 5008 // drive them down to the known value in a very slow way which we 5009 // can accelerate. 5010 T.indicatePessimisticFixpoint(); 5011 } 5012 } 5013 5014 return T.isValidState(); 5015 }; 5016 5017 for (const auto &VAC : Values) 5018 if (!VisitValueCB(*VAC.getValue())) 5019 return indicatePessimisticFixpoint(); 5020 5021 return clampStateAndIndicateChange(getState(), T); 5022 } 5023 5024 /// See AbstractAttribute::trackStatistics() 5025 void trackStatistics() const override { 5026 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable) 5027 } 5028 }; 5029 5030 /// Dereferenceable attribute for a return value. 5031 struct AADereferenceableReturned final 5032 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> { 5033 AADereferenceableReturned(const IRPosition &IRP, Attributor &A) 5034 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>( 5035 IRP, A) {} 5036 5037 /// See AbstractAttribute::trackStatistics() 5038 void trackStatistics() const override { 5039 STATS_DECLTRACK_FNRET_ATTR(dereferenceable) 5040 } 5041 }; 5042 5043 /// Dereferenceable attribute for an argument 5044 struct AADereferenceableArgument final 5045 : AAArgumentFromCallSiteArguments<AADereferenceable, 5046 AADereferenceableImpl> { 5047 using Base = 5048 AAArgumentFromCallSiteArguments<AADereferenceable, AADereferenceableImpl>; 5049 AADereferenceableArgument(const IRPosition &IRP, Attributor &A) 5050 : Base(IRP, A) {} 5051 5052 /// See AbstractAttribute::trackStatistics() 5053 void trackStatistics() const override { 5054 STATS_DECLTRACK_ARG_ATTR(dereferenceable) 5055 } 5056 }; 5057 5058 /// Dereferenceable attribute for a call site argument. 5059 struct AADereferenceableCallSiteArgument final : AADereferenceableFloating { 5060 AADereferenceableCallSiteArgument(const IRPosition &IRP, Attributor &A) 5061 : AADereferenceableFloating(IRP, A) {} 5062 5063 /// See AbstractAttribute::trackStatistics() 5064 void trackStatistics() const override { 5065 STATS_DECLTRACK_CSARG_ATTR(dereferenceable) 5066 } 5067 }; 5068 5069 /// Dereferenceable attribute deduction for a call site return value. 5070 struct AADereferenceableCallSiteReturned final 5071 : AACallSiteReturnedFromReturned<AADereferenceable, AADereferenceableImpl> { 5072 using Base = 5073 AACallSiteReturnedFromReturned<AADereferenceable, AADereferenceableImpl>; 5074 AADereferenceableCallSiteReturned(const IRPosition &IRP, Attributor &A) 5075 : Base(IRP, A) {} 5076 5077 /// See AbstractAttribute::trackStatistics() 5078 void trackStatistics() const override { 5079 STATS_DECLTRACK_CS_ATTR(dereferenceable); 5080 } 5081 }; 5082 } // namespace 5083 5084 // ------------------------ Align Argument Attribute ------------------------ 5085 5086 namespace { 5087 static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA, 5088 Value &AssociatedValue, const Use *U, 5089 const Instruction *I, bool &TrackUse) { 5090 // We need to follow common pointer manipulation uses to the accesses they 5091 // feed into. 5092 if (isa<CastInst>(I)) { 5093 // Follow all but ptr2int casts. 5094 TrackUse = !isa<PtrToIntInst>(I); 5095 return 0; 5096 } 5097 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) { 5098 if (GEP->hasAllConstantIndices()) 5099 TrackUse = true; 5100 return 0; 5101 } 5102 5103 MaybeAlign MA; 5104 if (const auto *CB = dyn_cast<CallBase>(I)) { 5105 if (CB->isBundleOperand(U) || CB->isCallee(U)) 5106 return 0; 5107 5108 unsigned ArgNo = CB->getArgOperandNo(U); 5109 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo); 5110 // As long as we only use known information there is no need to track 5111 // dependences here. 5112 auto &AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP, DepClassTy::NONE); 5113 MA = MaybeAlign(AlignAA.getKnownAlign()); 5114 } 5115 5116 const DataLayout &DL = A.getDataLayout(); 5117 const Value *UseV = U->get(); 5118 if (auto *SI = dyn_cast<StoreInst>(I)) { 5119 if (SI->getPointerOperand() == UseV) 5120 MA = SI->getAlign(); 5121 } else if (auto *LI = dyn_cast<LoadInst>(I)) { 5122 if (LI->getPointerOperand() == UseV) 5123 MA = LI->getAlign(); 5124 } 5125 5126 if (!MA || *MA <= QueryingAA.getKnownAlign()) 5127 return 0; 5128 5129 unsigned Alignment = MA->value(); 5130 int64_t Offset; 5131 5132 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) { 5133 if (Base == &AssociatedValue) { 5134 // BasePointerAddr + Offset = Alignment * Q for some integer Q. 5135 // So we can say that the maximum power of two which is a divisor of 5136 // gcd(Offset, Alignment) is an alignment. 5137 5138 uint32_t gcd = std::gcd(uint32_t(abs((int32_t)Offset)), Alignment); 5139 Alignment = llvm::PowerOf2Floor(gcd); 5140 } 5141 } 5142 5143 return Alignment; 5144 } 5145 5146 struct AAAlignImpl : AAAlign { 5147 AAAlignImpl(const IRPosition &IRP, Attributor &A) : AAAlign(IRP, A) {} 5148 5149 /// See AbstractAttribute::initialize(...). 5150 void initialize(Attributor &A) override { 5151 SmallVector<Attribute, 4> Attrs; 5152 getAttrs({Attribute::Alignment}, Attrs); 5153 for (const Attribute &Attr : Attrs) 5154 takeKnownMaximum(Attr.getValueAsInt()); 5155 5156 Value &V = *getAssociatedValue().stripPointerCasts(); 5157 takeKnownMaximum(V.getPointerAlignment(A.getDataLayout()).value()); 5158 5159 if (getIRPosition().isFnInterfaceKind() && 5160 (!getAnchorScope() || 5161 !A.isFunctionIPOAmendable(*getAssociatedFunction()))) { 5162 indicatePessimisticFixpoint(); 5163 return; 5164 } 5165 5166 if (Instruction *CtxI = getCtxI()) 5167 followUsesInMBEC(*this, A, getState(), *CtxI); 5168 } 5169 5170 /// See AbstractAttribute::manifest(...). 5171 ChangeStatus manifest(Attributor &A) override { 5172 ChangeStatus LoadStoreChanged = ChangeStatus::UNCHANGED; 5173 5174 // Check for users that allow alignment annotations. 5175 Value &AssociatedValue = getAssociatedValue(); 5176 for (const Use &U : AssociatedValue.uses()) { 5177 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) { 5178 if (SI->getPointerOperand() == &AssociatedValue) 5179 if (SI->getAlign() < getAssumedAlign()) { 5180 STATS_DECLTRACK(AAAlign, Store, 5181 "Number of times alignment added to a store"); 5182 SI->setAlignment(getAssumedAlign()); 5183 LoadStoreChanged = ChangeStatus::CHANGED; 5184 } 5185 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) { 5186 if (LI->getPointerOperand() == &AssociatedValue) 5187 if (LI->getAlign() < getAssumedAlign()) { 5188 LI->setAlignment(getAssumedAlign()); 5189 STATS_DECLTRACK(AAAlign, Load, 5190 "Number of times alignment added to a load"); 5191 LoadStoreChanged = ChangeStatus::CHANGED; 5192 } 5193 } 5194 } 5195 5196 ChangeStatus Changed = AAAlign::manifest(A); 5197 5198 Align InheritAlign = 5199 getAssociatedValue().getPointerAlignment(A.getDataLayout()); 5200 if (InheritAlign >= getAssumedAlign()) 5201 return LoadStoreChanged; 5202 return Changed | LoadStoreChanged; 5203 } 5204 5205 // TODO: Provide a helper to determine the implied ABI alignment and check in 5206 // the existing manifest method and a new one for AAAlignImpl that value 5207 // to avoid making the alignment explicit if it did not improve. 5208 5209 /// See AbstractAttribute::getDeducedAttributes 5210 void getDeducedAttributes(LLVMContext &Ctx, 5211 SmallVectorImpl<Attribute> &Attrs) const override { 5212 if (getAssumedAlign() > 1) 5213 Attrs.emplace_back( 5214 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign()))); 5215 } 5216 5217 /// See followUsesInMBEC 5218 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I, 5219 AAAlign::StateType &State) { 5220 bool TrackUse = false; 5221 5222 unsigned int KnownAlign = 5223 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse); 5224 State.takeKnownMaximum(KnownAlign); 5225 5226 return TrackUse; 5227 } 5228 5229 /// See AbstractAttribute::getAsStr(). 5230 const std::string getAsStr() const override { 5231 return "align<" + std::to_string(getKnownAlign().value()) + "-" + 5232 std::to_string(getAssumedAlign().value()) + ">"; 5233 } 5234 }; 5235 5236 /// Align attribute for a floating value. 5237 struct AAAlignFloating : AAAlignImpl { 5238 AAAlignFloating(const IRPosition &IRP, Attributor &A) : AAAlignImpl(IRP, A) {} 5239 5240 /// See AbstractAttribute::updateImpl(...). 5241 ChangeStatus updateImpl(Attributor &A) override { 5242 const DataLayout &DL = A.getDataLayout(); 5243 5244 bool Stripped; 5245 bool UsedAssumedInformation = false; 5246 SmallVector<AA::ValueAndContext> Values; 5247 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values, 5248 AA::AnyScope, UsedAssumedInformation)) { 5249 Values.push_back({getAssociatedValue(), getCtxI()}); 5250 Stripped = false; 5251 } else { 5252 Stripped = Values.size() != 1 || 5253 Values.front().getValue() != &getAssociatedValue(); 5254 } 5255 5256 StateType T; 5257 auto VisitValueCB = [&](Value &V) -> bool { 5258 if (isa<UndefValue>(V) || isa<ConstantPointerNull>(V)) 5259 return true; 5260 const auto &AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V), 5261 DepClassTy::REQUIRED); 5262 if (!Stripped && this == &AA) { 5263 int64_t Offset; 5264 unsigned Alignment = 1; 5265 if (const Value *Base = 5266 GetPointerBaseWithConstantOffset(&V, Offset, DL)) { 5267 // TODO: Use AAAlign for the base too. 5268 Align PA = Base->getPointerAlignment(DL); 5269 // BasePointerAddr + Offset = Alignment * Q for some integer Q. 5270 // So we can say that the maximum power of two which is a divisor of 5271 // gcd(Offset, Alignment) is an alignment. 5272 5273 uint32_t gcd = 5274 std::gcd(uint32_t(abs((int32_t)Offset)), uint32_t(PA.value())); 5275 Alignment = llvm::PowerOf2Floor(gcd); 5276 } else { 5277 Alignment = V.getPointerAlignment(DL).value(); 5278 } 5279 // Use only IR information if we did not strip anything. 5280 T.takeKnownMaximum(Alignment); 5281 T.indicatePessimisticFixpoint(); 5282 } else { 5283 // Use abstract attribute information. 5284 const AAAlign::StateType &DS = AA.getState(); 5285 T ^= DS; 5286 } 5287 return T.isValidState(); 5288 }; 5289 5290 for (const auto &VAC : Values) { 5291 if (!VisitValueCB(*VAC.getValue())) 5292 return indicatePessimisticFixpoint(); 5293 } 5294 5295 // TODO: If we know we visited all incoming values, thus no are assumed 5296 // dead, we can take the known information from the state T. 5297 return clampStateAndIndicateChange(getState(), T); 5298 } 5299 5300 /// See AbstractAttribute::trackStatistics() 5301 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) } 5302 }; 5303 5304 /// Align attribute for function return value. 5305 struct AAAlignReturned final 5306 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> { 5307 using Base = AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>; 5308 AAAlignReturned(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {} 5309 5310 /// See AbstractAttribute::initialize(...). 5311 void initialize(Attributor &A) override { 5312 Base::initialize(A); 5313 Function *F = getAssociatedFunction(); 5314 if (!F || F->isDeclaration()) 5315 indicatePessimisticFixpoint(); 5316 } 5317 5318 /// See AbstractAttribute::trackStatistics() 5319 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) } 5320 }; 5321 5322 /// Align attribute for function argument. 5323 struct AAAlignArgument final 5324 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> { 5325 using Base = AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>; 5326 AAAlignArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {} 5327 5328 /// See AbstractAttribute::manifest(...). 5329 ChangeStatus manifest(Attributor &A) override { 5330 // If the associated argument is involved in a must-tail call we give up 5331 // because we would need to keep the argument alignments of caller and 5332 // callee in-sync. Just does not seem worth the trouble right now. 5333 if (A.getInfoCache().isInvolvedInMustTailCall(*getAssociatedArgument())) 5334 return ChangeStatus::UNCHANGED; 5335 return Base::manifest(A); 5336 } 5337 5338 /// See AbstractAttribute::trackStatistics() 5339 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) } 5340 }; 5341 5342 struct AAAlignCallSiteArgument final : AAAlignFloating { 5343 AAAlignCallSiteArgument(const IRPosition &IRP, Attributor &A) 5344 : AAAlignFloating(IRP, A) {} 5345 5346 /// See AbstractAttribute::manifest(...). 5347 ChangeStatus manifest(Attributor &A) override { 5348 // If the associated argument is involved in a must-tail call we give up 5349 // because we would need to keep the argument alignments of caller and 5350 // callee in-sync. Just does not seem worth the trouble right now. 5351 if (Argument *Arg = getAssociatedArgument()) 5352 if (A.getInfoCache().isInvolvedInMustTailCall(*Arg)) 5353 return ChangeStatus::UNCHANGED; 5354 ChangeStatus Changed = AAAlignImpl::manifest(A); 5355 Align InheritAlign = 5356 getAssociatedValue().getPointerAlignment(A.getDataLayout()); 5357 if (InheritAlign >= getAssumedAlign()) 5358 Changed = ChangeStatus::UNCHANGED; 5359 return Changed; 5360 } 5361 5362 /// See AbstractAttribute::updateImpl(Attributor &A). 5363 ChangeStatus updateImpl(Attributor &A) override { 5364 ChangeStatus Changed = AAAlignFloating::updateImpl(A); 5365 if (Argument *Arg = getAssociatedArgument()) { 5366 // We only take known information from the argument 5367 // so we do not need to track a dependence. 5368 const auto &ArgAlignAA = A.getAAFor<AAAlign>( 5369 *this, IRPosition::argument(*Arg), DepClassTy::NONE); 5370 takeKnownMaximum(ArgAlignAA.getKnownAlign().value()); 5371 } 5372 return Changed; 5373 } 5374 5375 /// See AbstractAttribute::trackStatistics() 5376 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) } 5377 }; 5378 5379 /// Align attribute deduction for a call site return value. 5380 struct AAAlignCallSiteReturned final 5381 : AACallSiteReturnedFromReturned<AAAlign, AAAlignImpl> { 5382 using Base = AACallSiteReturnedFromReturned<AAAlign, AAAlignImpl>; 5383 AAAlignCallSiteReturned(const IRPosition &IRP, Attributor &A) 5384 : Base(IRP, A) {} 5385 5386 /// See AbstractAttribute::initialize(...). 5387 void initialize(Attributor &A) override { 5388 Base::initialize(A); 5389 Function *F = getAssociatedFunction(); 5390 if (!F || F->isDeclaration()) 5391 indicatePessimisticFixpoint(); 5392 } 5393 5394 /// See AbstractAttribute::trackStatistics() 5395 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); } 5396 }; 5397 } // namespace 5398 5399 /// ------------------ Function No-Return Attribute ---------------------------- 5400 namespace { 5401 struct AANoReturnImpl : public AANoReturn { 5402 AANoReturnImpl(const IRPosition &IRP, Attributor &A) : AANoReturn(IRP, A) {} 5403 5404 /// See AbstractAttribute::initialize(...). 5405 void initialize(Attributor &A) override { 5406 AANoReturn::initialize(A); 5407 Function *F = getAssociatedFunction(); 5408 if (!F || F->isDeclaration()) 5409 indicatePessimisticFixpoint(); 5410 } 5411 5412 /// See AbstractAttribute::getAsStr(). 5413 const std::string getAsStr() const override { 5414 return getAssumed() ? "noreturn" : "may-return"; 5415 } 5416 5417 /// See AbstractAttribute::updateImpl(Attributor &A). 5418 ChangeStatus updateImpl(Attributor &A) override { 5419 auto CheckForNoReturn = [](Instruction &) { return false; }; 5420 bool UsedAssumedInformation = false; 5421 if (!A.checkForAllInstructions(CheckForNoReturn, *this, 5422 {(unsigned)Instruction::Ret}, 5423 UsedAssumedInformation)) 5424 return indicatePessimisticFixpoint(); 5425 return ChangeStatus::UNCHANGED; 5426 } 5427 }; 5428 5429 struct AANoReturnFunction final : AANoReturnImpl { 5430 AANoReturnFunction(const IRPosition &IRP, Attributor &A) 5431 : AANoReturnImpl(IRP, A) {} 5432 5433 /// See AbstractAttribute::trackStatistics() 5434 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) } 5435 }; 5436 5437 /// NoReturn attribute deduction for a call sites. 5438 struct AANoReturnCallSite final : AANoReturnImpl { 5439 AANoReturnCallSite(const IRPosition &IRP, Attributor &A) 5440 : AANoReturnImpl(IRP, A) {} 5441 5442 /// See AbstractAttribute::initialize(...). 5443 void initialize(Attributor &A) override { 5444 AANoReturnImpl::initialize(A); 5445 if (Function *F = getAssociatedFunction()) { 5446 const IRPosition &FnPos = IRPosition::function(*F); 5447 auto &FnAA = A.getAAFor<AANoReturn>(*this, FnPos, DepClassTy::REQUIRED); 5448 if (!FnAA.isAssumedNoReturn()) 5449 indicatePessimisticFixpoint(); 5450 } 5451 } 5452 5453 /// See AbstractAttribute::updateImpl(...). 5454 ChangeStatus updateImpl(Attributor &A) override { 5455 // TODO: Once we have call site specific value information we can provide 5456 // call site specific liveness information and then it makes 5457 // sense to specialize attributes for call sites arguments instead of 5458 // redirecting requests to the callee argument. 5459 Function *F = getAssociatedFunction(); 5460 const IRPosition &FnPos = IRPosition::function(*F); 5461 auto &FnAA = A.getAAFor<AANoReturn>(*this, FnPos, DepClassTy::REQUIRED); 5462 return clampStateAndIndicateChange(getState(), FnAA.getState()); 5463 } 5464 5465 /// See AbstractAttribute::trackStatistics() 5466 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); } 5467 }; 5468 } // namespace 5469 5470 /// ----------------------- Instance Info --------------------------------- 5471 5472 namespace { 5473 /// A class to hold the state of for no-capture attributes. 5474 struct AAInstanceInfoImpl : public AAInstanceInfo { 5475 AAInstanceInfoImpl(const IRPosition &IRP, Attributor &A) 5476 : AAInstanceInfo(IRP, A) {} 5477 5478 /// See AbstractAttribute::initialize(...). 5479 void initialize(Attributor &A) override { 5480 Value &V = getAssociatedValue(); 5481 if (auto *C = dyn_cast<Constant>(&V)) { 5482 if (C->isThreadDependent()) 5483 indicatePessimisticFixpoint(); 5484 else 5485 indicateOptimisticFixpoint(); 5486 return; 5487 } 5488 if (auto *CB = dyn_cast<CallBase>(&V)) 5489 if (CB->arg_size() == 0 && !CB->mayHaveSideEffects() && 5490 !CB->mayReadFromMemory()) { 5491 indicateOptimisticFixpoint(); 5492 return; 5493 } 5494 } 5495 5496 /// See AbstractAttribute::updateImpl(...). 5497 ChangeStatus updateImpl(Attributor &A) override { 5498 ChangeStatus Changed = ChangeStatus::UNCHANGED; 5499 5500 Value &V = getAssociatedValue(); 5501 const Function *Scope = nullptr; 5502 if (auto *I = dyn_cast<Instruction>(&V)) 5503 Scope = I->getFunction(); 5504 if (auto *A = dyn_cast<Argument>(&V)) { 5505 Scope = A->getParent(); 5506 if (!Scope->hasLocalLinkage()) 5507 return Changed; 5508 } 5509 if (!Scope) 5510 return indicateOptimisticFixpoint(); 5511 5512 auto &NoRecurseAA = A.getAAFor<AANoRecurse>( 5513 *this, IRPosition::function(*Scope), DepClassTy::OPTIONAL); 5514 if (NoRecurseAA.isAssumedNoRecurse()) 5515 return Changed; 5516 5517 auto UsePred = [&](const Use &U, bool &Follow) { 5518 const Instruction *UserI = dyn_cast<Instruction>(U.getUser()); 5519 if (!UserI || isa<GetElementPtrInst>(UserI) || isa<CastInst>(UserI) || 5520 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) { 5521 Follow = true; 5522 return true; 5523 } 5524 if (isa<LoadInst>(UserI) || isa<CmpInst>(UserI) || 5525 (isa<StoreInst>(UserI) && 5526 cast<StoreInst>(UserI)->getValueOperand() != U.get())) 5527 return true; 5528 if (auto *CB = dyn_cast<CallBase>(UserI)) { 5529 // This check is not guaranteeing uniqueness but for now that we cannot 5530 // end up with two versions of \p U thinking it was one. 5531 if (!CB->getCalledFunction() || 5532 !CB->getCalledFunction()->hasLocalLinkage()) 5533 return true; 5534 if (!CB->isArgOperand(&U)) 5535 return false; 5536 const auto &ArgInstanceInfoAA = A.getAAFor<AAInstanceInfo>( 5537 *this, IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U)), 5538 DepClassTy::OPTIONAL); 5539 if (!ArgInstanceInfoAA.isAssumedUniqueForAnalysis()) 5540 return false; 5541 // If this call base might reach the scope again we might forward the 5542 // argument back here. This is very conservative. 5543 if (AA::isPotentiallyReachable( 5544 A, *CB, *Scope, *this, /* ExclusionSet */ nullptr, 5545 [Scope](const Function &Fn) { return &Fn != Scope; })) 5546 return false; 5547 return true; 5548 } 5549 return false; 5550 }; 5551 5552 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) { 5553 if (auto *SI = dyn_cast<StoreInst>(OldU.getUser())) { 5554 auto *Ptr = SI->getPointerOperand()->stripPointerCasts(); 5555 if ((isa<AllocaInst>(Ptr) || isNoAliasCall(Ptr)) && 5556 AA::isDynamicallyUnique(A, *this, *Ptr)) 5557 return true; 5558 } 5559 return false; 5560 }; 5561 5562 if (!A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ true, 5563 DepClassTy::OPTIONAL, 5564 /* IgnoreDroppableUses */ true, EquivalentUseCB)) 5565 return indicatePessimisticFixpoint(); 5566 5567 return Changed; 5568 } 5569 5570 /// See AbstractState::getAsStr(). 5571 const std::string getAsStr() const override { 5572 return isAssumedUniqueForAnalysis() ? "<unique [fAa]>" : "<unknown>"; 5573 } 5574 5575 /// See AbstractAttribute::trackStatistics() 5576 void trackStatistics() const override {} 5577 }; 5578 5579 /// InstanceInfo attribute for floating values. 5580 struct AAInstanceInfoFloating : AAInstanceInfoImpl { 5581 AAInstanceInfoFloating(const IRPosition &IRP, Attributor &A) 5582 : AAInstanceInfoImpl(IRP, A) {} 5583 }; 5584 5585 /// NoCapture attribute for function arguments. 5586 struct AAInstanceInfoArgument final : AAInstanceInfoFloating { 5587 AAInstanceInfoArgument(const IRPosition &IRP, Attributor &A) 5588 : AAInstanceInfoFloating(IRP, A) {} 5589 }; 5590 5591 /// InstanceInfo attribute for call site arguments. 5592 struct AAInstanceInfoCallSiteArgument final : AAInstanceInfoImpl { 5593 AAInstanceInfoCallSiteArgument(const IRPosition &IRP, Attributor &A) 5594 : AAInstanceInfoImpl(IRP, A) {} 5595 5596 /// See AbstractAttribute::updateImpl(...). 5597 ChangeStatus updateImpl(Attributor &A) override { 5598 // TODO: Once we have call site specific value information we can provide 5599 // call site specific liveness information and then it makes 5600 // sense to specialize attributes for call sites arguments instead of 5601 // redirecting requests to the callee argument. 5602 Argument *Arg = getAssociatedArgument(); 5603 if (!Arg) 5604 return indicatePessimisticFixpoint(); 5605 const IRPosition &ArgPos = IRPosition::argument(*Arg); 5606 auto &ArgAA = 5607 A.getAAFor<AAInstanceInfo>(*this, ArgPos, DepClassTy::REQUIRED); 5608 return clampStateAndIndicateChange(getState(), ArgAA.getState()); 5609 } 5610 }; 5611 5612 /// InstanceInfo attribute for function return value. 5613 struct AAInstanceInfoReturned final : AAInstanceInfoImpl { 5614 AAInstanceInfoReturned(const IRPosition &IRP, Attributor &A) 5615 : AAInstanceInfoImpl(IRP, A) { 5616 llvm_unreachable("InstanceInfo is not applicable to function returns!"); 5617 } 5618 5619 /// See AbstractAttribute::initialize(...). 5620 void initialize(Attributor &A) override { 5621 llvm_unreachable("InstanceInfo is not applicable to function returns!"); 5622 } 5623 5624 /// See AbstractAttribute::updateImpl(...). 5625 ChangeStatus updateImpl(Attributor &A) override { 5626 llvm_unreachable("InstanceInfo is not applicable to function returns!"); 5627 } 5628 }; 5629 5630 /// InstanceInfo attribute deduction for a call site return value. 5631 struct AAInstanceInfoCallSiteReturned final : AAInstanceInfoFloating { 5632 AAInstanceInfoCallSiteReturned(const IRPosition &IRP, Attributor &A) 5633 : AAInstanceInfoFloating(IRP, A) {} 5634 }; 5635 } // namespace 5636 5637 /// ----------------------- Variable Capturing --------------------------------- 5638 5639 namespace { 5640 /// A class to hold the state of for no-capture attributes. 5641 struct AANoCaptureImpl : public AANoCapture { 5642 AANoCaptureImpl(const IRPosition &IRP, Attributor &A) : AANoCapture(IRP, A) {} 5643 5644 /// See AbstractAttribute::initialize(...). 5645 void initialize(Attributor &A) override { 5646 if (hasAttr(getAttrKind(), /* IgnoreSubsumingPositions */ true)) { 5647 indicateOptimisticFixpoint(); 5648 return; 5649 } 5650 Function *AnchorScope = getAnchorScope(); 5651 if (isFnInterfaceKind() && 5652 (!AnchorScope || !A.isFunctionIPOAmendable(*AnchorScope))) { 5653 indicatePessimisticFixpoint(); 5654 return; 5655 } 5656 5657 // You cannot "capture" null in the default address space. 5658 if (isa<ConstantPointerNull>(getAssociatedValue()) && 5659 getAssociatedValue().getType()->getPointerAddressSpace() == 0) { 5660 indicateOptimisticFixpoint(); 5661 return; 5662 } 5663 5664 const Function *F = 5665 isArgumentPosition() ? getAssociatedFunction() : AnchorScope; 5666 5667 // Check what state the associated function can actually capture. 5668 if (F) 5669 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this); 5670 else 5671 indicatePessimisticFixpoint(); 5672 } 5673 5674 /// See AbstractAttribute::updateImpl(...). 5675 ChangeStatus updateImpl(Attributor &A) override; 5676 5677 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...). 5678 void getDeducedAttributes(LLVMContext &Ctx, 5679 SmallVectorImpl<Attribute> &Attrs) const override { 5680 if (!isAssumedNoCaptureMaybeReturned()) 5681 return; 5682 5683 if (isArgumentPosition()) { 5684 if (isAssumedNoCapture()) 5685 Attrs.emplace_back(Attribute::get(Ctx, Attribute::NoCapture)); 5686 else if (ManifestInternal) 5687 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned")); 5688 } 5689 } 5690 5691 /// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known 5692 /// depending on the ability of the function associated with \p IRP to capture 5693 /// state in memory and through "returning/throwing", respectively. 5694 static void determineFunctionCaptureCapabilities(const IRPosition &IRP, 5695 const Function &F, 5696 BitIntegerState &State) { 5697 // TODO: Once we have memory behavior attributes we should use them here. 5698 5699 // If we know we cannot communicate or write to memory, we do not care about 5700 // ptr2int anymore. 5701 if (F.onlyReadsMemory() && F.doesNotThrow() && 5702 F.getReturnType()->isVoidTy()) { 5703 State.addKnownBits(NO_CAPTURE); 5704 return; 5705 } 5706 5707 // A function cannot capture state in memory if it only reads memory, it can 5708 // however return/throw state and the state might be influenced by the 5709 // pointer value, e.g., loading from a returned pointer might reveal a bit. 5710 if (F.onlyReadsMemory()) 5711 State.addKnownBits(NOT_CAPTURED_IN_MEM); 5712 5713 // A function cannot communicate state back if it does not through 5714 // exceptions and doesn not return values. 5715 if (F.doesNotThrow() && F.getReturnType()->isVoidTy()) 5716 State.addKnownBits(NOT_CAPTURED_IN_RET); 5717 5718 // Check existing "returned" attributes. 5719 int ArgNo = IRP.getCalleeArgNo(); 5720 if (F.doesNotThrow() && ArgNo >= 0) { 5721 for (unsigned u = 0, e = F.arg_size(); u < e; ++u) 5722 if (F.hasParamAttribute(u, Attribute::Returned)) { 5723 if (u == unsigned(ArgNo)) 5724 State.removeAssumedBits(NOT_CAPTURED_IN_RET); 5725 else if (F.onlyReadsMemory()) 5726 State.addKnownBits(NO_CAPTURE); 5727 else 5728 State.addKnownBits(NOT_CAPTURED_IN_RET); 5729 break; 5730 } 5731 } 5732 } 5733 5734 /// See AbstractState::getAsStr(). 5735 const std::string getAsStr() const override { 5736 if (isKnownNoCapture()) 5737 return "known not-captured"; 5738 if (isAssumedNoCapture()) 5739 return "assumed not-captured"; 5740 if (isKnownNoCaptureMaybeReturned()) 5741 return "known not-captured-maybe-returned"; 5742 if (isAssumedNoCaptureMaybeReturned()) 5743 return "assumed not-captured-maybe-returned"; 5744 return "assumed-captured"; 5745 } 5746 5747 /// Check the use \p U and update \p State accordingly. Return true if we 5748 /// should continue to update the state. 5749 bool checkUse(Attributor &A, AANoCapture::StateType &State, const Use &U, 5750 bool &Follow) { 5751 Instruction *UInst = cast<Instruction>(U.getUser()); 5752 LLVM_DEBUG(dbgs() << "[AANoCapture] Check use: " << *U.get() << " in " 5753 << *UInst << "\n"); 5754 5755 // Deal with ptr2int by following uses. 5756 if (isa<PtrToIntInst>(UInst)) { 5757 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n"); 5758 return isCapturedIn(State, /* Memory */ true, /* Integer */ true, 5759 /* Return */ true); 5760 } 5761 5762 // For stores we already checked if we can follow them, if they make it 5763 // here we give up. 5764 if (isa<StoreInst>(UInst)) 5765 return isCapturedIn(State, /* Memory */ true, /* Integer */ false, 5766 /* Return */ false); 5767 5768 // Explicitly catch return instructions. 5769 if (isa<ReturnInst>(UInst)) { 5770 if (UInst->getFunction() == getAnchorScope()) 5771 return isCapturedIn(State, /* Memory */ false, /* Integer */ false, 5772 /* Return */ true); 5773 return isCapturedIn(State, /* Memory */ true, /* Integer */ true, 5774 /* Return */ true); 5775 } 5776 5777 // For now we only use special logic for call sites. However, the tracker 5778 // itself knows about a lot of other non-capturing cases already. 5779 auto *CB = dyn_cast<CallBase>(UInst); 5780 if (!CB || !CB->isArgOperand(&U)) 5781 return isCapturedIn(State, /* Memory */ true, /* Integer */ true, 5782 /* Return */ true); 5783 5784 unsigned ArgNo = CB->getArgOperandNo(&U); 5785 const IRPosition &CSArgPos = IRPosition::callsite_argument(*CB, ArgNo); 5786 // If we have a abstract no-capture attribute for the argument we can use 5787 // it to justify a non-capture attribute here. This allows recursion! 5788 auto &ArgNoCaptureAA = 5789 A.getAAFor<AANoCapture>(*this, CSArgPos, DepClassTy::REQUIRED); 5790 if (ArgNoCaptureAA.isAssumedNoCapture()) 5791 return isCapturedIn(State, /* Memory */ false, /* Integer */ false, 5792 /* Return */ false); 5793 if (ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) { 5794 Follow = true; 5795 return isCapturedIn(State, /* Memory */ false, /* Integer */ false, 5796 /* Return */ false); 5797 } 5798 5799 // Lastly, we could not find a reason no-capture can be assumed so we don't. 5800 return isCapturedIn(State, /* Memory */ true, /* Integer */ true, 5801 /* Return */ true); 5802 } 5803 5804 /// Update \p State according to \p CapturedInMem, \p CapturedInInt, and 5805 /// \p CapturedInRet, then return true if we should continue updating the 5806 /// state. 5807 static bool isCapturedIn(AANoCapture::StateType &State, bool CapturedInMem, 5808 bool CapturedInInt, bool CapturedInRet) { 5809 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int " 5810 << CapturedInInt << "|Ret " << CapturedInRet << "]\n"); 5811 if (CapturedInMem) 5812 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM); 5813 if (CapturedInInt) 5814 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT); 5815 if (CapturedInRet) 5816 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET); 5817 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED); 5818 } 5819 }; 5820 5821 ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) { 5822 const IRPosition &IRP = getIRPosition(); 5823 Value *V = isArgumentPosition() ? IRP.getAssociatedArgument() 5824 : &IRP.getAssociatedValue(); 5825 if (!V) 5826 return indicatePessimisticFixpoint(); 5827 5828 const Function *F = 5829 isArgumentPosition() ? IRP.getAssociatedFunction() : IRP.getAnchorScope(); 5830 assert(F && "Expected a function!"); 5831 const IRPosition &FnPos = IRPosition::function(*F); 5832 5833 AANoCapture::StateType T; 5834 5835 // Readonly means we cannot capture through memory. 5836 bool IsKnown; 5837 if (AA::isAssumedReadOnly(A, FnPos, *this, IsKnown)) { 5838 T.addKnownBits(NOT_CAPTURED_IN_MEM); 5839 if (IsKnown) 5840 addKnownBits(NOT_CAPTURED_IN_MEM); 5841 } 5842 5843 // Make sure all returned values are different than the underlying value. 5844 // TODO: we could do this in a more sophisticated way inside 5845 // AAReturnedValues, e.g., track all values that escape through returns 5846 // directly somehow. 5847 auto CheckReturnedArgs = [&](const AAReturnedValues &RVAA) { 5848 if (!RVAA.getState().isValidState()) 5849 return false; 5850 bool SeenConstant = false; 5851 for (const auto &It : RVAA.returned_values()) { 5852 if (isa<Constant>(It.first)) { 5853 if (SeenConstant) 5854 return false; 5855 SeenConstant = true; 5856 } else if (!isa<Argument>(It.first) || 5857 It.first == getAssociatedArgument()) 5858 return false; 5859 } 5860 return true; 5861 }; 5862 5863 const auto &NoUnwindAA = 5864 A.getAAFor<AANoUnwind>(*this, FnPos, DepClassTy::OPTIONAL); 5865 if (NoUnwindAA.isAssumedNoUnwind()) { 5866 bool IsVoidTy = F->getReturnType()->isVoidTy(); 5867 const AAReturnedValues *RVAA = 5868 IsVoidTy ? nullptr 5869 : &A.getAAFor<AAReturnedValues>(*this, FnPos, 5870 5871 DepClassTy::OPTIONAL); 5872 if (IsVoidTy || CheckReturnedArgs(*RVAA)) { 5873 T.addKnownBits(NOT_CAPTURED_IN_RET); 5874 if (T.isKnown(NOT_CAPTURED_IN_MEM)) 5875 return ChangeStatus::UNCHANGED; 5876 if (NoUnwindAA.isKnownNoUnwind() && 5877 (IsVoidTy || RVAA->getState().isAtFixpoint())) { 5878 addKnownBits(NOT_CAPTURED_IN_RET); 5879 if (isKnown(NOT_CAPTURED_IN_MEM)) 5880 return indicateOptimisticFixpoint(); 5881 } 5882 } 5883 } 5884 5885 auto IsDereferenceableOrNull = [&](Value *O, const DataLayout &DL) { 5886 const auto &DerefAA = A.getAAFor<AADereferenceable>( 5887 *this, IRPosition::value(*O), DepClassTy::OPTIONAL); 5888 return DerefAA.getAssumedDereferenceableBytes(); 5889 }; 5890 5891 auto UseCheck = [&](const Use &U, bool &Follow) -> bool { 5892 switch (DetermineUseCaptureKind(U, IsDereferenceableOrNull)) { 5893 case UseCaptureKind::NO_CAPTURE: 5894 return true; 5895 case UseCaptureKind::MAY_CAPTURE: 5896 return checkUse(A, T, U, Follow); 5897 case UseCaptureKind::PASSTHROUGH: 5898 Follow = true; 5899 return true; 5900 } 5901 llvm_unreachable("Unexpected use capture kind!"); 5902 }; 5903 5904 if (!A.checkForAllUses(UseCheck, *this, *V)) 5905 return indicatePessimisticFixpoint(); 5906 5907 AANoCapture::StateType &S = getState(); 5908 auto Assumed = S.getAssumed(); 5909 S.intersectAssumedBits(T.getAssumed()); 5910 if (!isAssumedNoCaptureMaybeReturned()) 5911 return indicatePessimisticFixpoint(); 5912 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED 5913 : ChangeStatus::CHANGED; 5914 } 5915 5916 /// NoCapture attribute for function arguments. 5917 struct AANoCaptureArgument final : AANoCaptureImpl { 5918 AANoCaptureArgument(const IRPosition &IRP, Attributor &A) 5919 : AANoCaptureImpl(IRP, A) {} 5920 5921 /// See AbstractAttribute::trackStatistics() 5922 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) } 5923 }; 5924 5925 /// NoCapture attribute for call site arguments. 5926 struct AANoCaptureCallSiteArgument final : AANoCaptureImpl { 5927 AANoCaptureCallSiteArgument(const IRPosition &IRP, Attributor &A) 5928 : AANoCaptureImpl(IRP, A) {} 5929 5930 /// See AbstractAttribute::initialize(...). 5931 void initialize(Attributor &A) override { 5932 if (Argument *Arg = getAssociatedArgument()) 5933 if (Arg->hasByValAttr()) 5934 indicateOptimisticFixpoint(); 5935 AANoCaptureImpl::initialize(A); 5936 } 5937 5938 /// See AbstractAttribute::updateImpl(...). 5939 ChangeStatus updateImpl(Attributor &A) override { 5940 // TODO: Once we have call site specific value information we can provide 5941 // call site specific liveness information and then it makes 5942 // sense to specialize attributes for call sites arguments instead of 5943 // redirecting requests to the callee argument. 5944 Argument *Arg = getAssociatedArgument(); 5945 if (!Arg) 5946 return indicatePessimisticFixpoint(); 5947 const IRPosition &ArgPos = IRPosition::argument(*Arg); 5948 auto &ArgAA = A.getAAFor<AANoCapture>(*this, ArgPos, DepClassTy::REQUIRED); 5949 return clampStateAndIndicateChange(getState(), ArgAA.getState()); 5950 } 5951 5952 /// See AbstractAttribute::trackStatistics() 5953 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nocapture)}; 5954 }; 5955 5956 /// NoCapture attribute for floating values. 5957 struct AANoCaptureFloating final : AANoCaptureImpl { 5958 AANoCaptureFloating(const IRPosition &IRP, Attributor &A) 5959 : AANoCaptureImpl(IRP, A) {} 5960 5961 /// See AbstractAttribute::trackStatistics() 5962 void trackStatistics() const override { 5963 STATS_DECLTRACK_FLOATING_ATTR(nocapture) 5964 } 5965 }; 5966 5967 /// NoCapture attribute for function return value. 5968 struct AANoCaptureReturned final : AANoCaptureImpl { 5969 AANoCaptureReturned(const IRPosition &IRP, Attributor &A) 5970 : AANoCaptureImpl(IRP, A) { 5971 llvm_unreachable("NoCapture is not applicable to function returns!"); 5972 } 5973 5974 /// See AbstractAttribute::initialize(...). 5975 void initialize(Attributor &A) override { 5976 llvm_unreachable("NoCapture is not applicable to function returns!"); 5977 } 5978 5979 /// See AbstractAttribute::updateImpl(...). 5980 ChangeStatus updateImpl(Attributor &A) override { 5981 llvm_unreachable("NoCapture is not applicable to function returns!"); 5982 } 5983 5984 /// See AbstractAttribute::trackStatistics() 5985 void trackStatistics() const override {} 5986 }; 5987 5988 /// NoCapture attribute deduction for a call site return value. 5989 struct AANoCaptureCallSiteReturned final : AANoCaptureImpl { 5990 AANoCaptureCallSiteReturned(const IRPosition &IRP, Attributor &A) 5991 : AANoCaptureImpl(IRP, A) {} 5992 5993 /// See AbstractAttribute::initialize(...). 5994 void initialize(Attributor &A) override { 5995 const Function *F = getAnchorScope(); 5996 // Check what state the associated function can actually capture. 5997 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this); 5998 } 5999 6000 /// See AbstractAttribute::trackStatistics() 6001 void trackStatistics() const override { 6002 STATS_DECLTRACK_CSRET_ATTR(nocapture) 6003 } 6004 }; 6005 } // namespace 6006 6007 /// ------------------ Value Simplify Attribute ---------------------------- 6008 6009 bool ValueSimplifyStateType::unionAssumed(std::optional<Value *> Other) { 6010 // FIXME: Add a typecast support. 6011 SimplifiedAssociatedValue = AA::combineOptionalValuesInAAValueLatice( 6012 SimplifiedAssociatedValue, Other, Ty); 6013 if (SimplifiedAssociatedValue == std::optional<Value *>(nullptr)) 6014 return false; 6015 6016 LLVM_DEBUG({ 6017 if (SimplifiedAssociatedValue) 6018 dbgs() << "[ValueSimplify] is assumed to be " 6019 << **SimplifiedAssociatedValue << "\n"; 6020 else 6021 dbgs() << "[ValueSimplify] is assumed to be <none>\n"; 6022 }); 6023 return true; 6024 } 6025 6026 namespace { 6027 struct AAValueSimplifyImpl : AAValueSimplify { 6028 AAValueSimplifyImpl(const IRPosition &IRP, Attributor &A) 6029 : AAValueSimplify(IRP, A) {} 6030 6031 /// See AbstractAttribute::initialize(...). 6032 void initialize(Attributor &A) override { 6033 if (getAssociatedValue().getType()->isVoidTy()) 6034 indicatePessimisticFixpoint(); 6035 if (A.hasSimplificationCallback(getIRPosition())) 6036 indicatePessimisticFixpoint(); 6037 } 6038 6039 /// See AbstractAttribute::getAsStr(). 6040 const std::string getAsStr() const override { 6041 LLVM_DEBUG({ 6042 dbgs() << "SAV: " << (bool)SimplifiedAssociatedValue << " "; 6043 if (SimplifiedAssociatedValue && *SimplifiedAssociatedValue) 6044 dbgs() << "SAV: " << **SimplifiedAssociatedValue << " "; 6045 }); 6046 return isValidState() ? (isAtFixpoint() ? "simplified" : "maybe-simple") 6047 : "not-simple"; 6048 } 6049 6050 /// See AbstractAttribute::trackStatistics() 6051 void trackStatistics() const override {} 6052 6053 /// See AAValueSimplify::getAssumedSimplifiedValue() 6054 std::optional<Value *> 6055 getAssumedSimplifiedValue(Attributor &A) const override { 6056 return SimplifiedAssociatedValue; 6057 } 6058 6059 /// Ensure the return value is \p V with type \p Ty, if not possible return 6060 /// nullptr. If \p Check is true we will only verify such an operation would 6061 /// suceed and return a non-nullptr value if that is the case. No IR is 6062 /// generated or modified. 6063 static Value *ensureType(Attributor &A, Value &V, Type &Ty, Instruction *CtxI, 6064 bool Check) { 6065 if (auto *TypedV = AA::getWithType(V, Ty)) 6066 return TypedV; 6067 if (CtxI && V.getType()->canLosslesslyBitCastTo(&Ty)) 6068 return Check ? &V 6069 : BitCastInst::CreatePointerBitCastOrAddrSpaceCast(&V, &Ty, 6070 "", CtxI); 6071 return nullptr; 6072 } 6073 6074 /// Reproduce \p I with type \p Ty or return nullptr if that is not posisble. 6075 /// If \p Check is true we will only verify such an operation would suceed and 6076 /// return a non-nullptr value if that is the case. No IR is generated or 6077 /// modified. 6078 static Value *reproduceInst(Attributor &A, 6079 const AbstractAttribute &QueryingAA, 6080 Instruction &I, Type &Ty, Instruction *CtxI, 6081 bool Check, ValueToValueMapTy &VMap) { 6082 assert(CtxI && "Cannot reproduce an instruction without context!"); 6083 if (Check && (I.mayReadFromMemory() || 6084 !isSafeToSpeculativelyExecute(&I, CtxI, /* DT */ nullptr, 6085 /* TLI */ nullptr))) 6086 return nullptr; 6087 for (Value *Op : I.operands()) { 6088 Value *NewOp = reproduceValue(A, QueryingAA, *Op, Ty, CtxI, Check, VMap); 6089 if (!NewOp) { 6090 assert(Check && "Manifest of new value unexpectedly failed!"); 6091 return nullptr; 6092 } 6093 if (!Check) 6094 VMap[Op] = NewOp; 6095 } 6096 if (Check) 6097 return &I; 6098 6099 Instruction *CloneI = I.clone(); 6100 // TODO: Try to salvage debug information here. 6101 CloneI->setDebugLoc(DebugLoc()); 6102 VMap[&I] = CloneI; 6103 CloneI->insertBefore(CtxI); 6104 RemapInstruction(CloneI, VMap); 6105 return CloneI; 6106 } 6107 6108 /// Reproduce \p V with type \p Ty or return nullptr if that is not posisble. 6109 /// If \p Check is true we will only verify such an operation would suceed and 6110 /// return a non-nullptr value if that is the case. No IR is generated or 6111 /// modified. 6112 static Value *reproduceValue(Attributor &A, 6113 const AbstractAttribute &QueryingAA, Value &V, 6114 Type &Ty, Instruction *CtxI, bool Check, 6115 ValueToValueMapTy &VMap) { 6116 if (const auto &NewV = VMap.lookup(&V)) 6117 return NewV; 6118 bool UsedAssumedInformation = false; 6119 std::optional<Value *> SimpleV = A.getAssumedSimplified( 6120 V, QueryingAA, UsedAssumedInformation, AA::Interprocedural); 6121 if (!SimpleV.has_value()) 6122 return PoisonValue::get(&Ty); 6123 Value *EffectiveV = &V; 6124 if (*SimpleV) 6125 EffectiveV = *SimpleV; 6126 if (auto *C = dyn_cast<Constant>(EffectiveV)) 6127 return C; 6128 if (CtxI && AA::isValidAtPosition(AA::ValueAndContext(*EffectiveV, *CtxI), 6129 A.getInfoCache())) 6130 return ensureType(A, *EffectiveV, Ty, CtxI, Check); 6131 if (auto *I = dyn_cast<Instruction>(EffectiveV)) 6132 if (Value *NewV = reproduceInst(A, QueryingAA, *I, Ty, CtxI, Check, VMap)) 6133 return ensureType(A, *NewV, Ty, CtxI, Check); 6134 return nullptr; 6135 } 6136 6137 /// Return a value we can use as replacement for the associated one, or 6138 /// nullptr if we don't have one that makes sense. 6139 Value *manifestReplacementValue(Attributor &A, Instruction *CtxI) const { 6140 Value *NewV = SimplifiedAssociatedValue 6141 ? *SimplifiedAssociatedValue 6142 : UndefValue::get(getAssociatedType()); 6143 if (NewV && NewV != &getAssociatedValue()) { 6144 ValueToValueMapTy VMap; 6145 // First verify we can reprduce the value with the required type at the 6146 // context location before we actually start modifying the IR. 6147 if (reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI, 6148 /* CheckOnly */ true, VMap)) 6149 return reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI, 6150 /* CheckOnly */ false, VMap); 6151 } 6152 return nullptr; 6153 } 6154 6155 /// Helper function for querying AAValueSimplify and updating candidate. 6156 /// \param IRP The value position we are trying to unify with SimplifiedValue 6157 bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA, 6158 const IRPosition &IRP, bool Simplify = true) { 6159 bool UsedAssumedInformation = false; 6160 std::optional<Value *> QueryingValueSimplified = &IRP.getAssociatedValue(); 6161 if (Simplify) 6162 QueryingValueSimplified = A.getAssumedSimplified( 6163 IRP, QueryingAA, UsedAssumedInformation, AA::Interprocedural); 6164 return unionAssumed(QueryingValueSimplified); 6165 } 6166 6167 /// Returns a candidate is found or not 6168 template <typename AAType> bool askSimplifiedValueFor(Attributor &A) { 6169 if (!getAssociatedValue().getType()->isIntegerTy()) 6170 return false; 6171 6172 // This will also pass the call base context. 6173 const auto &AA = 6174 A.getAAFor<AAType>(*this, getIRPosition(), DepClassTy::NONE); 6175 6176 std::optional<Constant *> COpt = AA.getAssumedConstant(A); 6177 6178 if (!COpt) { 6179 SimplifiedAssociatedValue = std::nullopt; 6180 A.recordDependence(AA, *this, DepClassTy::OPTIONAL); 6181 return true; 6182 } 6183 if (auto *C = *COpt) { 6184 SimplifiedAssociatedValue = C; 6185 A.recordDependence(AA, *this, DepClassTy::OPTIONAL); 6186 return true; 6187 } 6188 return false; 6189 } 6190 6191 bool askSimplifiedValueForOtherAAs(Attributor &A) { 6192 if (askSimplifiedValueFor<AAValueConstantRange>(A)) 6193 return true; 6194 if (askSimplifiedValueFor<AAPotentialConstantValues>(A)) 6195 return true; 6196 return false; 6197 } 6198 6199 /// See AbstractAttribute::manifest(...). 6200 ChangeStatus manifest(Attributor &A) override { 6201 ChangeStatus Changed = ChangeStatus::UNCHANGED; 6202 for (auto &U : getAssociatedValue().uses()) { 6203 // Check if we need to adjust the insertion point to make sure the IR is 6204 // valid. 6205 Instruction *IP = dyn_cast<Instruction>(U.getUser()); 6206 if (auto *PHI = dyn_cast_or_null<PHINode>(IP)) 6207 IP = PHI->getIncomingBlock(U)->getTerminator(); 6208 if (auto *NewV = manifestReplacementValue(A, IP)) { 6209 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << getAssociatedValue() 6210 << " -> " << *NewV << " :: " << *this << "\n"); 6211 if (A.changeUseAfterManifest(U, *NewV)) 6212 Changed = ChangeStatus::CHANGED; 6213 } 6214 } 6215 6216 return Changed | AAValueSimplify::manifest(A); 6217 } 6218 6219 /// See AbstractState::indicatePessimisticFixpoint(...). 6220 ChangeStatus indicatePessimisticFixpoint() override { 6221 SimplifiedAssociatedValue = &getAssociatedValue(); 6222 return AAValueSimplify::indicatePessimisticFixpoint(); 6223 } 6224 }; 6225 6226 struct AAValueSimplifyArgument final : AAValueSimplifyImpl { 6227 AAValueSimplifyArgument(const IRPosition &IRP, Attributor &A) 6228 : AAValueSimplifyImpl(IRP, A) {} 6229 6230 void initialize(Attributor &A) override { 6231 AAValueSimplifyImpl::initialize(A); 6232 if (!getAnchorScope() || getAnchorScope()->isDeclaration()) 6233 indicatePessimisticFixpoint(); 6234 if (hasAttr({Attribute::InAlloca, Attribute::Preallocated, 6235 Attribute::StructRet, Attribute::Nest, Attribute::ByVal}, 6236 /* IgnoreSubsumingPositions */ true)) 6237 indicatePessimisticFixpoint(); 6238 } 6239 6240 /// See AbstractAttribute::updateImpl(...). 6241 ChangeStatus updateImpl(Attributor &A) override { 6242 // Byval is only replacable if it is readonly otherwise we would write into 6243 // the replaced value and not the copy that byval creates implicitly. 6244 Argument *Arg = getAssociatedArgument(); 6245 if (Arg->hasByValAttr()) { 6246 // TODO: We probably need to verify synchronization is not an issue, e.g., 6247 // there is no race by not copying a constant byval. 6248 bool IsKnown; 6249 if (!AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown)) 6250 return indicatePessimisticFixpoint(); 6251 } 6252 6253 auto Before = SimplifiedAssociatedValue; 6254 6255 auto PredForCallSite = [&](AbstractCallSite ACS) { 6256 const IRPosition &ACSArgPos = 6257 IRPosition::callsite_argument(ACS, getCallSiteArgNo()); 6258 // Check if a coresponding argument was found or if it is on not 6259 // associated (which can happen for callback calls). 6260 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID) 6261 return false; 6262 6263 // Simplify the argument operand explicitly and check if the result is 6264 // valid in the current scope. This avoids refering to simplified values 6265 // in other functions, e.g., we don't want to say a an argument in a 6266 // static function is actually an argument in a different function. 6267 bool UsedAssumedInformation = false; 6268 std::optional<Constant *> SimpleArgOp = 6269 A.getAssumedConstant(ACSArgPos, *this, UsedAssumedInformation); 6270 if (!SimpleArgOp) 6271 return true; 6272 if (!*SimpleArgOp) 6273 return false; 6274 if (!AA::isDynamicallyUnique(A, *this, **SimpleArgOp)) 6275 return false; 6276 return unionAssumed(*SimpleArgOp); 6277 }; 6278 6279 // Generate a answer specific to a call site context. 6280 bool Success; 6281 bool UsedAssumedInformation = false; 6282 if (hasCallBaseContext() && 6283 getCallBaseContext()->getCalledFunction() == Arg->getParent()) 6284 Success = PredForCallSite( 6285 AbstractCallSite(&getCallBaseContext()->getCalledOperandUse())); 6286 else 6287 Success = A.checkForAllCallSites(PredForCallSite, *this, true, 6288 UsedAssumedInformation); 6289 6290 if (!Success) 6291 if (!askSimplifiedValueForOtherAAs(A)) 6292 return indicatePessimisticFixpoint(); 6293 6294 // If a candidate was found in this update, return CHANGED. 6295 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED 6296 : ChangeStatus ::CHANGED; 6297 } 6298 6299 /// See AbstractAttribute::trackStatistics() 6300 void trackStatistics() const override { 6301 STATS_DECLTRACK_ARG_ATTR(value_simplify) 6302 } 6303 }; 6304 6305 struct AAValueSimplifyReturned : AAValueSimplifyImpl { 6306 AAValueSimplifyReturned(const IRPosition &IRP, Attributor &A) 6307 : AAValueSimplifyImpl(IRP, A) {} 6308 6309 /// See AAValueSimplify::getAssumedSimplifiedValue() 6310 std::optional<Value *> 6311 getAssumedSimplifiedValue(Attributor &A) const override { 6312 if (!isValidState()) 6313 return nullptr; 6314 return SimplifiedAssociatedValue; 6315 } 6316 6317 /// See AbstractAttribute::updateImpl(...). 6318 ChangeStatus updateImpl(Attributor &A) override { 6319 auto Before = SimplifiedAssociatedValue; 6320 6321 auto ReturnInstCB = [&](Instruction &I) { 6322 auto &RI = cast<ReturnInst>(I); 6323 return checkAndUpdate( 6324 A, *this, 6325 IRPosition::value(*RI.getReturnValue(), getCallBaseContext())); 6326 }; 6327 6328 bool UsedAssumedInformation = false; 6329 if (!A.checkForAllInstructions(ReturnInstCB, *this, {Instruction::Ret}, 6330 UsedAssumedInformation)) 6331 if (!askSimplifiedValueForOtherAAs(A)) 6332 return indicatePessimisticFixpoint(); 6333 6334 // If a candidate was found in this update, return CHANGED. 6335 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED 6336 : ChangeStatus ::CHANGED; 6337 } 6338 6339 ChangeStatus manifest(Attributor &A) override { 6340 // We queried AAValueSimplify for the returned values so they will be 6341 // replaced if a simplified form was found. Nothing to do here. 6342 return ChangeStatus::UNCHANGED; 6343 } 6344 6345 /// See AbstractAttribute::trackStatistics() 6346 void trackStatistics() const override { 6347 STATS_DECLTRACK_FNRET_ATTR(value_simplify) 6348 } 6349 }; 6350 6351 struct AAValueSimplifyFloating : AAValueSimplifyImpl { 6352 AAValueSimplifyFloating(const IRPosition &IRP, Attributor &A) 6353 : AAValueSimplifyImpl(IRP, A) {} 6354 6355 /// See AbstractAttribute::initialize(...). 6356 void initialize(Attributor &A) override { 6357 AAValueSimplifyImpl::initialize(A); 6358 Value &V = getAnchorValue(); 6359 6360 // TODO: add other stuffs 6361 if (isa<Constant>(V)) 6362 indicatePessimisticFixpoint(); 6363 } 6364 6365 /// See AbstractAttribute::updateImpl(...). 6366 ChangeStatus updateImpl(Attributor &A) override { 6367 auto Before = SimplifiedAssociatedValue; 6368 if (!askSimplifiedValueForOtherAAs(A)) 6369 return indicatePessimisticFixpoint(); 6370 6371 // If a candidate was found in this update, return CHANGED. 6372 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED 6373 : ChangeStatus ::CHANGED; 6374 } 6375 6376 /// See AbstractAttribute::trackStatistics() 6377 void trackStatistics() const override { 6378 STATS_DECLTRACK_FLOATING_ATTR(value_simplify) 6379 } 6380 }; 6381 6382 struct AAValueSimplifyFunction : AAValueSimplifyImpl { 6383 AAValueSimplifyFunction(const IRPosition &IRP, Attributor &A) 6384 : AAValueSimplifyImpl(IRP, A) {} 6385 6386 /// See AbstractAttribute::initialize(...). 6387 void initialize(Attributor &A) override { 6388 SimplifiedAssociatedValue = nullptr; 6389 indicateOptimisticFixpoint(); 6390 } 6391 /// See AbstractAttribute::initialize(...). 6392 ChangeStatus updateImpl(Attributor &A) override { 6393 llvm_unreachable( 6394 "AAValueSimplify(Function|CallSite)::updateImpl will not be called"); 6395 } 6396 /// See AbstractAttribute::trackStatistics() 6397 void trackStatistics() const override { 6398 STATS_DECLTRACK_FN_ATTR(value_simplify) 6399 } 6400 }; 6401 6402 struct AAValueSimplifyCallSite : AAValueSimplifyFunction { 6403 AAValueSimplifyCallSite(const IRPosition &IRP, Attributor &A) 6404 : AAValueSimplifyFunction(IRP, A) {} 6405 /// See AbstractAttribute::trackStatistics() 6406 void trackStatistics() const override { 6407 STATS_DECLTRACK_CS_ATTR(value_simplify) 6408 } 6409 }; 6410 6411 struct AAValueSimplifyCallSiteReturned : AAValueSimplifyImpl { 6412 AAValueSimplifyCallSiteReturned(const IRPosition &IRP, Attributor &A) 6413 : AAValueSimplifyImpl(IRP, A) {} 6414 6415 void initialize(Attributor &A) override { 6416 AAValueSimplifyImpl::initialize(A); 6417 Function *Fn = getAssociatedFunction(); 6418 if (!Fn) { 6419 indicatePessimisticFixpoint(); 6420 return; 6421 } 6422 for (Argument &Arg : Fn->args()) { 6423 if (Arg.hasReturnedAttr()) { 6424 auto IRP = IRPosition::callsite_argument(*cast<CallBase>(getCtxI()), 6425 Arg.getArgNo()); 6426 if (IRP.getPositionKind() == IRPosition::IRP_CALL_SITE_ARGUMENT && 6427 checkAndUpdate(A, *this, IRP)) 6428 indicateOptimisticFixpoint(); 6429 else 6430 indicatePessimisticFixpoint(); 6431 return; 6432 } 6433 } 6434 } 6435 6436 /// See AbstractAttribute::updateImpl(...). 6437 ChangeStatus updateImpl(Attributor &A) override { 6438 auto Before = SimplifiedAssociatedValue; 6439 auto &RetAA = A.getAAFor<AAReturnedValues>( 6440 *this, IRPosition::function(*getAssociatedFunction()), 6441 DepClassTy::REQUIRED); 6442 auto PredForReturned = 6443 [&](Value &RetVal, const SmallSetVector<ReturnInst *, 4> &RetInsts) { 6444 bool UsedAssumedInformation = false; 6445 std::optional<Value *> CSRetVal = 6446 A.translateArgumentToCallSiteContent( 6447 &RetVal, *cast<CallBase>(getCtxI()), *this, 6448 UsedAssumedInformation); 6449 SimplifiedAssociatedValue = AA::combineOptionalValuesInAAValueLatice( 6450 SimplifiedAssociatedValue, CSRetVal, getAssociatedType()); 6451 return SimplifiedAssociatedValue != std::optional<Value *>(nullptr); 6452 }; 6453 if (!RetAA.checkForAllReturnedValuesAndReturnInsts(PredForReturned)) 6454 if (!askSimplifiedValueForOtherAAs(A)) 6455 return indicatePessimisticFixpoint(); 6456 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED 6457 : ChangeStatus ::CHANGED; 6458 } 6459 6460 void trackStatistics() const override { 6461 STATS_DECLTRACK_CSRET_ATTR(value_simplify) 6462 } 6463 }; 6464 6465 struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating { 6466 AAValueSimplifyCallSiteArgument(const IRPosition &IRP, Attributor &A) 6467 : AAValueSimplifyFloating(IRP, A) {} 6468 6469 /// See AbstractAttribute::manifest(...). 6470 ChangeStatus manifest(Attributor &A) override { 6471 ChangeStatus Changed = ChangeStatus::UNCHANGED; 6472 // TODO: We should avoid simplification duplication to begin with. 6473 auto *FloatAA = A.lookupAAFor<AAValueSimplify>( 6474 IRPosition::value(getAssociatedValue()), this, DepClassTy::NONE); 6475 if (FloatAA && FloatAA->getState().isValidState()) 6476 return Changed; 6477 6478 if (auto *NewV = manifestReplacementValue(A, getCtxI())) { 6479 Use &U = cast<CallBase>(&getAnchorValue()) 6480 ->getArgOperandUse(getCallSiteArgNo()); 6481 if (A.changeUseAfterManifest(U, *NewV)) 6482 Changed = ChangeStatus::CHANGED; 6483 } 6484 6485 return Changed | AAValueSimplify::manifest(A); 6486 } 6487 6488 void trackStatistics() const override { 6489 STATS_DECLTRACK_CSARG_ATTR(value_simplify) 6490 } 6491 }; 6492 } // namespace 6493 6494 /// ----------------------- Heap-To-Stack Conversion --------------------------- 6495 namespace { 6496 struct AAHeapToStackFunction final : public AAHeapToStack { 6497 6498 struct AllocationInfo { 6499 /// The call that allocates the memory. 6500 CallBase *const CB; 6501 6502 /// The library function id for the allocation. 6503 LibFunc LibraryFunctionId = NotLibFunc; 6504 6505 /// The status wrt. a rewrite. 6506 enum { 6507 STACK_DUE_TO_USE, 6508 STACK_DUE_TO_FREE, 6509 INVALID, 6510 } Status = STACK_DUE_TO_USE; 6511 6512 /// Flag to indicate if we encountered a use that might free this allocation 6513 /// but which is not in the deallocation infos. 6514 bool HasPotentiallyFreeingUnknownUses = false; 6515 6516 /// Flag to indicate that we should place the new alloca in the function 6517 /// entry block rather than where the call site (CB) is. 6518 bool MoveAllocaIntoEntry = true; 6519 6520 /// The set of free calls that use this allocation. 6521 SmallSetVector<CallBase *, 1> PotentialFreeCalls{}; 6522 }; 6523 6524 struct DeallocationInfo { 6525 /// The call that deallocates the memory. 6526 CallBase *const CB; 6527 /// The value freed by the call. 6528 Value *FreedOp; 6529 6530 /// Flag to indicate if we don't know all objects this deallocation might 6531 /// free. 6532 bool MightFreeUnknownObjects = false; 6533 6534 /// The set of allocation calls that are potentially freed. 6535 SmallSetVector<CallBase *, 1> PotentialAllocationCalls{}; 6536 }; 6537 6538 AAHeapToStackFunction(const IRPosition &IRP, Attributor &A) 6539 : AAHeapToStack(IRP, A) {} 6540 6541 ~AAHeapToStackFunction() { 6542 // Ensure we call the destructor so we release any memory allocated in the 6543 // sets. 6544 for (auto &It : AllocationInfos) 6545 It.second->~AllocationInfo(); 6546 for (auto &It : DeallocationInfos) 6547 It.second->~DeallocationInfo(); 6548 } 6549 6550 void initialize(Attributor &A) override { 6551 AAHeapToStack::initialize(A); 6552 6553 const Function *F = getAnchorScope(); 6554 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F); 6555 6556 auto AllocationIdentifierCB = [&](Instruction &I) { 6557 CallBase *CB = dyn_cast<CallBase>(&I); 6558 if (!CB) 6559 return true; 6560 if (Value *FreedOp = getFreedOperand(CB, TLI)) { 6561 DeallocationInfos[CB] = new (A.Allocator) DeallocationInfo{CB, FreedOp}; 6562 return true; 6563 } 6564 // To do heap to stack, we need to know that the allocation itself is 6565 // removable once uses are rewritten, and that we can initialize the 6566 // alloca to the same pattern as the original allocation result. 6567 if (isRemovableAlloc(CB, TLI)) { 6568 auto *I8Ty = Type::getInt8Ty(CB->getParent()->getContext()); 6569 if (nullptr != getInitialValueOfAllocation(CB, TLI, I8Ty)) { 6570 AllocationInfo *AI = new (A.Allocator) AllocationInfo{CB}; 6571 AllocationInfos[CB] = AI; 6572 if (TLI) 6573 TLI->getLibFunc(*CB, AI->LibraryFunctionId); 6574 } 6575 } 6576 return true; 6577 }; 6578 6579 bool UsedAssumedInformation = false; 6580 bool Success = A.checkForAllCallLikeInstructions( 6581 AllocationIdentifierCB, *this, UsedAssumedInformation, 6582 /* CheckBBLivenessOnly */ false, 6583 /* CheckPotentiallyDead */ true); 6584 (void)Success; 6585 assert(Success && "Did not expect the call base visit callback to fail!"); 6586 6587 Attributor::SimplifictionCallbackTy SCB = 6588 [](const IRPosition &, const AbstractAttribute *, 6589 bool &) -> std::optional<Value *> { return nullptr; }; 6590 for (const auto &It : AllocationInfos) 6591 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first), 6592 SCB); 6593 for (const auto &It : DeallocationInfos) 6594 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first), 6595 SCB); 6596 } 6597 6598 const std::string getAsStr() const override { 6599 unsigned NumH2SMallocs = 0, NumInvalidMallocs = 0; 6600 for (const auto &It : AllocationInfos) { 6601 if (It.second->Status == AllocationInfo::INVALID) 6602 ++NumInvalidMallocs; 6603 else 6604 ++NumH2SMallocs; 6605 } 6606 return "[H2S] Mallocs Good/Bad: " + std::to_string(NumH2SMallocs) + "/" + 6607 std::to_string(NumInvalidMallocs); 6608 } 6609 6610 /// See AbstractAttribute::trackStatistics(). 6611 void trackStatistics() const override { 6612 STATS_DECL( 6613 MallocCalls, Function, 6614 "Number of malloc/calloc/aligned_alloc calls converted to allocas"); 6615 for (const auto &It : AllocationInfos) 6616 if (It.second->Status != AllocationInfo::INVALID) 6617 ++BUILD_STAT_NAME(MallocCalls, Function); 6618 } 6619 6620 bool isAssumedHeapToStack(const CallBase &CB) const override { 6621 if (isValidState()) 6622 if (AllocationInfo *AI = 6623 AllocationInfos.lookup(const_cast<CallBase *>(&CB))) 6624 return AI->Status != AllocationInfo::INVALID; 6625 return false; 6626 } 6627 6628 bool isAssumedHeapToStackRemovedFree(CallBase &CB) const override { 6629 if (!isValidState()) 6630 return false; 6631 6632 for (const auto &It : AllocationInfos) { 6633 AllocationInfo &AI = *It.second; 6634 if (AI.Status == AllocationInfo::INVALID) 6635 continue; 6636 6637 if (AI.PotentialFreeCalls.count(&CB)) 6638 return true; 6639 } 6640 6641 return false; 6642 } 6643 6644 ChangeStatus manifest(Attributor &A) override { 6645 assert(getState().isValidState() && 6646 "Attempted to manifest an invalid state!"); 6647 6648 ChangeStatus HasChanged = ChangeStatus::UNCHANGED; 6649 Function *F = getAnchorScope(); 6650 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F); 6651 6652 for (auto &It : AllocationInfos) { 6653 AllocationInfo &AI = *It.second; 6654 if (AI.Status == AllocationInfo::INVALID) 6655 continue; 6656 6657 for (CallBase *FreeCall : AI.PotentialFreeCalls) { 6658 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n"); 6659 A.deleteAfterManifest(*FreeCall); 6660 HasChanged = ChangeStatus::CHANGED; 6661 } 6662 6663 LLVM_DEBUG(dbgs() << "H2S: Removing malloc-like call: " << *AI.CB 6664 << "\n"); 6665 6666 auto Remark = [&](OptimizationRemark OR) { 6667 LibFunc IsAllocShared; 6668 if (TLI->getLibFunc(*AI.CB, IsAllocShared)) 6669 if (IsAllocShared == LibFunc___kmpc_alloc_shared) 6670 return OR << "Moving globalized variable to the stack."; 6671 return OR << "Moving memory allocation from the heap to the stack."; 6672 }; 6673 if (AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared) 6674 A.emitRemark<OptimizationRemark>(AI.CB, "OMP110", Remark); 6675 else 6676 A.emitRemark<OptimizationRemark>(AI.CB, "HeapToStack", Remark); 6677 6678 const DataLayout &DL = A.getInfoCache().getDL(); 6679 Value *Size; 6680 std::optional<APInt> SizeAPI = getSize(A, *this, AI); 6681 if (SizeAPI) { 6682 Size = ConstantInt::get(AI.CB->getContext(), *SizeAPI); 6683 } else { 6684 LLVMContext &Ctx = AI.CB->getContext(); 6685 ObjectSizeOpts Opts; 6686 ObjectSizeOffsetEvaluator Eval(DL, TLI, Ctx, Opts); 6687 SizeOffsetEvalType SizeOffsetPair = Eval.compute(AI.CB); 6688 assert(SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown() && 6689 cast<ConstantInt>(SizeOffsetPair.second)->isZero()); 6690 Size = SizeOffsetPair.first; 6691 } 6692 6693 Instruction *IP = 6694 AI.MoveAllocaIntoEntry ? &F->getEntryBlock().front() : AI.CB; 6695 6696 Align Alignment(1); 6697 if (MaybeAlign RetAlign = AI.CB->getRetAlign()) 6698 Alignment = std::max(Alignment, *RetAlign); 6699 if (Value *Align = getAllocAlignment(AI.CB, TLI)) { 6700 std::optional<APInt> AlignmentAPI = getAPInt(A, *this, *Align); 6701 assert(AlignmentAPI && AlignmentAPI->getZExtValue() > 0 && 6702 "Expected an alignment during manifest!"); 6703 Alignment = 6704 std::max(Alignment, assumeAligned(AlignmentAPI->getZExtValue())); 6705 } 6706 6707 // TODO: Hoist the alloca towards the function entry. 6708 unsigned AS = DL.getAllocaAddrSpace(); 6709 Instruction *Alloca = 6710 new AllocaInst(Type::getInt8Ty(F->getContext()), AS, Size, Alignment, 6711 AI.CB->getName() + ".h2s", IP); 6712 6713 if (Alloca->getType() != AI.CB->getType()) 6714 Alloca = BitCastInst::CreatePointerBitCastOrAddrSpaceCast( 6715 Alloca, AI.CB->getType(), "malloc_cast", AI.CB); 6716 6717 auto *I8Ty = Type::getInt8Ty(F->getContext()); 6718 auto *InitVal = getInitialValueOfAllocation(AI.CB, TLI, I8Ty); 6719 assert(InitVal && 6720 "Must be able to materialize initial memory state of allocation"); 6721 6722 A.changeAfterManifest(IRPosition::inst(*AI.CB), *Alloca); 6723 6724 if (auto *II = dyn_cast<InvokeInst>(AI.CB)) { 6725 auto *NBB = II->getNormalDest(); 6726 BranchInst::Create(NBB, AI.CB->getParent()); 6727 A.deleteAfterManifest(*AI.CB); 6728 } else { 6729 A.deleteAfterManifest(*AI.CB); 6730 } 6731 6732 // Initialize the alloca with the same value as used by the allocation 6733 // function. We can skip undef as the initial value of an alloc is 6734 // undef, and the memset would simply end up being DSEd. 6735 if (!isa<UndefValue>(InitVal)) { 6736 IRBuilder<> Builder(Alloca->getNextNode()); 6737 // TODO: Use alignment above if align!=1 6738 Builder.CreateMemSet(Alloca, InitVal, Size, std::nullopt); 6739 } 6740 HasChanged = ChangeStatus::CHANGED; 6741 } 6742 6743 return HasChanged; 6744 } 6745 6746 std::optional<APInt> getAPInt(Attributor &A, const AbstractAttribute &AA, 6747 Value &V) { 6748 bool UsedAssumedInformation = false; 6749 std::optional<Constant *> SimpleV = 6750 A.getAssumedConstant(V, AA, UsedAssumedInformation); 6751 if (!SimpleV) 6752 return APInt(64, 0); 6753 if (auto *CI = dyn_cast_or_null<ConstantInt>(*SimpleV)) 6754 return CI->getValue(); 6755 return std::nullopt; 6756 } 6757 6758 std::optional<APInt> getSize(Attributor &A, const AbstractAttribute &AA, 6759 AllocationInfo &AI) { 6760 auto Mapper = [&](const Value *V) -> const Value * { 6761 bool UsedAssumedInformation = false; 6762 if (std::optional<Constant *> SimpleV = 6763 A.getAssumedConstant(*V, AA, UsedAssumedInformation)) 6764 if (*SimpleV) 6765 return *SimpleV; 6766 return V; 6767 }; 6768 6769 const Function *F = getAnchorScope(); 6770 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F); 6771 return getAllocSize(AI.CB, TLI, Mapper); 6772 } 6773 6774 /// Collection of all malloc-like calls in a function with associated 6775 /// information. 6776 MapVector<CallBase *, AllocationInfo *> AllocationInfos; 6777 6778 /// Collection of all free-like calls in a function with associated 6779 /// information. 6780 MapVector<CallBase *, DeallocationInfo *> DeallocationInfos; 6781 6782 ChangeStatus updateImpl(Attributor &A) override; 6783 }; 6784 6785 ChangeStatus AAHeapToStackFunction::updateImpl(Attributor &A) { 6786 ChangeStatus Changed = ChangeStatus::UNCHANGED; 6787 const Function *F = getAnchorScope(); 6788 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F); 6789 6790 const auto &LivenessAA = 6791 A.getAAFor<AAIsDead>(*this, IRPosition::function(*F), DepClassTy::NONE); 6792 6793 MustBeExecutedContextExplorer &Explorer = 6794 A.getInfoCache().getMustBeExecutedContextExplorer(); 6795 6796 bool StackIsAccessibleByOtherThreads = 6797 A.getInfoCache().stackIsAccessibleByOtherThreads(); 6798 6799 LoopInfo *LI = 6800 A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(*F); 6801 std::optional<bool> MayContainIrreducibleControl; 6802 auto IsInLoop = [&](BasicBlock &BB) { 6803 if (&F->getEntryBlock() == &BB) 6804 return false; 6805 if (!MayContainIrreducibleControl.has_value()) 6806 MayContainIrreducibleControl = mayContainIrreducibleControl(*F, LI); 6807 if (*MayContainIrreducibleControl) 6808 return true; 6809 if (!LI) 6810 return true; 6811 return LI->getLoopFor(&BB) != nullptr; 6812 }; 6813 6814 // Flag to ensure we update our deallocation information at most once per 6815 // updateImpl call and only if we use the free check reasoning. 6816 bool HasUpdatedFrees = false; 6817 6818 auto UpdateFrees = [&]() { 6819 HasUpdatedFrees = true; 6820 6821 for (auto &It : DeallocationInfos) { 6822 DeallocationInfo &DI = *It.second; 6823 // For now we cannot use deallocations that have unknown inputs, skip 6824 // them. 6825 if (DI.MightFreeUnknownObjects) 6826 continue; 6827 6828 // No need to analyze dead calls, ignore them instead. 6829 bool UsedAssumedInformation = false; 6830 if (A.isAssumedDead(*DI.CB, this, &LivenessAA, UsedAssumedInformation, 6831 /* CheckBBLivenessOnly */ true)) 6832 continue; 6833 6834 // Use the non-optimistic version to get the freed object. 6835 Value *Obj = getUnderlyingObject(DI.FreedOp); 6836 if (!Obj) { 6837 LLVM_DEBUG(dbgs() << "[H2S] Unknown underlying object for free!\n"); 6838 DI.MightFreeUnknownObjects = true; 6839 continue; 6840 } 6841 6842 // Free of null and undef can be ignored as no-ops (or UB in the latter 6843 // case). 6844 if (isa<ConstantPointerNull>(Obj) || isa<UndefValue>(Obj)) 6845 continue; 6846 6847 CallBase *ObjCB = dyn_cast<CallBase>(Obj); 6848 if (!ObjCB) { 6849 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-call object: " << *Obj 6850 << "\n"); 6851 DI.MightFreeUnknownObjects = true; 6852 continue; 6853 } 6854 6855 AllocationInfo *AI = AllocationInfos.lookup(ObjCB); 6856 if (!AI) { 6857 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-allocation object: " << *Obj 6858 << "\n"); 6859 DI.MightFreeUnknownObjects = true; 6860 continue; 6861 } 6862 6863 DI.PotentialAllocationCalls.insert(ObjCB); 6864 } 6865 }; 6866 6867 auto FreeCheck = [&](AllocationInfo &AI) { 6868 // If the stack is not accessible by other threads, the "must-free" logic 6869 // doesn't apply as the pointer could be shared and needs to be places in 6870 // "shareable" memory. 6871 if (!StackIsAccessibleByOtherThreads) { 6872 auto &NoSyncAA = 6873 A.getAAFor<AANoSync>(*this, getIRPosition(), DepClassTy::OPTIONAL); 6874 if (!NoSyncAA.isAssumedNoSync()) { 6875 LLVM_DEBUG( 6876 dbgs() << "[H2S] found an escaping use, stack is not accessible by " 6877 "other threads and function is not nosync:\n"); 6878 return false; 6879 } 6880 } 6881 if (!HasUpdatedFrees) 6882 UpdateFrees(); 6883 6884 // TODO: Allow multi exit functions that have different free calls. 6885 if (AI.PotentialFreeCalls.size() != 1) { 6886 LLVM_DEBUG(dbgs() << "[H2S] did not find one free call but " 6887 << AI.PotentialFreeCalls.size() << "\n"); 6888 return false; 6889 } 6890 CallBase *UniqueFree = *AI.PotentialFreeCalls.begin(); 6891 DeallocationInfo *DI = DeallocationInfos.lookup(UniqueFree); 6892 if (!DI) { 6893 LLVM_DEBUG( 6894 dbgs() << "[H2S] unique free call was not known as deallocation call " 6895 << *UniqueFree << "\n"); 6896 return false; 6897 } 6898 if (DI->MightFreeUnknownObjects) { 6899 LLVM_DEBUG( 6900 dbgs() << "[H2S] unique free call might free unknown allocations\n"); 6901 return false; 6902 } 6903 if (DI->PotentialAllocationCalls.empty()) 6904 return true; 6905 if (DI->PotentialAllocationCalls.size() > 1) { 6906 LLVM_DEBUG(dbgs() << "[H2S] unique free call might free " 6907 << DI->PotentialAllocationCalls.size() 6908 << " different allocations\n"); 6909 return false; 6910 } 6911 if (*DI->PotentialAllocationCalls.begin() != AI.CB) { 6912 LLVM_DEBUG( 6913 dbgs() 6914 << "[H2S] unique free call not known to free this allocation but " 6915 << **DI->PotentialAllocationCalls.begin() << "\n"); 6916 return false; 6917 } 6918 Instruction *CtxI = isa<InvokeInst>(AI.CB) ? AI.CB : AI.CB->getNextNode(); 6919 if (!Explorer.findInContextOf(UniqueFree, CtxI)) { 6920 LLVM_DEBUG( 6921 dbgs() 6922 << "[H2S] unique free call might not be executed with the allocation " 6923 << *UniqueFree << "\n"); 6924 return false; 6925 } 6926 return true; 6927 }; 6928 6929 auto UsesCheck = [&](AllocationInfo &AI) { 6930 bool ValidUsesOnly = true; 6931 6932 auto Pred = [&](const Use &U, bool &Follow) -> bool { 6933 Instruction *UserI = cast<Instruction>(U.getUser()); 6934 if (isa<LoadInst>(UserI)) 6935 return true; 6936 if (auto *SI = dyn_cast<StoreInst>(UserI)) { 6937 if (SI->getValueOperand() == U.get()) { 6938 LLVM_DEBUG(dbgs() 6939 << "[H2S] escaping store to memory: " << *UserI << "\n"); 6940 ValidUsesOnly = false; 6941 } else { 6942 // A store into the malloc'ed memory is fine. 6943 } 6944 return true; 6945 } 6946 if (auto *CB = dyn_cast<CallBase>(UserI)) { 6947 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd()) 6948 return true; 6949 if (DeallocationInfos.count(CB)) { 6950 AI.PotentialFreeCalls.insert(CB); 6951 return true; 6952 } 6953 6954 unsigned ArgNo = CB->getArgOperandNo(&U); 6955 6956 const auto &NoCaptureAA = A.getAAFor<AANoCapture>( 6957 *this, IRPosition::callsite_argument(*CB, ArgNo), 6958 DepClassTy::OPTIONAL); 6959 6960 // If a call site argument use is nofree, we are fine. 6961 const auto &ArgNoFreeAA = A.getAAFor<AANoFree>( 6962 *this, IRPosition::callsite_argument(*CB, ArgNo), 6963 DepClassTy::OPTIONAL); 6964 6965 bool MaybeCaptured = !NoCaptureAA.isAssumedNoCapture(); 6966 bool MaybeFreed = !ArgNoFreeAA.isAssumedNoFree(); 6967 if (MaybeCaptured || 6968 (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared && 6969 MaybeFreed)) { 6970 AI.HasPotentiallyFreeingUnknownUses |= MaybeFreed; 6971 6972 // Emit a missed remark if this is missed OpenMP globalization. 6973 auto Remark = [&](OptimizationRemarkMissed ORM) { 6974 return ORM 6975 << "Could not move globalized variable to the stack. " 6976 "Variable is potentially captured in call. Mark " 6977 "parameter as `__attribute__((noescape))` to override."; 6978 }; 6979 6980 if (ValidUsesOnly && 6981 AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared) 6982 A.emitRemark<OptimizationRemarkMissed>(CB, "OMP113", Remark); 6983 6984 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n"); 6985 ValidUsesOnly = false; 6986 } 6987 return true; 6988 } 6989 6990 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) || 6991 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) { 6992 Follow = true; 6993 return true; 6994 } 6995 // Unknown user for which we can not track uses further (in a way that 6996 // makes sense). 6997 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n"); 6998 ValidUsesOnly = false; 6999 return true; 7000 }; 7001 if (!A.checkForAllUses(Pred, *this, *AI.CB)) 7002 return false; 7003 return ValidUsesOnly; 7004 }; 7005 7006 // The actual update starts here. We look at all allocations and depending on 7007 // their status perform the appropriate check(s). 7008 for (auto &It : AllocationInfos) { 7009 AllocationInfo &AI = *It.second; 7010 if (AI.Status == AllocationInfo::INVALID) 7011 continue; 7012 7013 if (Value *Align = getAllocAlignment(AI.CB, TLI)) { 7014 std::optional<APInt> APAlign = getAPInt(A, *this, *Align); 7015 if (!APAlign) { 7016 // Can't generate an alloca which respects the required alignment 7017 // on the allocation. 7018 LLVM_DEBUG(dbgs() << "[H2S] Unknown allocation alignment: " << *AI.CB 7019 << "\n"); 7020 AI.Status = AllocationInfo::INVALID; 7021 Changed = ChangeStatus::CHANGED; 7022 continue; 7023 } 7024 if (APAlign->ugt(llvm::Value::MaximumAlignment) || 7025 !APAlign->isPowerOf2()) { 7026 LLVM_DEBUG(dbgs() << "[H2S] Invalid allocation alignment: " << APAlign 7027 << "\n"); 7028 AI.Status = AllocationInfo::INVALID; 7029 Changed = ChangeStatus::CHANGED; 7030 continue; 7031 } 7032 } 7033 7034 std::optional<APInt> Size = getSize(A, *this, AI); 7035 if (MaxHeapToStackSize != -1) { 7036 if (!Size || Size->ugt(MaxHeapToStackSize)) { 7037 LLVM_DEBUG({ 7038 if (!Size) 7039 dbgs() << "[H2S] Unknown allocation size: " << *AI.CB << "\n"; 7040 else 7041 dbgs() << "[H2S] Allocation size too large: " << *AI.CB << " vs. " 7042 << MaxHeapToStackSize << "\n"; 7043 }); 7044 7045 AI.Status = AllocationInfo::INVALID; 7046 Changed = ChangeStatus::CHANGED; 7047 continue; 7048 } 7049 } 7050 7051 switch (AI.Status) { 7052 case AllocationInfo::STACK_DUE_TO_USE: 7053 if (UsesCheck(AI)) 7054 break; 7055 AI.Status = AllocationInfo::STACK_DUE_TO_FREE; 7056 [[fallthrough]]; 7057 case AllocationInfo::STACK_DUE_TO_FREE: 7058 if (FreeCheck(AI)) 7059 break; 7060 AI.Status = AllocationInfo::INVALID; 7061 Changed = ChangeStatus::CHANGED; 7062 break; 7063 case AllocationInfo::INVALID: 7064 llvm_unreachable("Invalid allocations should never reach this point!"); 7065 }; 7066 7067 // Check if we still think we can move it into the entry block. If the 7068 // alloca comes from a converted __kmpc_alloc_shared then we can usually 7069 // ignore the potential compilations associated with loops. 7070 bool IsGlobalizedLocal = 7071 AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared; 7072 if (AI.MoveAllocaIntoEntry && 7073 (!Size.has_value() || 7074 (!IsGlobalizedLocal && IsInLoop(*AI.CB->getParent())))) 7075 AI.MoveAllocaIntoEntry = false; 7076 } 7077 7078 return Changed; 7079 } 7080 } // namespace 7081 7082 /// ----------------------- Privatizable Pointers ------------------------------ 7083 namespace { 7084 struct AAPrivatizablePtrImpl : public AAPrivatizablePtr { 7085 AAPrivatizablePtrImpl(const IRPosition &IRP, Attributor &A) 7086 : AAPrivatizablePtr(IRP, A), PrivatizableType(std::nullopt) {} 7087 7088 ChangeStatus indicatePessimisticFixpoint() override { 7089 AAPrivatizablePtr::indicatePessimisticFixpoint(); 7090 PrivatizableType = nullptr; 7091 return ChangeStatus::CHANGED; 7092 } 7093 7094 /// Identify the type we can chose for a private copy of the underlying 7095 /// argument. None means it is not clear yet, nullptr means there is none. 7096 virtual std::optional<Type *> identifyPrivatizableType(Attributor &A) = 0; 7097 7098 /// Return a privatizable type that encloses both T0 and T1. 7099 /// TODO: This is merely a stub for now as we should manage a mapping as well. 7100 std::optional<Type *> combineTypes(std::optional<Type *> T0, 7101 std::optional<Type *> T1) { 7102 if (!T0) 7103 return T1; 7104 if (!T1) 7105 return T0; 7106 if (T0 == T1) 7107 return T0; 7108 return nullptr; 7109 } 7110 7111 std::optional<Type *> getPrivatizableType() const override { 7112 return PrivatizableType; 7113 } 7114 7115 const std::string getAsStr() const override { 7116 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]"; 7117 } 7118 7119 protected: 7120 std::optional<Type *> PrivatizableType; 7121 }; 7122 7123 // TODO: Do this for call site arguments (probably also other values) as well. 7124 7125 struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl { 7126 AAPrivatizablePtrArgument(const IRPosition &IRP, Attributor &A) 7127 : AAPrivatizablePtrImpl(IRP, A) {} 7128 7129 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...) 7130 std::optional<Type *> identifyPrivatizableType(Attributor &A) override { 7131 // If this is a byval argument and we know all the call sites (so we can 7132 // rewrite them), there is no need to check them explicitly. 7133 bool UsedAssumedInformation = false; 7134 SmallVector<Attribute, 1> Attrs; 7135 getAttrs({Attribute::ByVal}, Attrs, /* IgnoreSubsumingPositions */ true); 7136 if (!Attrs.empty() && 7137 A.checkForAllCallSites([](AbstractCallSite ACS) { return true; }, *this, 7138 true, UsedAssumedInformation)) 7139 return Attrs[0].getValueAsType(); 7140 7141 std::optional<Type *> Ty; 7142 unsigned ArgNo = getIRPosition().getCallSiteArgNo(); 7143 7144 // Make sure the associated call site argument has the same type at all call 7145 // sites and it is an allocation we know is safe to privatize, for now that 7146 // means we only allow alloca instructions. 7147 // TODO: We can additionally analyze the accesses in the callee to create 7148 // the type from that information instead. That is a little more 7149 // involved and will be done in a follow up patch. 7150 auto CallSiteCheck = [&](AbstractCallSite ACS) { 7151 IRPosition ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo); 7152 // Check if a coresponding argument was found or if it is one not 7153 // associated (which can happen for callback calls). 7154 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID) 7155 return false; 7156 7157 // Check that all call sites agree on a type. 7158 auto &PrivCSArgAA = 7159 A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos, DepClassTy::REQUIRED); 7160 std::optional<Type *> CSTy = PrivCSArgAA.getPrivatizableType(); 7161 7162 LLVM_DEBUG({ 7163 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: "; 7164 if (CSTy && *CSTy) 7165 (*CSTy)->print(dbgs()); 7166 else if (CSTy) 7167 dbgs() << "<nullptr>"; 7168 else 7169 dbgs() << "<none>"; 7170 }); 7171 7172 Ty = combineTypes(Ty, CSTy); 7173 7174 LLVM_DEBUG({ 7175 dbgs() << " : New Type: "; 7176 if (Ty && *Ty) 7177 (*Ty)->print(dbgs()); 7178 else if (Ty) 7179 dbgs() << "<nullptr>"; 7180 else 7181 dbgs() << "<none>"; 7182 dbgs() << "\n"; 7183 }); 7184 7185 return !Ty || *Ty; 7186 }; 7187 7188 if (!A.checkForAllCallSites(CallSiteCheck, *this, true, 7189 UsedAssumedInformation)) 7190 return nullptr; 7191 return Ty; 7192 } 7193 7194 /// See AbstractAttribute::updateImpl(...). 7195 ChangeStatus updateImpl(Attributor &A) override { 7196 PrivatizableType = identifyPrivatizableType(A); 7197 if (!PrivatizableType) 7198 return ChangeStatus::UNCHANGED; 7199 if (!*PrivatizableType) 7200 return indicatePessimisticFixpoint(); 7201 7202 // The dependence is optional so we don't give up once we give up on the 7203 // alignment. 7204 A.getAAFor<AAAlign>(*this, IRPosition::value(getAssociatedValue()), 7205 DepClassTy::OPTIONAL); 7206 7207 // Avoid arguments with padding for now. 7208 if (!getIRPosition().hasAttr(Attribute::ByVal) && 7209 !isDenselyPacked(*PrivatizableType, A.getInfoCache().getDL())) { 7210 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n"); 7211 return indicatePessimisticFixpoint(); 7212 } 7213 7214 // Collect the types that will replace the privatizable type in the function 7215 // signature. 7216 SmallVector<Type *, 16> ReplacementTypes; 7217 identifyReplacementTypes(*PrivatizableType, ReplacementTypes); 7218 7219 // Verify callee and caller agree on how the promoted argument would be 7220 // passed. 7221 Function &Fn = *getIRPosition().getAnchorScope(); 7222 const auto *TTI = 7223 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn); 7224 if (!TTI) { 7225 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Missing TTI for function " 7226 << Fn.getName() << "\n"); 7227 return indicatePessimisticFixpoint(); 7228 } 7229 7230 auto CallSiteCheck = [&](AbstractCallSite ACS) { 7231 CallBase *CB = ACS.getInstruction(); 7232 return TTI->areTypesABICompatible( 7233 CB->getCaller(), CB->getCalledFunction(), ReplacementTypes); 7234 }; 7235 bool UsedAssumedInformation = false; 7236 if (!A.checkForAllCallSites(CallSiteCheck, *this, true, 7237 UsedAssumedInformation)) { 7238 LLVM_DEBUG( 7239 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for " 7240 << Fn.getName() << "\n"); 7241 return indicatePessimisticFixpoint(); 7242 } 7243 7244 // Register a rewrite of the argument. 7245 Argument *Arg = getAssociatedArgument(); 7246 if (!A.isValidFunctionSignatureRewrite(*Arg, ReplacementTypes)) { 7247 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n"); 7248 return indicatePessimisticFixpoint(); 7249 } 7250 7251 unsigned ArgNo = Arg->getArgNo(); 7252 7253 // Helper to check if for the given call site the associated argument is 7254 // passed to a callback where the privatization would be different. 7255 auto IsCompatiblePrivArgOfCallback = [&](CallBase &CB) { 7256 SmallVector<const Use *, 4> CallbackUses; 7257 AbstractCallSite::getCallbackUses(CB, CallbackUses); 7258 for (const Use *U : CallbackUses) { 7259 AbstractCallSite CBACS(U); 7260 assert(CBACS && CBACS.isCallbackCall()); 7261 for (Argument &CBArg : CBACS.getCalledFunction()->args()) { 7262 int CBArgNo = CBACS.getCallArgOperandNo(CBArg); 7263 7264 LLVM_DEBUG({ 7265 dbgs() 7266 << "[AAPrivatizablePtr] Argument " << *Arg 7267 << "check if can be privatized in the context of its parent (" 7268 << Arg->getParent()->getName() 7269 << ")\n[AAPrivatizablePtr] because it is an argument in a " 7270 "callback (" 7271 << CBArgNo << "@" << CBACS.getCalledFunction()->getName() 7272 << ")\n[AAPrivatizablePtr] " << CBArg << " : " 7273 << CBACS.getCallArgOperand(CBArg) << " vs " 7274 << CB.getArgOperand(ArgNo) << "\n" 7275 << "[AAPrivatizablePtr] " << CBArg << " : " 7276 << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n"; 7277 }); 7278 7279 if (CBArgNo != int(ArgNo)) 7280 continue; 7281 const auto &CBArgPrivAA = A.getAAFor<AAPrivatizablePtr>( 7282 *this, IRPosition::argument(CBArg), DepClassTy::REQUIRED); 7283 if (CBArgPrivAA.isValidState()) { 7284 auto CBArgPrivTy = CBArgPrivAA.getPrivatizableType(); 7285 if (!CBArgPrivTy) 7286 continue; 7287 if (*CBArgPrivTy == PrivatizableType) 7288 continue; 7289 } 7290 7291 LLVM_DEBUG({ 7292 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg 7293 << " cannot be privatized in the context of its parent (" 7294 << Arg->getParent()->getName() 7295 << ")\n[AAPrivatizablePtr] because it is an argument in a " 7296 "callback (" 7297 << CBArgNo << "@" << CBACS.getCalledFunction()->getName() 7298 << ").\n[AAPrivatizablePtr] for which the argument " 7299 "privatization is not compatible.\n"; 7300 }); 7301 return false; 7302 } 7303 } 7304 return true; 7305 }; 7306 7307 // Helper to check if for the given call site the associated argument is 7308 // passed to a direct call where the privatization would be different. 7309 auto IsCompatiblePrivArgOfDirectCS = [&](AbstractCallSite ACS) { 7310 CallBase *DC = cast<CallBase>(ACS.getInstruction()); 7311 int DCArgNo = ACS.getCallArgOperandNo(ArgNo); 7312 assert(DCArgNo >= 0 && unsigned(DCArgNo) < DC->arg_size() && 7313 "Expected a direct call operand for callback call operand"); 7314 7315 LLVM_DEBUG({ 7316 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg 7317 << " check if be privatized in the context of its parent (" 7318 << Arg->getParent()->getName() 7319 << ")\n[AAPrivatizablePtr] because it is an argument in a " 7320 "direct call of (" 7321 << DCArgNo << "@" << DC->getCalledFunction()->getName() 7322 << ").\n"; 7323 }); 7324 7325 Function *DCCallee = DC->getCalledFunction(); 7326 if (unsigned(DCArgNo) < DCCallee->arg_size()) { 7327 const auto &DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>( 7328 *this, IRPosition::argument(*DCCallee->getArg(DCArgNo)), 7329 DepClassTy::REQUIRED); 7330 if (DCArgPrivAA.isValidState()) { 7331 auto DCArgPrivTy = DCArgPrivAA.getPrivatizableType(); 7332 if (!DCArgPrivTy) 7333 return true; 7334 if (*DCArgPrivTy == PrivatizableType) 7335 return true; 7336 } 7337 } 7338 7339 LLVM_DEBUG({ 7340 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg 7341 << " cannot be privatized in the context of its parent (" 7342 << Arg->getParent()->getName() 7343 << ")\n[AAPrivatizablePtr] because it is an argument in a " 7344 "direct call of (" 7345 << ACS.getInstruction()->getCalledFunction()->getName() 7346 << ").\n[AAPrivatizablePtr] for which the argument " 7347 "privatization is not compatible.\n"; 7348 }); 7349 return false; 7350 }; 7351 7352 // Helper to check if the associated argument is used at the given abstract 7353 // call site in a way that is incompatible with the privatization assumed 7354 // here. 7355 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) { 7356 if (ACS.isDirectCall()) 7357 return IsCompatiblePrivArgOfCallback(*ACS.getInstruction()); 7358 if (ACS.isCallbackCall()) 7359 return IsCompatiblePrivArgOfDirectCS(ACS); 7360 return false; 7361 }; 7362 7363 if (!A.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite, *this, true, 7364 UsedAssumedInformation)) 7365 return indicatePessimisticFixpoint(); 7366 7367 return ChangeStatus::UNCHANGED; 7368 } 7369 7370 /// Given a type to private \p PrivType, collect the constituates (which are 7371 /// used) in \p ReplacementTypes. 7372 static void 7373 identifyReplacementTypes(Type *PrivType, 7374 SmallVectorImpl<Type *> &ReplacementTypes) { 7375 // TODO: For now we expand the privatization type to the fullest which can 7376 // lead to dead arguments that need to be removed later. 7377 assert(PrivType && "Expected privatizable type!"); 7378 7379 // Traverse the type, extract constituate types on the outermost level. 7380 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) { 7381 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) 7382 ReplacementTypes.push_back(PrivStructType->getElementType(u)); 7383 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) { 7384 ReplacementTypes.append(PrivArrayType->getNumElements(), 7385 PrivArrayType->getElementType()); 7386 } else { 7387 ReplacementTypes.push_back(PrivType); 7388 } 7389 } 7390 7391 /// Initialize \p Base according to the type \p PrivType at position \p IP. 7392 /// The values needed are taken from the arguments of \p F starting at 7393 /// position \p ArgNo. 7394 static void createInitialization(Type *PrivType, Value &Base, Function &F, 7395 unsigned ArgNo, Instruction &IP) { 7396 assert(PrivType && "Expected privatizable type!"); 7397 7398 IRBuilder<NoFolder> IRB(&IP); 7399 const DataLayout &DL = F.getParent()->getDataLayout(); 7400 7401 // Traverse the type, build GEPs and stores. 7402 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) { 7403 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType); 7404 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) { 7405 Type *PointeeTy = PrivStructType->getElementType(u)->getPointerTo(); 7406 Value *Ptr = 7407 constructPointer(PointeeTy, PrivType, &Base, 7408 PrivStructLayout->getElementOffset(u), IRB, DL); 7409 new StoreInst(F.getArg(ArgNo + u), Ptr, &IP); 7410 } 7411 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) { 7412 Type *PointeeTy = PrivArrayType->getElementType(); 7413 Type *PointeePtrTy = PointeeTy->getPointerTo(); 7414 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy); 7415 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) { 7416 Value *Ptr = constructPointer(PointeePtrTy, PrivType, &Base, 7417 u * PointeeTySize, IRB, DL); 7418 new StoreInst(F.getArg(ArgNo + u), Ptr, &IP); 7419 } 7420 } else { 7421 new StoreInst(F.getArg(ArgNo), &Base, &IP); 7422 } 7423 } 7424 7425 /// Extract values from \p Base according to the type \p PrivType at the 7426 /// call position \p ACS. The values are appended to \p ReplacementValues. 7427 void createReplacementValues(Align Alignment, Type *PrivType, 7428 AbstractCallSite ACS, Value *Base, 7429 SmallVectorImpl<Value *> &ReplacementValues) { 7430 assert(Base && "Expected base value!"); 7431 assert(PrivType && "Expected privatizable type!"); 7432 Instruction *IP = ACS.getInstruction(); 7433 7434 IRBuilder<NoFolder> IRB(IP); 7435 const DataLayout &DL = IP->getModule()->getDataLayout(); 7436 7437 Type *PrivPtrType = PrivType->getPointerTo(); 7438 if (Base->getType() != PrivPtrType) 7439 Base = BitCastInst::CreatePointerBitCastOrAddrSpaceCast( 7440 Base, PrivPtrType, "", ACS.getInstruction()); 7441 7442 // Traverse the type, build GEPs and loads. 7443 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) { 7444 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType); 7445 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) { 7446 Type *PointeeTy = PrivStructType->getElementType(u); 7447 Value *Ptr = 7448 constructPointer(PointeeTy->getPointerTo(), PrivType, Base, 7449 PrivStructLayout->getElementOffset(u), IRB, DL); 7450 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP); 7451 L->setAlignment(Alignment); 7452 ReplacementValues.push_back(L); 7453 } 7454 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) { 7455 Type *PointeeTy = PrivArrayType->getElementType(); 7456 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy); 7457 Type *PointeePtrTy = PointeeTy->getPointerTo(); 7458 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) { 7459 Value *Ptr = constructPointer(PointeePtrTy, PrivType, Base, 7460 u * PointeeTySize, IRB, DL); 7461 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP); 7462 L->setAlignment(Alignment); 7463 ReplacementValues.push_back(L); 7464 } 7465 } else { 7466 LoadInst *L = new LoadInst(PrivType, Base, "", IP); 7467 L->setAlignment(Alignment); 7468 ReplacementValues.push_back(L); 7469 } 7470 } 7471 7472 /// See AbstractAttribute::manifest(...) 7473 ChangeStatus manifest(Attributor &A) override { 7474 if (!PrivatizableType) 7475 return ChangeStatus::UNCHANGED; 7476 assert(*PrivatizableType && "Expected privatizable type!"); 7477 7478 // Collect all tail calls in the function as we cannot allow new allocas to 7479 // escape into tail recursion. 7480 // TODO: Be smarter about new allocas escaping into tail calls. 7481 SmallVector<CallInst *, 16> TailCalls; 7482 bool UsedAssumedInformation = false; 7483 if (!A.checkForAllInstructions( 7484 [&](Instruction &I) { 7485 CallInst &CI = cast<CallInst>(I); 7486 if (CI.isTailCall()) 7487 TailCalls.push_back(&CI); 7488 return true; 7489 }, 7490 *this, {Instruction::Call}, UsedAssumedInformation)) 7491 return ChangeStatus::UNCHANGED; 7492 7493 Argument *Arg = getAssociatedArgument(); 7494 // Query AAAlign attribute for alignment of associated argument to 7495 // determine the best alignment of loads. 7496 const auto &AlignAA = 7497 A.getAAFor<AAAlign>(*this, IRPosition::value(*Arg), DepClassTy::NONE); 7498 7499 // Callback to repair the associated function. A new alloca is placed at the 7500 // beginning and initialized with the values passed through arguments. The 7501 // new alloca replaces the use of the old pointer argument. 7502 Attributor::ArgumentReplacementInfo::CalleeRepairCBTy FnRepairCB = 7503 [=](const Attributor::ArgumentReplacementInfo &ARI, 7504 Function &ReplacementFn, Function::arg_iterator ArgIt) { 7505 BasicBlock &EntryBB = ReplacementFn.getEntryBlock(); 7506 Instruction *IP = &*EntryBB.getFirstInsertionPt(); 7507 const DataLayout &DL = IP->getModule()->getDataLayout(); 7508 unsigned AS = DL.getAllocaAddrSpace(); 7509 Instruction *AI = new AllocaInst(*PrivatizableType, AS, 7510 Arg->getName() + ".priv", IP); 7511 createInitialization(*PrivatizableType, *AI, ReplacementFn, 7512 ArgIt->getArgNo(), *IP); 7513 7514 if (AI->getType() != Arg->getType()) 7515 AI = BitCastInst::CreatePointerBitCastOrAddrSpaceCast( 7516 AI, Arg->getType(), "", IP); 7517 Arg->replaceAllUsesWith(AI); 7518 7519 for (CallInst *CI : TailCalls) 7520 CI->setTailCall(false); 7521 }; 7522 7523 // Callback to repair a call site of the associated function. The elements 7524 // of the privatizable type are loaded prior to the call and passed to the 7525 // new function version. 7526 Attributor::ArgumentReplacementInfo::ACSRepairCBTy ACSRepairCB = 7527 [=, &AlignAA](const Attributor::ArgumentReplacementInfo &ARI, 7528 AbstractCallSite ACS, 7529 SmallVectorImpl<Value *> &NewArgOperands) { 7530 // When no alignment is specified for the load instruction, 7531 // natural alignment is assumed. 7532 createReplacementValues( 7533 AlignAA.getAssumedAlign(), *PrivatizableType, ACS, 7534 ACS.getCallArgOperand(ARI.getReplacedArg().getArgNo()), 7535 NewArgOperands); 7536 }; 7537 7538 // Collect the types that will replace the privatizable type in the function 7539 // signature. 7540 SmallVector<Type *, 16> ReplacementTypes; 7541 identifyReplacementTypes(*PrivatizableType, ReplacementTypes); 7542 7543 // Register a rewrite of the argument. 7544 if (A.registerFunctionSignatureRewrite(*Arg, ReplacementTypes, 7545 std::move(FnRepairCB), 7546 std::move(ACSRepairCB))) 7547 return ChangeStatus::CHANGED; 7548 return ChangeStatus::UNCHANGED; 7549 } 7550 7551 /// See AbstractAttribute::trackStatistics() 7552 void trackStatistics() const override { 7553 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr); 7554 } 7555 }; 7556 7557 struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl { 7558 AAPrivatizablePtrFloating(const IRPosition &IRP, Attributor &A) 7559 : AAPrivatizablePtrImpl(IRP, A) {} 7560 7561 /// See AbstractAttribute::initialize(...). 7562 void initialize(Attributor &A) override { 7563 // TODO: We can privatize more than arguments. 7564 indicatePessimisticFixpoint(); 7565 } 7566 7567 ChangeStatus updateImpl(Attributor &A) override { 7568 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::" 7569 "updateImpl will not be called"); 7570 } 7571 7572 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...) 7573 std::optional<Type *> identifyPrivatizableType(Attributor &A) override { 7574 Value *Obj = getUnderlyingObject(&getAssociatedValue()); 7575 if (!Obj) { 7576 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n"); 7577 return nullptr; 7578 } 7579 7580 if (auto *AI = dyn_cast<AllocaInst>(Obj)) 7581 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize())) 7582 if (CI->isOne()) 7583 return AI->getAllocatedType(); 7584 if (auto *Arg = dyn_cast<Argument>(Obj)) { 7585 auto &PrivArgAA = A.getAAFor<AAPrivatizablePtr>( 7586 *this, IRPosition::argument(*Arg), DepClassTy::REQUIRED); 7587 if (PrivArgAA.isAssumedPrivatizablePtr()) 7588 return PrivArgAA.getPrivatizableType(); 7589 } 7590 7591 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid " 7592 "alloca nor privatizable argument: " 7593 << *Obj << "!\n"); 7594 return nullptr; 7595 } 7596 7597 /// See AbstractAttribute::trackStatistics() 7598 void trackStatistics() const override { 7599 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr); 7600 } 7601 }; 7602 7603 struct AAPrivatizablePtrCallSiteArgument final 7604 : public AAPrivatizablePtrFloating { 7605 AAPrivatizablePtrCallSiteArgument(const IRPosition &IRP, Attributor &A) 7606 : AAPrivatizablePtrFloating(IRP, A) {} 7607 7608 /// See AbstractAttribute::initialize(...). 7609 void initialize(Attributor &A) override { 7610 if (getIRPosition().hasAttr(Attribute::ByVal)) 7611 indicateOptimisticFixpoint(); 7612 } 7613 7614 /// See AbstractAttribute::updateImpl(...). 7615 ChangeStatus updateImpl(Attributor &A) override { 7616 PrivatizableType = identifyPrivatizableType(A); 7617 if (!PrivatizableType) 7618 return ChangeStatus::UNCHANGED; 7619 if (!*PrivatizableType) 7620 return indicatePessimisticFixpoint(); 7621 7622 const IRPosition &IRP = getIRPosition(); 7623 auto &NoCaptureAA = 7624 A.getAAFor<AANoCapture>(*this, IRP, DepClassTy::REQUIRED); 7625 if (!NoCaptureAA.isAssumedNoCapture()) { 7626 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n"); 7627 return indicatePessimisticFixpoint(); 7628 } 7629 7630 auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, IRP, DepClassTy::REQUIRED); 7631 if (!NoAliasAA.isAssumedNoAlias()) { 7632 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n"); 7633 return indicatePessimisticFixpoint(); 7634 } 7635 7636 bool IsKnown; 7637 if (!AA::isAssumedReadOnly(A, IRP, *this, IsKnown)) { 7638 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n"); 7639 return indicatePessimisticFixpoint(); 7640 } 7641 7642 return ChangeStatus::UNCHANGED; 7643 } 7644 7645 /// See AbstractAttribute::trackStatistics() 7646 void trackStatistics() const override { 7647 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr); 7648 } 7649 }; 7650 7651 struct AAPrivatizablePtrCallSiteReturned final 7652 : public AAPrivatizablePtrFloating { 7653 AAPrivatizablePtrCallSiteReturned(const IRPosition &IRP, Attributor &A) 7654 : AAPrivatizablePtrFloating(IRP, A) {} 7655 7656 /// See AbstractAttribute::initialize(...). 7657 void initialize(Attributor &A) override { 7658 // TODO: We can privatize more than arguments. 7659 indicatePessimisticFixpoint(); 7660 } 7661 7662 /// See AbstractAttribute::trackStatistics() 7663 void trackStatistics() const override { 7664 STATS_DECLTRACK_CSRET_ATTR(privatizable_ptr); 7665 } 7666 }; 7667 7668 struct AAPrivatizablePtrReturned final : public AAPrivatizablePtrFloating { 7669 AAPrivatizablePtrReturned(const IRPosition &IRP, Attributor &A) 7670 : AAPrivatizablePtrFloating(IRP, A) {} 7671 7672 /// See AbstractAttribute::initialize(...). 7673 void initialize(Attributor &A) override { 7674 // TODO: We can privatize more than arguments. 7675 indicatePessimisticFixpoint(); 7676 } 7677 7678 /// See AbstractAttribute::trackStatistics() 7679 void trackStatistics() const override { 7680 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr); 7681 } 7682 }; 7683 } // namespace 7684 7685 /// -------------------- Memory Behavior Attributes ---------------------------- 7686 /// Includes read-none, read-only, and write-only. 7687 /// ---------------------------------------------------------------------------- 7688 namespace { 7689 struct AAMemoryBehaviorImpl : public AAMemoryBehavior { 7690 AAMemoryBehaviorImpl(const IRPosition &IRP, Attributor &A) 7691 : AAMemoryBehavior(IRP, A) {} 7692 7693 /// See AbstractAttribute::initialize(...). 7694 void initialize(Attributor &A) override { 7695 intersectAssumedBits(BEST_STATE); 7696 getKnownStateFromValue(getIRPosition(), getState()); 7697 AAMemoryBehavior::initialize(A); 7698 } 7699 7700 /// Return the memory behavior information encoded in the IR for \p IRP. 7701 static void getKnownStateFromValue(const IRPosition &IRP, 7702 BitIntegerState &State, 7703 bool IgnoreSubsumingPositions = false) { 7704 SmallVector<Attribute, 2> Attrs; 7705 IRP.getAttrs(AttrKinds, Attrs, IgnoreSubsumingPositions); 7706 for (const Attribute &Attr : Attrs) { 7707 switch (Attr.getKindAsEnum()) { 7708 case Attribute::ReadNone: 7709 State.addKnownBits(NO_ACCESSES); 7710 break; 7711 case Attribute::ReadOnly: 7712 State.addKnownBits(NO_WRITES); 7713 break; 7714 case Attribute::WriteOnly: 7715 State.addKnownBits(NO_READS); 7716 break; 7717 default: 7718 llvm_unreachable("Unexpected attribute!"); 7719 } 7720 } 7721 7722 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) { 7723 if (!I->mayReadFromMemory()) 7724 State.addKnownBits(NO_READS); 7725 if (!I->mayWriteToMemory()) 7726 State.addKnownBits(NO_WRITES); 7727 } 7728 } 7729 7730 /// See AbstractAttribute::getDeducedAttributes(...). 7731 void getDeducedAttributes(LLVMContext &Ctx, 7732 SmallVectorImpl<Attribute> &Attrs) const override { 7733 assert(Attrs.size() == 0); 7734 if (isAssumedReadNone()) 7735 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone)); 7736 else if (isAssumedReadOnly()) 7737 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly)); 7738 else if (isAssumedWriteOnly()) 7739 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly)); 7740 assert(Attrs.size() <= 1); 7741 } 7742 7743 /// See AbstractAttribute::manifest(...). 7744 ChangeStatus manifest(Attributor &A) override { 7745 if (hasAttr(Attribute::ReadNone, /* IgnoreSubsumingPositions */ true)) 7746 return ChangeStatus::UNCHANGED; 7747 7748 const IRPosition &IRP = getIRPosition(); 7749 7750 // Check if we would improve the existing attributes first. 7751 SmallVector<Attribute, 4> DeducedAttrs; 7752 getDeducedAttributes(IRP.getAnchorValue().getContext(), DeducedAttrs); 7753 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) { 7754 return IRP.hasAttr(Attr.getKindAsEnum(), 7755 /* IgnoreSubsumingPositions */ true); 7756 })) 7757 return ChangeStatus::UNCHANGED; 7758 7759 // Clear existing attributes. 7760 IRP.removeAttrs(AttrKinds); 7761 7762 // Use the generic manifest method. 7763 return IRAttribute::manifest(A); 7764 } 7765 7766 /// See AbstractState::getAsStr(). 7767 const std::string getAsStr() const override { 7768 if (isAssumedReadNone()) 7769 return "readnone"; 7770 if (isAssumedReadOnly()) 7771 return "readonly"; 7772 if (isAssumedWriteOnly()) 7773 return "writeonly"; 7774 return "may-read/write"; 7775 } 7776 7777 /// The set of IR attributes AAMemoryBehavior deals with. 7778 static const Attribute::AttrKind AttrKinds[3]; 7779 }; 7780 7781 const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = { 7782 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly}; 7783 7784 /// Memory behavior attribute for a floating value. 7785 struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl { 7786 AAMemoryBehaviorFloating(const IRPosition &IRP, Attributor &A) 7787 : AAMemoryBehaviorImpl(IRP, A) {} 7788 7789 /// See AbstractAttribute::updateImpl(...). 7790 ChangeStatus updateImpl(Attributor &A) override; 7791 7792 /// See AbstractAttribute::trackStatistics() 7793 void trackStatistics() const override { 7794 if (isAssumedReadNone()) 7795 STATS_DECLTRACK_FLOATING_ATTR(readnone) 7796 else if (isAssumedReadOnly()) 7797 STATS_DECLTRACK_FLOATING_ATTR(readonly) 7798 else if (isAssumedWriteOnly()) 7799 STATS_DECLTRACK_FLOATING_ATTR(writeonly) 7800 } 7801 7802 private: 7803 /// Return true if users of \p UserI might access the underlying 7804 /// variable/location described by \p U and should therefore be analyzed. 7805 bool followUsersOfUseIn(Attributor &A, const Use &U, 7806 const Instruction *UserI); 7807 7808 /// Update the state according to the effect of use \p U in \p UserI. 7809 void analyzeUseIn(Attributor &A, const Use &U, const Instruction *UserI); 7810 }; 7811 7812 /// Memory behavior attribute for function argument. 7813 struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating { 7814 AAMemoryBehaviorArgument(const IRPosition &IRP, Attributor &A) 7815 : AAMemoryBehaviorFloating(IRP, A) {} 7816 7817 /// See AbstractAttribute::initialize(...). 7818 void initialize(Attributor &A) override { 7819 intersectAssumedBits(BEST_STATE); 7820 const IRPosition &IRP = getIRPosition(); 7821 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we 7822 // can query it when we use has/getAttr. That would allow us to reuse the 7823 // initialize of the base class here. 7824 bool HasByVal = 7825 IRP.hasAttr({Attribute::ByVal}, /* IgnoreSubsumingPositions */ true); 7826 getKnownStateFromValue(IRP, getState(), 7827 /* IgnoreSubsumingPositions */ HasByVal); 7828 7829 // Initialize the use vector with all direct uses of the associated value. 7830 Argument *Arg = getAssociatedArgument(); 7831 if (!Arg || !A.isFunctionIPOAmendable(*(Arg->getParent()))) 7832 indicatePessimisticFixpoint(); 7833 } 7834 7835 ChangeStatus manifest(Attributor &A) override { 7836 // TODO: Pointer arguments are not supported on vectors of pointers yet. 7837 if (!getAssociatedValue().getType()->isPointerTy()) 7838 return ChangeStatus::UNCHANGED; 7839 7840 // TODO: From readattrs.ll: "inalloca parameters are always 7841 // considered written" 7842 if (hasAttr({Attribute::InAlloca, Attribute::Preallocated})) { 7843 removeKnownBits(NO_WRITES); 7844 removeAssumedBits(NO_WRITES); 7845 } 7846 return AAMemoryBehaviorFloating::manifest(A); 7847 } 7848 7849 /// See AbstractAttribute::trackStatistics() 7850 void trackStatistics() const override { 7851 if (isAssumedReadNone()) 7852 STATS_DECLTRACK_ARG_ATTR(readnone) 7853 else if (isAssumedReadOnly()) 7854 STATS_DECLTRACK_ARG_ATTR(readonly) 7855 else if (isAssumedWriteOnly()) 7856 STATS_DECLTRACK_ARG_ATTR(writeonly) 7857 } 7858 }; 7859 7860 struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument { 7861 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP, Attributor &A) 7862 : AAMemoryBehaviorArgument(IRP, A) {} 7863 7864 /// See AbstractAttribute::initialize(...). 7865 void initialize(Attributor &A) override { 7866 // If we don't have an associated attribute this is either a variadic call 7867 // or an indirect call, either way, nothing to do here. 7868 Argument *Arg = getAssociatedArgument(); 7869 if (!Arg) { 7870 indicatePessimisticFixpoint(); 7871 return; 7872 } 7873 if (Arg->hasByValAttr()) { 7874 addKnownBits(NO_WRITES); 7875 removeKnownBits(NO_READS); 7876 removeAssumedBits(NO_READS); 7877 } 7878 AAMemoryBehaviorArgument::initialize(A); 7879 if (getAssociatedFunction()->isDeclaration()) 7880 indicatePessimisticFixpoint(); 7881 } 7882 7883 /// See AbstractAttribute::updateImpl(...). 7884 ChangeStatus updateImpl(Attributor &A) override { 7885 // TODO: Once we have call site specific value information we can provide 7886 // call site specific liveness liveness information and then it makes 7887 // sense to specialize attributes for call sites arguments instead of 7888 // redirecting requests to the callee argument. 7889 Argument *Arg = getAssociatedArgument(); 7890 const IRPosition &ArgPos = IRPosition::argument(*Arg); 7891 auto &ArgAA = 7892 A.getAAFor<AAMemoryBehavior>(*this, ArgPos, DepClassTy::REQUIRED); 7893 return clampStateAndIndicateChange(getState(), ArgAA.getState()); 7894 } 7895 7896 /// See AbstractAttribute::trackStatistics() 7897 void trackStatistics() const override { 7898 if (isAssumedReadNone()) 7899 STATS_DECLTRACK_CSARG_ATTR(readnone) 7900 else if (isAssumedReadOnly()) 7901 STATS_DECLTRACK_CSARG_ATTR(readonly) 7902 else if (isAssumedWriteOnly()) 7903 STATS_DECLTRACK_CSARG_ATTR(writeonly) 7904 } 7905 }; 7906 7907 /// Memory behavior attribute for a call site return position. 7908 struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating { 7909 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP, Attributor &A) 7910 : AAMemoryBehaviorFloating(IRP, A) {} 7911 7912 /// See AbstractAttribute::initialize(...). 7913 void initialize(Attributor &A) override { 7914 AAMemoryBehaviorImpl::initialize(A); 7915 Function *F = getAssociatedFunction(); 7916 if (!F || F->isDeclaration()) 7917 indicatePessimisticFixpoint(); 7918 } 7919 7920 /// See AbstractAttribute::manifest(...). 7921 ChangeStatus manifest(Attributor &A) override { 7922 // We do not annotate returned values. 7923 return ChangeStatus::UNCHANGED; 7924 } 7925 7926 /// See AbstractAttribute::trackStatistics() 7927 void trackStatistics() const override {} 7928 }; 7929 7930 /// An AA to represent the memory behavior function attributes. 7931 struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl { 7932 AAMemoryBehaviorFunction(const IRPosition &IRP, Attributor &A) 7933 : AAMemoryBehaviorImpl(IRP, A) {} 7934 7935 /// See AbstractAttribute::updateImpl(Attributor &A). 7936 ChangeStatus updateImpl(Attributor &A) override; 7937 7938 /// See AbstractAttribute::manifest(...). 7939 ChangeStatus manifest(Attributor &A) override { 7940 // TODO: It would be better to merge this with AAMemoryLocation, so that 7941 // we could determine read/write per location. This would also have the 7942 // benefit of only one place trying to manifest the memory attribute. 7943 Function &F = cast<Function>(getAnchorValue()); 7944 MemoryEffects ME = MemoryEffects::unknown(); 7945 if (isAssumedReadNone()) 7946 ME = MemoryEffects::none(); 7947 else if (isAssumedReadOnly()) 7948 ME = MemoryEffects::readOnly(); 7949 else if (isAssumedWriteOnly()) 7950 ME = MemoryEffects::writeOnly(); 7951 7952 // Intersect with existing memory attribute, as we currently deduce the 7953 // location and modref portion separately. 7954 MemoryEffects ExistingME = F.getMemoryEffects(); 7955 ME &= ExistingME; 7956 if (ME == ExistingME) 7957 return ChangeStatus::UNCHANGED; 7958 7959 return IRAttributeManifest::manifestAttrs( 7960 A, getIRPosition(), Attribute::getWithMemoryEffects(F.getContext(), ME), 7961 /*ForceReplace*/ true); 7962 } 7963 7964 /// See AbstractAttribute::trackStatistics() 7965 void trackStatistics() const override { 7966 if (isAssumedReadNone()) 7967 STATS_DECLTRACK_FN_ATTR(readnone) 7968 else if (isAssumedReadOnly()) 7969 STATS_DECLTRACK_FN_ATTR(readonly) 7970 else if (isAssumedWriteOnly()) 7971 STATS_DECLTRACK_FN_ATTR(writeonly) 7972 } 7973 }; 7974 7975 /// AAMemoryBehavior attribute for call sites. 7976 struct AAMemoryBehaviorCallSite final : AAMemoryBehaviorImpl { 7977 AAMemoryBehaviorCallSite(const IRPosition &IRP, Attributor &A) 7978 : AAMemoryBehaviorImpl(IRP, A) {} 7979 7980 /// See AbstractAttribute::initialize(...). 7981 void initialize(Attributor &A) override { 7982 AAMemoryBehaviorImpl::initialize(A); 7983 Function *F = getAssociatedFunction(); 7984 if (!F || F->isDeclaration()) 7985 indicatePessimisticFixpoint(); 7986 } 7987 7988 /// See AbstractAttribute::updateImpl(...). 7989 ChangeStatus updateImpl(Attributor &A) override { 7990 // TODO: Once we have call site specific value information we can provide 7991 // call site specific liveness liveness information and then it makes 7992 // sense to specialize attributes for call sites arguments instead of 7993 // redirecting requests to the callee argument. 7994 Function *F = getAssociatedFunction(); 7995 const IRPosition &FnPos = IRPosition::function(*F); 7996 auto &FnAA = 7997 A.getAAFor<AAMemoryBehavior>(*this, FnPos, DepClassTy::REQUIRED); 7998 return clampStateAndIndicateChange(getState(), FnAA.getState()); 7999 } 8000 8001 /// See AbstractAttribute::manifest(...). 8002 ChangeStatus manifest(Attributor &A) override { 8003 // TODO: Deduplicate this with AAMemoryBehaviorFunction. 8004 CallBase &CB = cast<CallBase>(getAnchorValue()); 8005 MemoryEffects ME = MemoryEffects::unknown(); 8006 if (isAssumedReadNone()) 8007 ME = MemoryEffects::none(); 8008 else if (isAssumedReadOnly()) 8009 ME = MemoryEffects::readOnly(); 8010 else if (isAssumedWriteOnly()) 8011 ME = MemoryEffects::writeOnly(); 8012 8013 // Intersect with existing memory attribute, as we currently deduce the 8014 // location and modref portion separately. 8015 MemoryEffects ExistingME = CB.getMemoryEffects(); 8016 ME &= ExistingME; 8017 if (ME == ExistingME) 8018 return ChangeStatus::UNCHANGED; 8019 8020 return IRAttributeManifest::manifestAttrs( 8021 A, getIRPosition(), 8022 Attribute::getWithMemoryEffects(CB.getContext(), ME), 8023 /*ForceReplace*/ true); 8024 } 8025 8026 /// See AbstractAttribute::trackStatistics() 8027 void trackStatistics() const override { 8028 if (isAssumedReadNone()) 8029 STATS_DECLTRACK_CS_ATTR(readnone) 8030 else if (isAssumedReadOnly()) 8031 STATS_DECLTRACK_CS_ATTR(readonly) 8032 else if (isAssumedWriteOnly()) 8033 STATS_DECLTRACK_CS_ATTR(writeonly) 8034 } 8035 }; 8036 8037 ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) { 8038 8039 // The current assumed state used to determine a change. 8040 auto AssumedState = getAssumed(); 8041 8042 auto CheckRWInst = [&](Instruction &I) { 8043 // If the instruction has an own memory behavior state, use it to restrict 8044 // the local state. No further analysis is required as the other memory 8045 // state is as optimistic as it gets. 8046 if (const auto *CB = dyn_cast<CallBase>(&I)) { 8047 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>( 8048 *this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED); 8049 intersectAssumedBits(MemBehaviorAA.getAssumed()); 8050 return !isAtFixpoint(); 8051 } 8052 8053 // Remove access kind modifiers if necessary. 8054 if (I.mayReadFromMemory()) 8055 removeAssumedBits(NO_READS); 8056 if (I.mayWriteToMemory()) 8057 removeAssumedBits(NO_WRITES); 8058 return !isAtFixpoint(); 8059 }; 8060 8061 bool UsedAssumedInformation = false; 8062 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this, 8063 UsedAssumedInformation)) 8064 return indicatePessimisticFixpoint(); 8065 8066 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED 8067 : ChangeStatus::UNCHANGED; 8068 } 8069 8070 ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) { 8071 8072 const IRPosition &IRP = getIRPosition(); 8073 const IRPosition &FnPos = IRPosition::function_scope(IRP); 8074 AAMemoryBehavior::StateType &S = getState(); 8075 8076 // First, check the function scope. We take the known information and we avoid 8077 // work if the assumed information implies the current assumed information for 8078 // this attribute. This is a valid for all but byval arguments. 8079 Argument *Arg = IRP.getAssociatedArgument(); 8080 AAMemoryBehavior::base_t FnMemAssumedState = 8081 AAMemoryBehavior::StateType::getWorstState(); 8082 if (!Arg || !Arg->hasByValAttr()) { 8083 const auto &FnMemAA = 8084 A.getAAFor<AAMemoryBehavior>(*this, FnPos, DepClassTy::OPTIONAL); 8085 FnMemAssumedState = FnMemAA.getAssumed(); 8086 S.addKnownBits(FnMemAA.getKnown()); 8087 if ((S.getAssumed() & FnMemAA.getAssumed()) == S.getAssumed()) 8088 return ChangeStatus::UNCHANGED; 8089 } 8090 8091 // The current assumed state used to determine a change. 8092 auto AssumedState = S.getAssumed(); 8093 8094 // Make sure the value is not captured (except through "return"), if 8095 // it is, any information derived would be irrelevant anyway as we cannot 8096 // check the potential aliases introduced by the capture. However, no need 8097 // to fall back to anythign less optimistic than the function state. 8098 const auto &ArgNoCaptureAA = 8099 A.getAAFor<AANoCapture>(*this, IRP, DepClassTy::OPTIONAL); 8100 if (!ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) { 8101 S.intersectAssumedBits(FnMemAssumedState); 8102 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED 8103 : ChangeStatus::UNCHANGED; 8104 } 8105 8106 // Visit and expand uses until all are analyzed or a fixpoint is reached. 8107 auto UsePred = [&](const Use &U, bool &Follow) -> bool { 8108 Instruction *UserI = cast<Instruction>(U.getUser()); 8109 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << *U << " in " << *UserI 8110 << " \n"); 8111 8112 // Droppable users, e.g., llvm::assume does not actually perform any action. 8113 if (UserI->isDroppable()) 8114 return true; 8115 8116 // Check if the users of UserI should also be visited. 8117 Follow = followUsersOfUseIn(A, U, UserI); 8118 8119 // If UserI might touch memory we analyze the use in detail. 8120 if (UserI->mayReadOrWriteMemory()) 8121 analyzeUseIn(A, U, UserI); 8122 8123 return !isAtFixpoint(); 8124 }; 8125 8126 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) 8127 return indicatePessimisticFixpoint(); 8128 8129 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED 8130 : ChangeStatus::UNCHANGED; 8131 } 8132 8133 bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use &U, 8134 const Instruction *UserI) { 8135 // The loaded value is unrelated to the pointer argument, no need to 8136 // follow the users of the load. 8137 if (isa<LoadInst>(UserI) || isa<ReturnInst>(UserI)) 8138 return false; 8139 8140 // By default we follow all uses assuming UserI might leak information on U, 8141 // we have special handling for call sites operands though. 8142 const auto *CB = dyn_cast<CallBase>(UserI); 8143 if (!CB || !CB->isArgOperand(&U)) 8144 return true; 8145 8146 // If the use is a call argument known not to be captured, the users of 8147 // the call do not need to be visited because they have to be unrelated to 8148 // the input. Note that this check is not trivial even though we disallow 8149 // general capturing of the underlying argument. The reason is that the 8150 // call might the argument "through return", which we allow and for which we 8151 // need to check call users. 8152 if (U.get()->getType()->isPointerTy()) { 8153 unsigned ArgNo = CB->getArgOperandNo(&U); 8154 const auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>( 8155 *this, IRPosition::callsite_argument(*CB, ArgNo), DepClassTy::OPTIONAL); 8156 return !ArgNoCaptureAA.isAssumedNoCapture(); 8157 } 8158 8159 return true; 8160 } 8161 8162 void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use &U, 8163 const Instruction *UserI) { 8164 assert(UserI->mayReadOrWriteMemory()); 8165 8166 switch (UserI->getOpcode()) { 8167 default: 8168 // TODO: Handle all atomics and other side-effect operations we know of. 8169 break; 8170 case Instruction::Load: 8171 // Loads cause the NO_READS property to disappear. 8172 removeAssumedBits(NO_READS); 8173 return; 8174 8175 case Instruction::Store: 8176 // Stores cause the NO_WRITES property to disappear if the use is the 8177 // pointer operand. Note that while capturing was taken care of somewhere 8178 // else we need to deal with stores of the value that is not looked through. 8179 if (cast<StoreInst>(UserI)->getPointerOperand() == U.get()) 8180 removeAssumedBits(NO_WRITES); 8181 else 8182 indicatePessimisticFixpoint(); 8183 return; 8184 8185 case Instruction::Call: 8186 case Instruction::CallBr: 8187 case Instruction::Invoke: { 8188 // For call sites we look at the argument memory behavior attribute (this 8189 // could be recursive!) in order to restrict our own state. 8190 const auto *CB = cast<CallBase>(UserI); 8191 8192 // Give up on operand bundles. 8193 if (CB->isBundleOperand(&U)) { 8194 indicatePessimisticFixpoint(); 8195 return; 8196 } 8197 8198 // Calling a function does read the function pointer, maybe write it if the 8199 // function is self-modifying. 8200 if (CB->isCallee(&U)) { 8201 removeAssumedBits(NO_READS); 8202 break; 8203 } 8204 8205 // Adjust the possible access behavior based on the information on the 8206 // argument. 8207 IRPosition Pos; 8208 if (U.get()->getType()->isPointerTy()) 8209 Pos = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U)); 8210 else 8211 Pos = IRPosition::callsite_function(*CB); 8212 const auto &MemBehaviorAA = 8213 A.getAAFor<AAMemoryBehavior>(*this, Pos, DepClassTy::OPTIONAL); 8214 // "assumed" has at most the same bits as the MemBehaviorAA assumed 8215 // and at least "known". 8216 intersectAssumedBits(MemBehaviorAA.getAssumed()); 8217 return; 8218 } 8219 }; 8220 8221 // Generally, look at the "may-properties" and adjust the assumed state if we 8222 // did not trigger special handling before. 8223 if (UserI->mayReadFromMemory()) 8224 removeAssumedBits(NO_READS); 8225 if (UserI->mayWriteToMemory()) 8226 removeAssumedBits(NO_WRITES); 8227 } 8228 } // namespace 8229 8230 /// -------------------- Memory Locations Attributes --------------------------- 8231 /// Includes read-none, argmemonly, inaccessiblememonly, 8232 /// inaccessiblememorargmemonly 8233 /// ---------------------------------------------------------------------------- 8234 8235 std::string AAMemoryLocation::getMemoryLocationsAsStr( 8236 AAMemoryLocation::MemoryLocationsKind MLK) { 8237 if (0 == (MLK & AAMemoryLocation::NO_LOCATIONS)) 8238 return "all memory"; 8239 if (MLK == AAMemoryLocation::NO_LOCATIONS) 8240 return "no memory"; 8241 std::string S = "memory:"; 8242 if (0 == (MLK & AAMemoryLocation::NO_LOCAL_MEM)) 8243 S += "stack,"; 8244 if (0 == (MLK & AAMemoryLocation::NO_CONST_MEM)) 8245 S += "constant,"; 8246 if (0 == (MLK & AAMemoryLocation::NO_GLOBAL_INTERNAL_MEM)) 8247 S += "internal global,"; 8248 if (0 == (MLK & AAMemoryLocation::NO_GLOBAL_EXTERNAL_MEM)) 8249 S += "external global,"; 8250 if (0 == (MLK & AAMemoryLocation::NO_ARGUMENT_MEM)) 8251 S += "argument,"; 8252 if (0 == (MLK & AAMemoryLocation::NO_INACCESSIBLE_MEM)) 8253 S += "inaccessible,"; 8254 if (0 == (MLK & AAMemoryLocation::NO_MALLOCED_MEM)) 8255 S += "malloced,"; 8256 if (0 == (MLK & AAMemoryLocation::NO_UNKOWN_MEM)) 8257 S += "unknown,"; 8258 S.pop_back(); 8259 return S; 8260 } 8261 8262 namespace { 8263 struct AAMemoryLocationImpl : public AAMemoryLocation { 8264 8265 AAMemoryLocationImpl(const IRPosition &IRP, Attributor &A) 8266 : AAMemoryLocation(IRP, A), Allocator(A.Allocator) { 8267 AccessKind2Accesses.fill(nullptr); 8268 } 8269 8270 ~AAMemoryLocationImpl() { 8271 // The AccessSets are allocated via a BumpPtrAllocator, we call 8272 // the destructor manually. 8273 for (AccessSet *AS : AccessKind2Accesses) 8274 if (AS) 8275 AS->~AccessSet(); 8276 } 8277 8278 /// See AbstractAttribute::initialize(...). 8279 void initialize(Attributor &A) override { 8280 intersectAssumedBits(BEST_STATE); 8281 getKnownStateFromValue(A, getIRPosition(), getState()); 8282 AAMemoryLocation::initialize(A); 8283 } 8284 8285 /// Return the memory behavior information encoded in the IR for \p IRP. 8286 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP, 8287 BitIntegerState &State, 8288 bool IgnoreSubsumingPositions = false) { 8289 // For internal functions we ignore `argmemonly` and 8290 // `inaccessiblememorargmemonly` as we might break it via interprocedural 8291 // constant propagation. It is unclear if this is the best way but it is 8292 // unlikely this will cause real performance problems. If we are deriving 8293 // attributes for the anchor function we even remove the attribute in 8294 // addition to ignoring it. 8295 // TODO: A better way to handle this would be to add ~NO_GLOBAL_MEM / 8296 // MemoryEffects::Other as a possible location. 8297 bool UseArgMemOnly = true; 8298 Function *AnchorFn = IRP.getAnchorScope(); 8299 if (AnchorFn && A.isRunOn(*AnchorFn)) 8300 UseArgMemOnly = !AnchorFn->hasLocalLinkage(); 8301 8302 SmallVector<Attribute, 2> Attrs; 8303 IRP.getAttrs({Attribute::Memory}, Attrs, IgnoreSubsumingPositions); 8304 for (const Attribute &Attr : Attrs) { 8305 // TODO: We can map MemoryEffects to Attributor locations more precisely. 8306 MemoryEffects ME = Attr.getMemoryEffects(); 8307 if (ME.doesNotAccessMemory()) { 8308 State.addKnownBits(NO_LOCAL_MEM | NO_CONST_MEM); 8309 continue; 8310 } 8311 if (ME.onlyAccessesInaccessibleMem()) { 8312 State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true)); 8313 continue; 8314 } 8315 if (ME.onlyAccessesArgPointees()) { 8316 if (UseArgMemOnly) 8317 State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true)); 8318 else { 8319 // Remove location information, only keep read/write info. 8320 ME = MemoryEffects(ME.getModRef()); 8321 IRAttributeManifest::manifestAttrs( 8322 A, IRP, 8323 Attribute::getWithMemoryEffects(IRP.getAnchorValue().getContext(), 8324 ME), 8325 /*ForceReplace*/ true); 8326 } 8327 continue; 8328 } 8329 if (ME.onlyAccessesInaccessibleOrArgMem()) { 8330 if (UseArgMemOnly) 8331 State.addKnownBits(inverseLocation( 8332 NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true)); 8333 else { 8334 // Remove location information, only keep read/write info. 8335 ME = MemoryEffects(ME.getModRef()); 8336 IRAttributeManifest::manifestAttrs( 8337 A, IRP, 8338 Attribute::getWithMemoryEffects(IRP.getAnchorValue().getContext(), 8339 ME), 8340 /*ForceReplace*/ true); 8341 } 8342 continue; 8343 } 8344 } 8345 } 8346 8347 /// See AbstractAttribute::getDeducedAttributes(...). 8348 void getDeducedAttributes(LLVMContext &Ctx, 8349 SmallVectorImpl<Attribute> &Attrs) const override { 8350 // TODO: We can map Attributor locations to MemoryEffects more precisely. 8351 assert(Attrs.size() == 0); 8352 if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION) { 8353 if (isAssumedReadNone()) 8354 Attrs.push_back( 8355 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::none())); 8356 else if (isAssumedInaccessibleMemOnly()) 8357 Attrs.push_back(Attribute::getWithMemoryEffects( 8358 Ctx, MemoryEffects::inaccessibleMemOnly())); 8359 else if (isAssumedArgMemOnly()) 8360 Attrs.push_back( 8361 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::argMemOnly())); 8362 else if (isAssumedInaccessibleOrArgMemOnly()) 8363 Attrs.push_back(Attribute::getWithMemoryEffects( 8364 Ctx, MemoryEffects::inaccessibleOrArgMemOnly())); 8365 } 8366 assert(Attrs.size() <= 1); 8367 } 8368 8369 /// See AbstractAttribute::manifest(...). 8370 ChangeStatus manifest(Attributor &A) override { 8371 // TODO: If AAMemoryLocation and AAMemoryBehavior are merged, we could 8372 // provide per-location modref information here. 8373 const IRPosition &IRP = getIRPosition(); 8374 8375 SmallVector<Attribute, 1> DeducedAttrs; 8376 getDeducedAttributes(IRP.getAnchorValue().getContext(), DeducedAttrs); 8377 if (DeducedAttrs.size() != 1) 8378 return ChangeStatus::UNCHANGED; 8379 MemoryEffects ME = DeducedAttrs[0].getMemoryEffects(); 8380 8381 // Intersect with existing memory attribute, as we currently deduce the 8382 // location and modref portion separately. 8383 SmallVector<Attribute, 1> ExistingAttrs; 8384 IRP.getAttrs({Attribute::Memory}, ExistingAttrs, 8385 /* IgnoreSubsumingPositions */ true); 8386 if (ExistingAttrs.size() == 1) { 8387 MemoryEffects ExistingME = ExistingAttrs[0].getMemoryEffects(); 8388 ME &= ExistingME; 8389 if (ME == ExistingME) 8390 return ChangeStatus::UNCHANGED; 8391 } 8392 8393 return IRAttributeManifest::manifestAttrs( 8394 A, IRP, 8395 Attribute::getWithMemoryEffects(IRP.getAnchorValue().getContext(), ME), 8396 /*ForceReplace*/ true); 8397 } 8398 8399 /// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...). 8400 bool checkForAllAccessesToMemoryKind( 8401 function_ref<bool(const Instruction *, const Value *, AccessKind, 8402 MemoryLocationsKind)> 8403 Pred, 8404 MemoryLocationsKind RequestedMLK) const override { 8405 if (!isValidState()) 8406 return false; 8407 8408 MemoryLocationsKind AssumedMLK = getAssumedNotAccessedLocation(); 8409 if (AssumedMLK == NO_LOCATIONS) 8410 return true; 8411 8412 unsigned Idx = 0; 8413 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; 8414 CurMLK *= 2, ++Idx) { 8415 if (CurMLK & RequestedMLK) 8416 continue; 8417 8418 if (const AccessSet *Accesses = AccessKind2Accesses[Idx]) 8419 for (const AccessInfo &AI : *Accesses) 8420 if (!Pred(AI.I, AI.Ptr, AI.Kind, CurMLK)) 8421 return false; 8422 } 8423 8424 return true; 8425 } 8426 8427 ChangeStatus indicatePessimisticFixpoint() override { 8428 // If we give up and indicate a pessimistic fixpoint this instruction will 8429 // become an access for all potential access kinds: 8430 // TODO: Add pointers for argmemonly and globals to improve the results of 8431 // checkForAllAccessesToMemoryKind. 8432 bool Changed = false; 8433 MemoryLocationsKind KnownMLK = getKnown(); 8434 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()); 8435 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) 8436 if (!(CurMLK & KnownMLK)) 8437 updateStateAndAccessesMap(getState(), CurMLK, I, nullptr, Changed, 8438 getAccessKindFromInst(I)); 8439 return AAMemoryLocation::indicatePessimisticFixpoint(); 8440 } 8441 8442 protected: 8443 /// Helper struct to tie together an instruction that has a read or write 8444 /// effect with the pointer it accesses (if any). 8445 struct AccessInfo { 8446 8447 /// The instruction that caused the access. 8448 const Instruction *I; 8449 8450 /// The base pointer that is accessed, or null if unknown. 8451 const Value *Ptr; 8452 8453 /// The kind of access (read/write/read+write). 8454 AccessKind Kind; 8455 8456 bool operator==(const AccessInfo &RHS) const { 8457 return I == RHS.I && Ptr == RHS.Ptr && Kind == RHS.Kind; 8458 } 8459 bool operator()(const AccessInfo &LHS, const AccessInfo &RHS) const { 8460 if (LHS.I != RHS.I) 8461 return LHS.I < RHS.I; 8462 if (LHS.Ptr != RHS.Ptr) 8463 return LHS.Ptr < RHS.Ptr; 8464 if (LHS.Kind != RHS.Kind) 8465 return LHS.Kind < RHS.Kind; 8466 return false; 8467 } 8468 }; 8469 8470 /// Mapping from *single* memory location kinds, e.g., LOCAL_MEM with the 8471 /// value of NO_LOCAL_MEM, to the accesses encountered for this memory kind. 8472 using AccessSet = SmallSet<AccessInfo, 2, AccessInfo>; 8473 std::array<AccessSet *, llvm::CTLog2<VALID_STATE>()> AccessKind2Accesses; 8474 8475 /// Categorize the pointer arguments of CB that might access memory in 8476 /// AccessedLoc and update the state and access map accordingly. 8477 void 8478 categorizeArgumentPointerLocations(Attributor &A, CallBase &CB, 8479 AAMemoryLocation::StateType &AccessedLocs, 8480 bool &Changed); 8481 8482 /// Return the kind(s) of location that may be accessed by \p V. 8483 AAMemoryLocation::MemoryLocationsKind 8484 categorizeAccessedLocations(Attributor &A, Instruction &I, bool &Changed); 8485 8486 /// Return the access kind as determined by \p I. 8487 AccessKind getAccessKindFromInst(const Instruction *I) { 8488 AccessKind AK = READ_WRITE; 8489 if (I) { 8490 AK = I->mayReadFromMemory() ? READ : NONE; 8491 AK = AccessKind(AK | (I->mayWriteToMemory() ? WRITE : NONE)); 8492 } 8493 return AK; 8494 } 8495 8496 /// Update the state \p State and the AccessKind2Accesses given that \p I is 8497 /// an access of kind \p AK to a \p MLK memory location with the access 8498 /// pointer \p Ptr. 8499 void updateStateAndAccessesMap(AAMemoryLocation::StateType &State, 8500 MemoryLocationsKind MLK, const Instruction *I, 8501 const Value *Ptr, bool &Changed, 8502 AccessKind AK = READ_WRITE) { 8503 8504 assert(isPowerOf2_32(MLK) && "Expected a single location set!"); 8505 auto *&Accesses = AccessKind2Accesses[llvm::Log2_32(MLK)]; 8506 if (!Accesses) 8507 Accesses = new (Allocator) AccessSet(); 8508 Changed |= Accesses->insert(AccessInfo{I, Ptr, AK}).second; 8509 State.removeAssumedBits(MLK); 8510 } 8511 8512 /// Determine the underlying locations kinds for \p Ptr, e.g., globals or 8513 /// arguments, and update the state and access map accordingly. 8514 void categorizePtrValue(Attributor &A, const Instruction &I, const Value &Ptr, 8515 AAMemoryLocation::StateType &State, bool &Changed); 8516 8517 /// Used to allocate access sets. 8518 BumpPtrAllocator &Allocator; 8519 }; 8520 8521 void AAMemoryLocationImpl::categorizePtrValue( 8522 Attributor &A, const Instruction &I, const Value &Ptr, 8523 AAMemoryLocation::StateType &State, bool &Changed) { 8524 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize pointer locations for " 8525 << Ptr << " [" 8526 << getMemoryLocationsAsStr(State.getAssumed()) << "]\n"); 8527 8528 auto Pred = [&](Value &Obj) { 8529 // TODO: recognize the TBAA used for constant accesses. 8530 MemoryLocationsKind MLK = NO_LOCATIONS; 8531 if (isa<UndefValue>(&Obj)) 8532 return true; 8533 if (isa<Argument>(&Obj)) { 8534 // TODO: For now we do not treat byval arguments as local copies performed 8535 // on the call edge, though, we should. To make that happen we need to 8536 // teach various passes, e.g., DSE, about the copy effect of a byval. That 8537 // would also allow us to mark functions only accessing byval arguments as 8538 // readnone again, arguably their accesses have no effect outside of the 8539 // function, like accesses to allocas. 8540 MLK = NO_ARGUMENT_MEM; 8541 } else if (auto *GV = dyn_cast<GlobalValue>(&Obj)) { 8542 // Reading constant memory is not treated as a read "effect" by the 8543 // function attr pass so we won't neither. Constants defined by TBAA are 8544 // similar. (We know we do not write it because it is constant.) 8545 if (auto *GVar = dyn_cast<GlobalVariable>(GV)) 8546 if (GVar->isConstant()) 8547 return true; 8548 8549 if (GV->hasLocalLinkage()) 8550 MLK = NO_GLOBAL_INTERNAL_MEM; 8551 else 8552 MLK = NO_GLOBAL_EXTERNAL_MEM; 8553 } else if (isa<ConstantPointerNull>(&Obj) && 8554 !NullPointerIsDefined(getAssociatedFunction(), 8555 Ptr.getType()->getPointerAddressSpace())) { 8556 return true; 8557 } else if (isa<AllocaInst>(&Obj)) { 8558 MLK = NO_LOCAL_MEM; 8559 } else if (const auto *CB = dyn_cast<CallBase>(&Obj)) { 8560 const auto &NoAliasAA = A.getAAFor<AANoAlias>( 8561 *this, IRPosition::callsite_returned(*CB), DepClassTy::OPTIONAL); 8562 if (NoAliasAA.isAssumedNoAlias()) 8563 MLK = NO_MALLOCED_MEM; 8564 else 8565 MLK = NO_UNKOWN_MEM; 8566 } else { 8567 MLK = NO_UNKOWN_MEM; 8568 } 8569 8570 assert(MLK != NO_LOCATIONS && "No location specified!"); 8571 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Ptr value can be categorized: " 8572 << Obj << " -> " << getMemoryLocationsAsStr(MLK) << "\n"); 8573 updateStateAndAccessesMap(getState(), MLK, &I, &Obj, Changed, 8574 getAccessKindFromInst(&I)); 8575 8576 return true; 8577 }; 8578 8579 const auto &AA = A.getAAFor<AAUnderlyingObjects>( 8580 *this, IRPosition::value(Ptr), DepClassTy::OPTIONAL); 8581 if (!AA.forallUnderlyingObjects(Pred, AA::Intraprocedural)) { 8582 LLVM_DEBUG( 8583 dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n"); 8584 updateStateAndAccessesMap(State, NO_UNKOWN_MEM, &I, nullptr, Changed, 8585 getAccessKindFromInst(&I)); 8586 return; 8587 } 8588 8589 LLVM_DEBUG( 8590 dbgs() << "[AAMemoryLocation] Accessed locations with pointer locations: " 8591 << getMemoryLocationsAsStr(State.getAssumed()) << "\n"); 8592 } 8593 8594 void AAMemoryLocationImpl::categorizeArgumentPointerLocations( 8595 Attributor &A, CallBase &CB, AAMemoryLocation::StateType &AccessedLocs, 8596 bool &Changed) { 8597 for (unsigned ArgNo = 0, E = CB.arg_size(); ArgNo < E; ++ArgNo) { 8598 8599 // Skip non-pointer arguments. 8600 const Value *ArgOp = CB.getArgOperand(ArgNo); 8601 if (!ArgOp->getType()->isPtrOrPtrVectorTy()) 8602 continue; 8603 8604 // Skip readnone arguments. 8605 const IRPosition &ArgOpIRP = IRPosition::callsite_argument(CB, ArgNo); 8606 const auto &ArgOpMemLocationAA = 8607 A.getAAFor<AAMemoryBehavior>(*this, ArgOpIRP, DepClassTy::OPTIONAL); 8608 8609 if (ArgOpMemLocationAA.isAssumedReadNone()) 8610 continue; 8611 8612 // Categorize potentially accessed pointer arguments as if there was an 8613 // access instruction with them as pointer. 8614 categorizePtrValue(A, CB, *ArgOp, AccessedLocs, Changed); 8615 } 8616 } 8617 8618 AAMemoryLocation::MemoryLocationsKind 8619 AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I, 8620 bool &Changed) { 8621 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize accessed locations for " 8622 << I << "\n"); 8623 8624 AAMemoryLocation::StateType AccessedLocs; 8625 AccessedLocs.intersectAssumedBits(NO_LOCATIONS); 8626 8627 if (auto *CB = dyn_cast<CallBase>(&I)) { 8628 8629 // First check if we assume any memory is access is visible. 8630 const auto &CBMemLocationAA = A.getAAFor<AAMemoryLocation>( 8631 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL); 8632 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I 8633 << " [" << CBMemLocationAA << "]\n"); 8634 8635 if (CBMemLocationAA.isAssumedReadNone()) 8636 return NO_LOCATIONS; 8637 8638 if (CBMemLocationAA.isAssumedInaccessibleMemOnly()) { 8639 updateStateAndAccessesMap(AccessedLocs, NO_INACCESSIBLE_MEM, &I, nullptr, 8640 Changed, getAccessKindFromInst(&I)); 8641 return AccessedLocs.getAssumed(); 8642 } 8643 8644 uint32_t CBAssumedNotAccessedLocs = 8645 CBMemLocationAA.getAssumedNotAccessedLocation(); 8646 8647 // Set the argmemonly and global bit as we handle them separately below. 8648 uint32_t CBAssumedNotAccessedLocsNoArgMem = 8649 CBAssumedNotAccessedLocs | NO_ARGUMENT_MEM | NO_GLOBAL_MEM; 8650 8651 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) { 8652 if (CBAssumedNotAccessedLocsNoArgMem & CurMLK) 8653 continue; 8654 updateStateAndAccessesMap(AccessedLocs, CurMLK, &I, nullptr, Changed, 8655 getAccessKindFromInst(&I)); 8656 } 8657 8658 // Now handle global memory if it might be accessed. This is slightly tricky 8659 // as NO_GLOBAL_MEM has multiple bits set. 8660 bool HasGlobalAccesses = ((~CBAssumedNotAccessedLocs) & NO_GLOBAL_MEM); 8661 if (HasGlobalAccesses) { 8662 auto AccessPred = [&](const Instruction *, const Value *Ptr, 8663 AccessKind Kind, MemoryLocationsKind MLK) { 8664 updateStateAndAccessesMap(AccessedLocs, MLK, &I, Ptr, Changed, 8665 getAccessKindFromInst(&I)); 8666 return true; 8667 }; 8668 if (!CBMemLocationAA.checkForAllAccessesToMemoryKind( 8669 AccessPred, inverseLocation(NO_GLOBAL_MEM, false, false))) 8670 return AccessedLocs.getWorstState(); 8671 } 8672 8673 LLVM_DEBUG( 8674 dbgs() << "[AAMemoryLocation] Accessed state before argument handling: " 8675 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n"); 8676 8677 // Now handle argument memory if it might be accessed. 8678 bool HasArgAccesses = ((~CBAssumedNotAccessedLocs) & NO_ARGUMENT_MEM); 8679 if (HasArgAccesses) 8680 categorizeArgumentPointerLocations(A, *CB, AccessedLocs, Changed); 8681 8682 LLVM_DEBUG( 8683 dbgs() << "[AAMemoryLocation] Accessed state after argument handling: " 8684 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n"); 8685 8686 return AccessedLocs.getAssumed(); 8687 } 8688 8689 if (const Value *Ptr = getPointerOperand(&I, /* AllowVolatile */ true)) { 8690 LLVM_DEBUG( 8691 dbgs() << "[AAMemoryLocation] Categorize memory access with pointer: " 8692 << I << " [" << *Ptr << "]\n"); 8693 categorizePtrValue(A, I, *Ptr, AccessedLocs, Changed); 8694 return AccessedLocs.getAssumed(); 8695 } 8696 8697 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Failed to categorize instruction: " 8698 << I << "\n"); 8699 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr, Changed, 8700 getAccessKindFromInst(&I)); 8701 return AccessedLocs.getAssumed(); 8702 } 8703 8704 /// An AA to represent the memory behavior function attributes. 8705 struct AAMemoryLocationFunction final : public AAMemoryLocationImpl { 8706 AAMemoryLocationFunction(const IRPosition &IRP, Attributor &A) 8707 : AAMemoryLocationImpl(IRP, A) {} 8708 8709 /// See AbstractAttribute::updateImpl(Attributor &A). 8710 ChangeStatus updateImpl(Attributor &A) override { 8711 8712 const auto &MemBehaviorAA = 8713 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE); 8714 if (MemBehaviorAA.isAssumedReadNone()) { 8715 if (MemBehaviorAA.isKnownReadNone()) 8716 return indicateOptimisticFixpoint(); 8717 assert(isAssumedReadNone() && 8718 "AAMemoryLocation was not read-none but AAMemoryBehavior was!"); 8719 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL); 8720 return ChangeStatus::UNCHANGED; 8721 } 8722 8723 // The current assumed state used to determine a change. 8724 auto AssumedState = getAssumed(); 8725 bool Changed = false; 8726 8727 auto CheckRWInst = [&](Instruction &I) { 8728 MemoryLocationsKind MLK = categorizeAccessedLocations(A, I, Changed); 8729 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I 8730 << ": " << getMemoryLocationsAsStr(MLK) << "\n"); 8731 removeAssumedBits(inverseLocation(MLK, false, false)); 8732 // Stop once only the valid bit set in the *not assumed location*, thus 8733 // once we don't actually exclude any memory locations in the state. 8734 return getAssumedNotAccessedLocation() != VALID_STATE; 8735 }; 8736 8737 bool UsedAssumedInformation = false; 8738 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this, 8739 UsedAssumedInformation)) 8740 return indicatePessimisticFixpoint(); 8741 8742 Changed |= AssumedState != getAssumed(); 8743 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 8744 } 8745 8746 /// See AbstractAttribute::trackStatistics() 8747 void trackStatistics() const override { 8748 if (isAssumedReadNone()) 8749 STATS_DECLTRACK_FN_ATTR(readnone) 8750 else if (isAssumedArgMemOnly()) 8751 STATS_DECLTRACK_FN_ATTR(argmemonly) 8752 else if (isAssumedInaccessibleMemOnly()) 8753 STATS_DECLTRACK_FN_ATTR(inaccessiblememonly) 8754 else if (isAssumedInaccessibleOrArgMemOnly()) 8755 STATS_DECLTRACK_FN_ATTR(inaccessiblememorargmemonly) 8756 } 8757 }; 8758 8759 /// AAMemoryLocation attribute for call sites. 8760 struct AAMemoryLocationCallSite final : AAMemoryLocationImpl { 8761 AAMemoryLocationCallSite(const IRPosition &IRP, Attributor &A) 8762 : AAMemoryLocationImpl(IRP, A) {} 8763 8764 /// See AbstractAttribute::initialize(...). 8765 void initialize(Attributor &A) override { 8766 AAMemoryLocationImpl::initialize(A); 8767 Function *F = getAssociatedFunction(); 8768 if (!F || F->isDeclaration()) 8769 indicatePessimisticFixpoint(); 8770 } 8771 8772 /// See AbstractAttribute::updateImpl(...). 8773 ChangeStatus updateImpl(Attributor &A) override { 8774 // TODO: Once we have call site specific value information we can provide 8775 // call site specific liveness liveness information and then it makes 8776 // sense to specialize attributes for call sites arguments instead of 8777 // redirecting requests to the callee argument. 8778 Function *F = getAssociatedFunction(); 8779 const IRPosition &FnPos = IRPosition::function(*F); 8780 auto &FnAA = 8781 A.getAAFor<AAMemoryLocation>(*this, FnPos, DepClassTy::REQUIRED); 8782 bool Changed = false; 8783 auto AccessPred = [&](const Instruction *I, const Value *Ptr, 8784 AccessKind Kind, MemoryLocationsKind MLK) { 8785 updateStateAndAccessesMap(getState(), MLK, I, Ptr, Changed, 8786 getAccessKindFromInst(I)); 8787 return true; 8788 }; 8789 if (!FnAA.checkForAllAccessesToMemoryKind(AccessPred, ALL_LOCATIONS)) 8790 return indicatePessimisticFixpoint(); 8791 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 8792 } 8793 8794 /// See AbstractAttribute::trackStatistics() 8795 void trackStatistics() const override { 8796 if (isAssumedReadNone()) 8797 STATS_DECLTRACK_CS_ATTR(readnone) 8798 } 8799 }; 8800 } // namespace 8801 8802 /// ------------------ Value Constant Range Attribute ------------------------- 8803 8804 namespace { 8805 struct AAValueConstantRangeImpl : AAValueConstantRange { 8806 using StateType = IntegerRangeState; 8807 AAValueConstantRangeImpl(const IRPosition &IRP, Attributor &A) 8808 : AAValueConstantRange(IRP, A) {} 8809 8810 /// See AbstractAttribute::initialize(..). 8811 void initialize(Attributor &A) override { 8812 if (A.hasSimplificationCallback(getIRPosition())) { 8813 indicatePessimisticFixpoint(); 8814 return; 8815 } 8816 8817 // Intersect a range given by SCEV. 8818 intersectKnown(getConstantRangeFromSCEV(A, getCtxI())); 8819 8820 // Intersect a range given by LVI. 8821 intersectKnown(getConstantRangeFromLVI(A, getCtxI())); 8822 } 8823 8824 /// See AbstractAttribute::getAsStr(). 8825 const std::string getAsStr() const override { 8826 std::string Str; 8827 llvm::raw_string_ostream OS(Str); 8828 OS << "range(" << getBitWidth() << ")<"; 8829 getKnown().print(OS); 8830 OS << " / "; 8831 getAssumed().print(OS); 8832 OS << ">"; 8833 return OS.str(); 8834 } 8835 8836 /// Helper function to get a SCEV expr for the associated value at program 8837 /// point \p I. 8838 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const { 8839 if (!getAnchorScope()) 8840 return nullptr; 8841 8842 ScalarEvolution *SE = 8843 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>( 8844 *getAnchorScope()); 8845 8846 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>( 8847 *getAnchorScope()); 8848 8849 if (!SE || !LI) 8850 return nullptr; 8851 8852 const SCEV *S = SE->getSCEV(&getAssociatedValue()); 8853 if (!I) 8854 return S; 8855 8856 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent())); 8857 } 8858 8859 /// Helper function to get a range from SCEV for the associated value at 8860 /// program point \p I. 8861 ConstantRange getConstantRangeFromSCEV(Attributor &A, 8862 const Instruction *I = nullptr) const { 8863 if (!getAnchorScope()) 8864 return getWorstState(getBitWidth()); 8865 8866 ScalarEvolution *SE = 8867 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>( 8868 *getAnchorScope()); 8869 8870 const SCEV *S = getSCEV(A, I); 8871 if (!SE || !S) 8872 return getWorstState(getBitWidth()); 8873 8874 return SE->getUnsignedRange(S); 8875 } 8876 8877 /// Helper function to get a range from LVI for the associated value at 8878 /// program point \p I. 8879 ConstantRange 8880 getConstantRangeFromLVI(Attributor &A, 8881 const Instruction *CtxI = nullptr) const { 8882 if (!getAnchorScope()) 8883 return getWorstState(getBitWidth()); 8884 8885 LazyValueInfo *LVI = 8886 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>( 8887 *getAnchorScope()); 8888 8889 if (!LVI || !CtxI) 8890 return getWorstState(getBitWidth()); 8891 return LVI->getConstantRange(&getAssociatedValue(), 8892 const_cast<Instruction *>(CtxI)); 8893 } 8894 8895 /// Return true if \p CtxI is valid for querying outside analyses. 8896 /// This basically makes sure we do not ask intra-procedural analysis 8897 /// about a context in the wrong function or a context that violates 8898 /// dominance assumptions they might have. The \p AllowAACtxI flag indicates 8899 /// if the original context of this AA is OK or should be considered invalid. 8900 bool isValidCtxInstructionForOutsideAnalysis(Attributor &A, 8901 const Instruction *CtxI, 8902 bool AllowAACtxI) const { 8903 if (!CtxI || (!AllowAACtxI && CtxI == getCtxI())) 8904 return false; 8905 8906 // Our context might be in a different function, neither intra-procedural 8907 // analysis (ScalarEvolution nor LazyValueInfo) can handle that. 8908 if (!AA::isValidInScope(getAssociatedValue(), CtxI->getFunction())) 8909 return false; 8910 8911 // If the context is not dominated by the value there are paths to the 8912 // context that do not define the value. This cannot be handled by 8913 // LazyValueInfo so we need to bail. 8914 if (auto *I = dyn_cast<Instruction>(&getAssociatedValue())) { 8915 InformationCache &InfoCache = A.getInfoCache(); 8916 const DominatorTree *DT = 8917 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>( 8918 *I->getFunction()); 8919 return DT && DT->dominates(I, CtxI); 8920 } 8921 8922 return true; 8923 } 8924 8925 /// See AAValueConstantRange::getKnownConstantRange(..). 8926 ConstantRange 8927 getKnownConstantRange(Attributor &A, 8928 const Instruction *CtxI = nullptr) const override { 8929 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI, 8930 /* AllowAACtxI */ false)) 8931 return getKnown(); 8932 8933 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI); 8934 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI); 8935 return getKnown().intersectWith(SCEVR).intersectWith(LVIR); 8936 } 8937 8938 /// See AAValueConstantRange::getAssumedConstantRange(..). 8939 ConstantRange 8940 getAssumedConstantRange(Attributor &A, 8941 const Instruction *CtxI = nullptr) const override { 8942 // TODO: Make SCEV use Attributor assumption. 8943 // We may be able to bound a variable range via assumptions in 8944 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to 8945 // evolve to x^2 + x, then we can say that y is in [2, 12]. 8946 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI, 8947 /* AllowAACtxI */ false)) 8948 return getAssumed(); 8949 8950 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI); 8951 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI); 8952 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR); 8953 } 8954 8955 /// Helper function to create MDNode for range metadata. 8956 static MDNode * 8957 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx, 8958 const ConstantRange &AssumedConstantRange) { 8959 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get( 8960 Ty, AssumedConstantRange.getLower())), 8961 ConstantAsMetadata::get(ConstantInt::get( 8962 Ty, AssumedConstantRange.getUpper()))}; 8963 return MDNode::get(Ctx, LowAndHigh); 8964 } 8965 8966 /// Return true if \p Assumed is included in \p KnownRanges. 8967 static bool isBetterRange(const ConstantRange &Assumed, MDNode *KnownRanges) { 8968 8969 if (Assumed.isFullSet()) 8970 return false; 8971 8972 if (!KnownRanges) 8973 return true; 8974 8975 // If multiple ranges are annotated in IR, we give up to annotate assumed 8976 // range for now. 8977 8978 // TODO: If there exists a known range which containts assumed range, we 8979 // can say assumed range is better. 8980 if (KnownRanges->getNumOperands() > 2) 8981 return false; 8982 8983 ConstantInt *Lower = 8984 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0)); 8985 ConstantInt *Upper = 8986 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1)); 8987 8988 ConstantRange Known(Lower->getValue(), Upper->getValue()); 8989 return Known.contains(Assumed) && Known != Assumed; 8990 } 8991 8992 /// Helper function to set range metadata. 8993 static bool 8994 setRangeMetadataIfisBetterRange(Instruction *I, 8995 const ConstantRange &AssumedConstantRange) { 8996 auto *OldRangeMD = I->getMetadata(LLVMContext::MD_range); 8997 if (isBetterRange(AssumedConstantRange, OldRangeMD)) { 8998 if (!AssumedConstantRange.isEmptySet()) { 8999 I->setMetadata(LLVMContext::MD_range, 9000 getMDNodeForConstantRange(I->getType(), I->getContext(), 9001 AssumedConstantRange)); 9002 return true; 9003 } 9004 } 9005 return false; 9006 } 9007 9008 /// See AbstractAttribute::manifest() 9009 ChangeStatus manifest(Attributor &A) override { 9010 ChangeStatus Changed = ChangeStatus::UNCHANGED; 9011 ConstantRange AssumedConstantRange = getAssumedConstantRange(A); 9012 assert(!AssumedConstantRange.isFullSet() && "Invalid state"); 9013 9014 auto &V = getAssociatedValue(); 9015 if (!AssumedConstantRange.isEmptySet() && 9016 !AssumedConstantRange.isSingleElement()) { 9017 if (Instruction *I = dyn_cast<Instruction>(&V)) { 9018 assert(I == getCtxI() && "Should not annotate an instruction which is " 9019 "not the context instruction"); 9020 if (isa<CallInst>(I) || isa<LoadInst>(I)) 9021 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange)) 9022 Changed = ChangeStatus::CHANGED; 9023 } 9024 } 9025 9026 return Changed; 9027 } 9028 }; 9029 9030 struct AAValueConstantRangeArgument final 9031 : AAArgumentFromCallSiteArguments< 9032 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState, 9033 true /* BridgeCallBaseContext */> { 9034 using Base = AAArgumentFromCallSiteArguments< 9035 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState, 9036 true /* BridgeCallBaseContext */>; 9037 AAValueConstantRangeArgument(const IRPosition &IRP, Attributor &A) 9038 : Base(IRP, A) {} 9039 9040 /// See AbstractAttribute::initialize(..). 9041 void initialize(Attributor &A) override { 9042 if (!getAnchorScope() || getAnchorScope()->isDeclaration()) { 9043 indicatePessimisticFixpoint(); 9044 } else { 9045 Base::initialize(A); 9046 } 9047 } 9048 9049 /// See AbstractAttribute::trackStatistics() 9050 void trackStatistics() const override { 9051 STATS_DECLTRACK_ARG_ATTR(value_range) 9052 } 9053 }; 9054 9055 struct AAValueConstantRangeReturned 9056 : AAReturnedFromReturnedValues<AAValueConstantRange, 9057 AAValueConstantRangeImpl, 9058 AAValueConstantRangeImpl::StateType, 9059 /* PropogateCallBaseContext */ true> { 9060 using Base = 9061 AAReturnedFromReturnedValues<AAValueConstantRange, 9062 AAValueConstantRangeImpl, 9063 AAValueConstantRangeImpl::StateType, 9064 /* PropogateCallBaseContext */ true>; 9065 AAValueConstantRangeReturned(const IRPosition &IRP, Attributor &A) 9066 : Base(IRP, A) {} 9067 9068 /// See AbstractAttribute::initialize(...). 9069 void initialize(Attributor &A) override {} 9070 9071 /// See AbstractAttribute::trackStatistics() 9072 void trackStatistics() const override { 9073 STATS_DECLTRACK_FNRET_ATTR(value_range) 9074 } 9075 }; 9076 9077 struct AAValueConstantRangeFloating : AAValueConstantRangeImpl { 9078 AAValueConstantRangeFloating(const IRPosition &IRP, Attributor &A) 9079 : AAValueConstantRangeImpl(IRP, A) {} 9080 9081 /// See AbstractAttribute::initialize(...). 9082 void initialize(Attributor &A) override { 9083 AAValueConstantRangeImpl::initialize(A); 9084 if (isAtFixpoint()) 9085 return; 9086 9087 Value &V = getAssociatedValue(); 9088 9089 if (auto *C = dyn_cast<ConstantInt>(&V)) { 9090 unionAssumed(ConstantRange(C->getValue())); 9091 indicateOptimisticFixpoint(); 9092 return; 9093 } 9094 9095 if (isa<UndefValue>(&V)) { 9096 // Collapse the undef state to 0. 9097 unionAssumed(ConstantRange(APInt(getBitWidth(), 0))); 9098 indicateOptimisticFixpoint(); 9099 return; 9100 } 9101 9102 if (isa<CallBase>(&V)) 9103 return; 9104 9105 if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V)) 9106 return; 9107 9108 // If it is a load instruction with range metadata, use it. 9109 if (LoadInst *LI = dyn_cast<LoadInst>(&V)) 9110 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) { 9111 intersectKnown(getConstantRangeFromMetadata(*RangeMD)); 9112 return; 9113 } 9114 9115 // We can work with PHI and select instruction as we traverse their operands 9116 // during update. 9117 if (isa<SelectInst>(V) || isa<PHINode>(V)) 9118 return; 9119 9120 // Otherwise we give up. 9121 indicatePessimisticFixpoint(); 9122 9123 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: " 9124 << getAssociatedValue() << "\n"); 9125 } 9126 9127 bool calculateBinaryOperator( 9128 Attributor &A, BinaryOperator *BinOp, IntegerRangeState &T, 9129 const Instruction *CtxI, 9130 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) { 9131 Value *LHS = BinOp->getOperand(0); 9132 Value *RHS = BinOp->getOperand(1); 9133 9134 // Simplify the operands first. 9135 bool UsedAssumedInformation = false; 9136 const auto &SimplifiedLHS = A.getAssumedSimplified( 9137 IRPosition::value(*LHS, getCallBaseContext()), *this, 9138 UsedAssumedInformation, AA::Interprocedural); 9139 if (!SimplifiedLHS.has_value()) 9140 return true; 9141 if (!*SimplifiedLHS) 9142 return false; 9143 LHS = *SimplifiedLHS; 9144 9145 const auto &SimplifiedRHS = A.getAssumedSimplified( 9146 IRPosition::value(*RHS, getCallBaseContext()), *this, 9147 UsedAssumedInformation, AA::Interprocedural); 9148 if (!SimplifiedRHS.has_value()) 9149 return true; 9150 if (!*SimplifiedRHS) 9151 return false; 9152 RHS = *SimplifiedRHS; 9153 9154 // TODO: Allow non integers as well. 9155 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy()) 9156 return false; 9157 9158 auto &LHSAA = A.getAAFor<AAValueConstantRange>( 9159 *this, IRPosition::value(*LHS, getCallBaseContext()), 9160 DepClassTy::REQUIRED); 9161 QuerriedAAs.push_back(&LHSAA); 9162 auto LHSAARange = LHSAA.getAssumedConstantRange(A, CtxI); 9163 9164 auto &RHSAA = A.getAAFor<AAValueConstantRange>( 9165 *this, IRPosition::value(*RHS, getCallBaseContext()), 9166 DepClassTy::REQUIRED); 9167 QuerriedAAs.push_back(&RHSAA); 9168 auto RHSAARange = RHSAA.getAssumedConstantRange(A, CtxI); 9169 9170 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange); 9171 9172 T.unionAssumed(AssumedRange); 9173 9174 // TODO: Track a known state too. 9175 9176 return T.isValidState(); 9177 } 9178 9179 bool calculateCastInst( 9180 Attributor &A, CastInst *CastI, IntegerRangeState &T, 9181 const Instruction *CtxI, 9182 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) { 9183 assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!"); 9184 // TODO: Allow non integers as well. 9185 Value *OpV = CastI->getOperand(0); 9186 9187 // Simplify the operand first. 9188 bool UsedAssumedInformation = false; 9189 const auto &SimplifiedOpV = A.getAssumedSimplified( 9190 IRPosition::value(*OpV, getCallBaseContext()), *this, 9191 UsedAssumedInformation, AA::Interprocedural); 9192 if (!SimplifiedOpV.has_value()) 9193 return true; 9194 if (!*SimplifiedOpV) 9195 return false; 9196 OpV = *SimplifiedOpV; 9197 9198 if (!OpV->getType()->isIntegerTy()) 9199 return false; 9200 9201 auto &OpAA = A.getAAFor<AAValueConstantRange>( 9202 *this, IRPosition::value(*OpV, getCallBaseContext()), 9203 DepClassTy::REQUIRED); 9204 QuerriedAAs.push_back(&OpAA); 9205 T.unionAssumed( 9206 OpAA.getAssumed().castOp(CastI->getOpcode(), getState().getBitWidth())); 9207 return T.isValidState(); 9208 } 9209 9210 bool 9211 calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T, 9212 const Instruction *CtxI, 9213 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) { 9214 Value *LHS = CmpI->getOperand(0); 9215 Value *RHS = CmpI->getOperand(1); 9216 9217 // Simplify the operands first. 9218 bool UsedAssumedInformation = false; 9219 const auto &SimplifiedLHS = A.getAssumedSimplified( 9220 IRPosition::value(*LHS, getCallBaseContext()), *this, 9221 UsedAssumedInformation, AA::Interprocedural); 9222 if (!SimplifiedLHS.has_value()) 9223 return true; 9224 if (!*SimplifiedLHS) 9225 return false; 9226 LHS = *SimplifiedLHS; 9227 9228 const auto &SimplifiedRHS = A.getAssumedSimplified( 9229 IRPosition::value(*RHS, getCallBaseContext()), *this, 9230 UsedAssumedInformation, AA::Interprocedural); 9231 if (!SimplifiedRHS.has_value()) 9232 return true; 9233 if (!*SimplifiedRHS) 9234 return false; 9235 RHS = *SimplifiedRHS; 9236 9237 // TODO: Allow non integers as well. 9238 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy()) 9239 return false; 9240 9241 auto &LHSAA = A.getAAFor<AAValueConstantRange>( 9242 *this, IRPosition::value(*LHS, getCallBaseContext()), 9243 DepClassTy::REQUIRED); 9244 QuerriedAAs.push_back(&LHSAA); 9245 auto &RHSAA = A.getAAFor<AAValueConstantRange>( 9246 *this, IRPosition::value(*RHS, getCallBaseContext()), 9247 DepClassTy::REQUIRED); 9248 QuerriedAAs.push_back(&RHSAA); 9249 auto LHSAARange = LHSAA.getAssumedConstantRange(A, CtxI); 9250 auto RHSAARange = RHSAA.getAssumedConstantRange(A, CtxI); 9251 9252 // If one of them is empty set, we can't decide. 9253 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet()) 9254 return true; 9255 9256 bool MustTrue = false, MustFalse = false; 9257 9258 auto AllowedRegion = 9259 ConstantRange::makeAllowedICmpRegion(CmpI->getPredicate(), RHSAARange); 9260 9261 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet()) 9262 MustFalse = true; 9263 9264 if (LHSAARange.icmp(CmpI->getPredicate(), RHSAARange)) 9265 MustTrue = true; 9266 9267 assert((!MustTrue || !MustFalse) && 9268 "Either MustTrue or MustFalse should be false!"); 9269 9270 if (MustTrue) 9271 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1))); 9272 else if (MustFalse) 9273 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0))); 9274 else 9275 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true)); 9276 9277 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " " << LHSAA 9278 << " " << RHSAA << "\n"); 9279 9280 // TODO: Track a known state too. 9281 return T.isValidState(); 9282 } 9283 9284 /// See AbstractAttribute::updateImpl(...). 9285 ChangeStatus updateImpl(Attributor &A) override { 9286 9287 IntegerRangeState T(getBitWidth()); 9288 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool { 9289 Instruction *I = dyn_cast<Instruction>(&V); 9290 if (!I || isa<CallBase>(I)) { 9291 9292 // Simplify the operand first. 9293 bool UsedAssumedInformation = false; 9294 const auto &SimplifiedOpV = A.getAssumedSimplified( 9295 IRPosition::value(V, getCallBaseContext()), *this, 9296 UsedAssumedInformation, AA::Interprocedural); 9297 if (!SimplifiedOpV.has_value()) 9298 return true; 9299 if (!*SimplifiedOpV) 9300 return false; 9301 Value *VPtr = *SimplifiedOpV; 9302 9303 // If the value is not instruction, we query AA to Attributor. 9304 const auto &AA = A.getAAFor<AAValueConstantRange>( 9305 *this, IRPosition::value(*VPtr, getCallBaseContext()), 9306 DepClassTy::REQUIRED); 9307 9308 // Clamp operator is not used to utilize a program point CtxI. 9309 T.unionAssumed(AA.getAssumedConstantRange(A, CtxI)); 9310 9311 return T.isValidState(); 9312 } 9313 9314 SmallVector<const AAValueConstantRange *, 4> QuerriedAAs; 9315 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) { 9316 if (!calculateBinaryOperator(A, BinOp, T, CtxI, QuerriedAAs)) 9317 return false; 9318 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) { 9319 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs)) 9320 return false; 9321 } else if (auto *CastI = dyn_cast<CastInst>(I)) { 9322 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs)) 9323 return false; 9324 } else { 9325 // Give up with other instructions. 9326 // TODO: Add other instructions 9327 9328 T.indicatePessimisticFixpoint(); 9329 return false; 9330 } 9331 9332 // Catch circular reasoning in a pessimistic way for now. 9333 // TODO: Check how the range evolves and if we stripped anything, see also 9334 // AADereferenceable or AAAlign for similar situations. 9335 for (const AAValueConstantRange *QueriedAA : QuerriedAAs) { 9336 if (QueriedAA != this) 9337 continue; 9338 // If we are in a stady state we do not need to worry. 9339 if (T.getAssumed() == getState().getAssumed()) 9340 continue; 9341 T.indicatePessimisticFixpoint(); 9342 } 9343 9344 return T.isValidState(); 9345 }; 9346 9347 if (!VisitValueCB(getAssociatedValue(), getCtxI())) 9348 return indicatePessimisticFixpoint(); 9349 9350 // Ensure that long def-use chains can't cause circular reasoning either by 9351 // introducing a cutoff below. 9352 if (clampStateAndIndicateChange(getState(), T) == ChangeStatus::UNCHANGED) 9353 return ChangeStatus::UNCHANGED; 9354 if (++NumChanges > MaxNumChanges) { 9355 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] performed " << NumChanges 9356 << " but only " << MaxNumChanges 9357 << " are allowed to avoid cyclic reasoning."); 9358 return indicatePessimisticFixpoint(); 9359 } 9360 return ChangeStatus::CHANGED; 9361 } 9362 9363 /// See AbstractAttribute::trackStatistics() 9364 void trackStatistics() const override { 9365 STATS_DECLTRACK_FLOATING_ATTR(value_range) 9366 } 9367 9368 /// Tracker to bail after too many widening steps of the constant range. 9369 int NumChanges = 0; 9370 9371 /// Upper bound for the number of allowed changes (=widening steps) for the 9372 /// constant range before we give up. 9373 static constexpr int MaxNumChanges = 5; 9374 }; 9375 9376 struct AAValueConstantRangeFunction : AAValueConstantRangeImpl { 9377 AAValueConstantRangeFunction(const IRPosition &IRP, Attributor &A) 9378 : AAValueConstantRangeImpl(IRP, A) {} 9379 9380 /// See AbstractAttribute::initialize(...). 9381 ChangeStatus updateImpl(Attributor &A) override { 9382 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will " 9383 "not be called"); 9384 } 9385 9386 /// See AbstractAttribute::trackStatistics() 9387 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) } 9388 }; 9389 9390 struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction { 9391 AAValueConstantRangeCallSite(const IRPosition &IRP, Attributor &A) 9392 : AAValueConstantRangeFunction(IRP, A) {} 9393 9394 /// See AbstractAttribute::trackStatistics() 9395 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) } 9396 }; 9397 9398 struct AAValueConstantRangeCallSiteReturned 9399 : AACallSiteReturnedFromReturned<AAValueConstantRange, 9400 AAValueConstantRangeImpl, 9401 AAValueConstantRangeImpl::StateType, 9402 /* IntroduceCallBaseContext */ true> { 9403 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP, Attributor &A) 9404 : AACallSiteReturnedFromReturned<AAValueConstantRange, 9405 AAValueConstantRangeImpl, 9406 AAValueConstantRangeImpl::StateType, 9407 /* IntroduceCallBaseContext */ true>(IRP, 9408 A) { 9409 } 9410 9411 /// See AbstractAttribute::initialize(...). 9412 void initialize(Attributor &A) override { 9413 // If it is a load instruction with range metadata, use the metadata. 9414 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue())) 9415 if (auto *RangeMD = CI->getMetadata(LLVMContext::MD_range)) 9416 intersectKnown(getConstantRangeFromMetadata(*RangeMD)); 9417 9418 AAValueConstantRangeImpl::initialize(A); 9419 } 9420 9421 /// See AbstractAttribute::trackStatistics() 9422 void trackStatistics() const override { 9423 STATS_DECLTRACK_CSRET_ATTR(value_range) 9424 } 9425 }; 9426 struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating { 9427 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP, Attributor &A) 9428 : AAValueConstantRangeFloating(IRP, A) {} 9429 9430 /// See AbstractAttribute::manifest() 9431 ChangeStatus manifest(Attributor &A) override { 9432 return ChangeStatus::UNCHANGED; 9433 } 9434 9435 /// See AbstractAttribute::trackStatistics() 9436 void trackStatistics() const override { 9437 STATS_DECLTRACK_CSARG_ATTR(value_range) 9438 } 9439 }; 9440 } // namespace 9441 9442 /// ------------------ Potential Values Attribute ------------------------- 9443 9444 namespace { 9445 struct AAPotentialConstantValuesImpl : AAPotentialConstantValues { 9446 using StateType = PotentialConstantIntValuesState; 9447 9448 AAPotentialConstantValuesImpl(const IRPosition &IRP, Attributor &A) 9449 : AAPotentialConstantValues(IRP, A) {} 9450 9451 /// See AbstractAttribute::initialize(..). 9452 void initialize(Attributor &A) override { 9453 if (A.hasSimplificationCallback(getIRPosition())) 9454 indicatePessimisticFixpoint(); 9455 else 9456 AAPotentialConstantValues::initialize(A); 9457 } 9458 9459 bool fillSetWithConstantValues(Attributor &A, const IRPosition &IRP, SetTy &S, 9460 bool &ContainsUndef, bool ForSelf) { 9461 SmallVector<AA::ValueAndContext> Values; 9462 bool UsedAssumedInformation = false; 9463 if (!A.getAssumedSimplifiedValues(IRP, *this, Values, AA::Interprocedural, 9464 UsedAssumedInformation)) { 9465 // Avoid recursion when the caller is computing constant values for this 9466 // IRP itself. 9467 if (ForSelf) 9468 return false; 9469 if (!IRP.getAssociatedType()->isIntegerTy()) 9470 return false; 9471 auto &PotentialValuesAA = A.getAAFor<AAPotentialConstantValues>( 9472 *this, IRP, DepClassTy::REQUIRED); 9473 if (!PotentialValuesAA.getState().isValidState()) 9474 return false; 9475 ContainsUndef = PotentialValuesAA.getState().undefIsContained(); 9476 S = PotentialValuesAA.getState().getAssumedSet(); 9477 return true; 9478 } 9479 9480 // Copy all the constant values, except UndefValue. ContainsUndef is true 9481 // iff Values contains only UndefValue instances. If there are other known 9482 // constants, then UndefValue is dropped. 9483 ContainsUndef = false; 9484 for (auto &It : Values) { 9485 if (isa<UndefValue>(It.getValue())) { 9486 ContainsUndef = true; 9487 continue; 9488 } 9489 auto *CI = dyn_cast<ConstantInt>(It.getValue()); 9490 if (!CI) 9491 return false; 9492 S.insert(CI->getValue()); 9493 } 9494 ContainsUndef &= S.empty(); 9495 9496 return true; 9497 } 9498 9499 /// See AbstractAttribute::getAsStr(). 9500 const std::string getAsStr() const override { 9501 std::string Str; 9502 llvm::raw_string_ostream OS(Str); 9503 OS << getState(); 9504 return OS.str(); 9505 } 9506 9507 /// See AbstractAttribute::updateImpl(...). 9508 ChangeStatus updateImpl(Attributor &A) override { 9509 return indicatePessimisticFixpoint(); 9510 } 9511 }; 9512 9513 struct AAPotentialConstantValuesArgument final 9514 : AAArgumentFromCallSiteArguments<AAPotentialConstantValues, 9515 AAPotentialConstantValuesImpl, 9516 PotentialConstantIntValuesState> { 9517 using Base = AAArgumentFromCallSiteArguments<AAPotentialConstantValues, 9518 AAPotentialConstantValuesImpl, 9519 PotentialConstantIntValuesState>; 9520 AAPotentialConstantValuesArgument(const IRPosition &IRP, Attributor &A) 9521 : Base(IRP, A) {} 9522 9523 /// See AbstractAttribute::initialize(..). 9524 void initialize(Attributor &A) override { 9525 if (!getAnchorScope() || getAnchorScope()->isDeclaration()) { 9526 indicatePessimisticFixpoint(); 9527 } else { 9528 Base::initialize(A); 9529 } 9530 } 9531 9532 /// See AbstractAttribute::trackStatistics() 9533 void trackStatistics() const override { 9534 STATS_DECLTRACK_ARG_ATTR(potential_values) 9535 } 9536 }; 9537 9538 struct AAPotentialConstantValuesReturned 9539 : AAReturnedFromReturnedValues<AAPotentialConstantValues, 9540 AAPotentialConstantValuesImpl> { 9541 using Base = AAReturnedFromReturnedValues<AAPotentialConstantValues, 9542 AAPotentialConstantValuesImpl>; 9543 AAPotentialConstantValuesReturned(const IRPosition &IRP, Attributor &A) 9544 : Base(IRP, A) {} 9545 9546 /// See AbstractAttribute::trackStatistics() 9547 void trackStatistics() const override { 9548 STATS_DECLTRACK_FNRET_ATTR(potential_values) 9549 } 9550 }; 9551 9552 struct AAPotentialConstantValuesFloating : AAPotentialConstantValuesImpl { 9553 AAPotentialConstantValuesFloating(const IRPosition &IRP, Attributor &A) 9554 : AAPotentialConstantValuesImpl(IRP, A) {} 9555 9556 /// See AbstractAttribute::initialize(..). 9557 void initialize(Attributor &A) override { 9558 AAPotentialConstantValuesImpl::initialize(A); 9559 if (isAtFixpoint()) 9560 return; 9561 9562 Value &V = getAssociatedValue(); 9563 9564 if (auto *C = dyn_cast<ConstantInt>(&V)) { 9565 unionAssumed(C->getValue()); 9566 indicateOptimisticFixpoint(); 9567 return; 9568 } 9569 9570 if (isa<UndefValue>(&V)) { 9571 unionAssumedWithUndef(); 9572 indicateOptimisticFixpoint(); 9573 return; 9574 } 9575 9576 if (isa<BinaryOperator>(&V) || isa<ICmpInst>(&V) || isa<CastInst>(&V)) 9577 return; 9578 9579 if (isa<SelectInst>(V) || isa<PHINode>(V) || isa<LoadInst>(V)) 9580 return; 9581 9582 indicatePessimisticFixpoint(); 9583 9584 LLVM_DEBUG(dbgs() << "[AAPotentialConstantValues] We give up: " 9585 << getAssociatedValue() << "\n"); 9586 } 9587 9588 static bool calculateICmpInst(const ICmpInst *ICI, const APInt &LHS, 9589 const APInt &RHS) { 9590 return ICmpInst::compare(LHS, RHS, ICI->getPredicate()); 9591 } 9592 9593 static APInt calculateCastInst(const CastInst *CI, const APInt &Src, 9594 uint32_t ResultBitWidth) { 9595 Instruction::CastOps CastOp = CI->getOpcode(); 9596 switch (CastOp) { 9597 default: 9598 llvm_unreachable("unsupported or not integer cast"); 9599 case Instruction::Trunc: 9600 return Src.trunc(ResultBitWidth); 9601 case Instruction::SExt: 9602 return Src.sext(ResultBitWidth); 9603 case Instruction::ZExt: 9604 return Src.zext(ResultBitWidth); 9605 case Instruction::BitCast: 9606 return Src; 9607 } 9608 } 9609 9610 static APInt calculateBinaryOperator(const BinaryOperator *BinOp, 9611 const APInt &LHS, const APInt &RHS, 9612 bool &SkipOperation, bool &Unsupported) { 9613 Instruction::BinaryOps BinOpcode = BinOp->getOpcode(); 9614 // Unsupported is set to true when the binary operator is not supported. 9615 // SkipOperation is set to true when UB occur with the given operand pair 9616 // (LHS, RHS). 9617 // TODO: we should look at nsw and nuw keywords to handle operations 9618 // that create poison or undef value. 9619 switch (BinOpcode) { 9620 default: 9621 Unsupported = true; 9622 return LHS; 9623 case Instruction::Add: 9624 return LHS + RHS; 9625 case Instruction::Sub: 9626 return LHS - RHS; 9627 case Instruction::Mul: 9628 return LHS * RHS; 9629 case Instruction::UDiv: 9630 if (RHS.isZero()) { 9631 SkipOperation = true; 9632 return LHS; 9633 } 9634 return LHS.udiv(RHS); 9635 case Instruction::SDiv: 9636 if (RHS.isZero()) { 9637 SkipOperation = true; 9638 return LHS; 9639 } 9640 return LHS.sdiv(RHS); 9641 case Instruction::URem: 9642 if (RHS.isZero()) { 9643 SkipOperation = true; 9644 return LHS; 9645 } 9646 return LHS.urem(RHS); 9647 case Instruction::SRem: 9648 if (RHS.isZero()) { 9649 SkipOperation = true; 9650 return LHS; 9651 } 9652 return LHS.srem(RHS); 9653 case Instruction::Shl: 9654 return LHS.shl(RHS); 9655 case Instruction::LShr: 9656 return LHS.lshr(RHS); 9657 case Instruction::AShr: 9658 return LHS.ashr(RHS); 9659 case Instruction::And: 9660 return LHS & RHS; 9661 case Instruction::Or: 9662 return LHS | RHS; 9663 case Instruction::Xor: 9664 return LHS ^ RHS; 9665 } 9666 } 9667 9668 bool calculateBinaryOperatorAndTakeUnion(const BinaryOperator *BinOp, 9669 const APInt &LHS, const APInt &RHS) { 9670 bool SkipOperation = false; 9671 bool Unsupported = false; 9672 APInt Result = 9673 calculateBinaryOperator(BinOp, LHS, RHS, SkipOperation, Unsupported); 9674 if (Unsupported) 9675 return false; 9676 // If SkipOperation is true, we can ignore this operand pair (L, R). 9677 if (!SkipOperation) 9678 unionAssumed(Result); 9679 return isValidState(); 9680 } 9681 9682 ChangeStatus updateWithICmpInst(Attributor &A, ICmpInst *ICI) { 9683 auto AssumedBefore = getAssumed(); 9684 Value *LHS = ICI->getOperand(0); 9685 Value *RHS = ICI->getOperand(1); 9686 9687 bool LHSContainsUndef = false, RHSContainsUndef = false; 9688 SetTy LHSAAPVS, RHSAAPVS; 9689 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS, 9690 LHSContainsUndef, /* ForSelf */ false) || 9691 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS, 9692 RHSContainsUndef, /* ForSelf */ false)) 9693 return indicatePessimisticFixpoint(); 9694 9695 // TODO: make use of undef flag to limit potential values aggressively. 9696 bool MaybeTrue = false, MaybeFalse = false; 9697 const APInt Zero(RHS->getType()->getIntegerBitWidth(), 0); 9698 if (LHSContainsUndef && RHSContainsUndef) { 9699 // The result of any comparison between undefs can be soundly replaced 9700 // with undef. 9701 unionAssumedWithUndef(); 9702 } else if (LHSContainsUndef) { 9703 for (const APInt &R : RHSAAPVS) { 9704 bool CmpResult = calculateICmpInst(ICI, Zero, R); 9705 MaybeTrue |= CmpResult; 9706 MaybeFalse |= !CmpResult; 9707 if (MaybeTrue & MaybeFalse) 9708 return indicatePessimisticFixpoint(); 9709 } 9710 } else if (RHSContainsUndef) { 9711 for (const APInt &L : LHSAAPVS) { 9712 bool CmpResult = calculateICmpInst(ICI, L, Zero); 9713 MaybeTrue |= CmpResult; 9714 MaybeFalse |= !CmpResult; 9715 if (MaybeTrue & MaybeFalse) 9716 return indicatePessimisticFixpoint(); 9717 } 9718 } else { 9719 for (const APInt &L : LHSAAPVS) { 9720 for (const APInt &R : RHSAAPVS) { 9721 bool CmpResult = calculateICmpInst(ICI, L, R); 9722 MaybeTrue |= CmpResult; 9723 MaybeFalse |= !CmpResult; 9724 if (MaybeTrue & MaybeFalse) 9725 return indicatePessimisticFixpoint(); 9726 } 9727 } 9728 } 9729 if (MaybeTrue) 9730 unionAssumed(APInt(/* numBits */ 1, /* val */ 1)); 9731 if (MaybeFalse) 9732 unionAssumed(APInt(/* numBits */ 1, /* val */ 0)); 9733 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 9734 : ChangeStatus::CHANGED; 9735 } 9736 9737 ChangeStatus updateWithSelectInst(Attributor &A, SelectInst *SI) { 9738 auto AssumedBefore = getAssumed(); 9739 Value *LHS = SI->getTrueValue(); 9740 Value *RHS = SI->getFalseValue(); 9741 9742 bool UsedAssumedInformation = false; 9743 std::optional<Constant *> C = A.getAssumedConstant( 9744 *SI->getCondition(), *this, UsedAssumedInformation); 9745 9746 // Check if we only need one operand. 9747 bool OnlyLeft = false, OnlyRight = false; 9748 if (C && *C && (*C)->isOneValue()) 9749 OnlyLeft = true; 9750 else if (C && *C && (*C)->isZeroValue()) 9751 OnlyRight = true; 9752 9753 bool LHSContainsUndef = false, RHSContainsUndef = false; 9754 SetTy LHSAAPVS, RHSAAPVS; 9755 if (!OnlyRight && 9756 !fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS, 9757 LHSContainsUndef, /* ForSelf */ false)) 9758 return indicatePessimisticFixpoint(); 9759 9760 if (!OnlyLeft && 9761 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS, 9762 RHSContainsUndef, /* ForSelf */ false)) 9763 return indicatePessimisticFixpoint(); 9764 9765 if (OnlyLeft || OnlyRight) { 9766 // select (true/false), lhs, rhs 9767 auto *OpAA = OnlyLeft ? &LHSAAPVS : &RHSAAPVS; 9768 auto Undef = OnlyLeft ? LHSContainsUndef : RHSContainsUndef; 9769 9770 if (Undef) 9771 unionAssumedWithUndef(); 9772 else { 9773 for (const auto &It : *OpAA) 9774 unionAssumed(It); 9775 } 9776 9777 } else if (LHSContainsUndef && RHSContainsUndef) { 9778 // select i1 *, undef , undef => undef 9779 unionAssumedWithUndef(); 9780 } else { 9781 for (const auto &It : LHSAAPVS) 9782 unionAssumed(It); 9783 for (const auto &It : RHSAAPVS) 9784 unionAssumed(It); 9785 } 9786 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 9787 : ChangeStatus::CHANGED; 9788 } 9789 9790 ChangeStatus updateWithCastInst(Attributor &A, CastInst *CI) { 9791 auto AssumedBefore = getAssumed(); 9792 if (!CI->isIntegerCast()) 9793 return indicatePessimisticFixpoint(); 9794 assert(CI->getNumOperands() == 1 && "Expected cast to be unary!"); 9795 uint32_t ResultBitWidth = CI->getDestTy()->getIntegerBitWidth(); 9796 Value *Src = CI->getOperand(0); 9797 9798 bool SrcContainsUndef = false; 9799 SetTy SrcPVS; 9800 if (!fillSetWithConstantValues(A, IRPosition::value(*Src), SrcPVS, 9801 SrcContainsUndef, /* ForSelf */ false)) 9802 return indicatePessimisticFixpoint(); 9803 9804 if (SrcContainsUndef) 9805 unionAssumedWithUndef(); 9806 else { 9807 for (const APInt &S : SrcPVS) { 9808 APInt T = calculateCastInst(CI, S, ResultBitWidth); 9809 unionAssumed(T); 9810 } 9811 } 9812 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 9813 : ChangeStatus::CHANGED; 9814 } 9815 9816 ChangeStatus updateWithBinaryOperator(Attributor &A, BinaryOperator *BinOp) { 9817 auto AssumedBefore = getAssumed(); 9818 Value *LHS = BinOp->getOperand(0); 9819 Value *RHS = BinOp->getOperand(1); 9820 9821 bool LHSContainsUndef = false, RHSContainsUndef = false; 9822 SetTy LHSAAPVS, RHSAAPVS; 9823 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS, 9824 LHSContainsUndef, /* ForSelf */ false) || 9825 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS, 9826 RHSContainsUndef, /* ForSelf */ false)) 9827 return indicatePessimisticFixpoint(); 9828 9829 const APInt Zero = APInt(LHS->getType()->getIntegerBitWidth(), 0); 9830 9831 // TODO: make use of undef flag to limit potential values aggressively. 9832 if (LHSContainsUndef && RHSContainsUndef) { 9833 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, Zero)) 9834 return indicatePessimisticFixpoint(); 9835 } else if (LHSContainsUndef) { 9836 for (const APInt &R : RHSAAPVS) { 9837 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, R)) 9838 return indicatePessimisticFixpoint(); 9839 } 9840 } else if (RHSContainsUndef) { 9841 for (const APInt &L : LHSAAPVS) { 9842 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, Zero)) 9843 return indicatePessimisticFixpoint(); 9844 } 9845 } else { 9846 for (const APInt &L : LHSAAPVS) { 9847 for (const APInt &R : RHSAAPVS) { 9848 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, R)) 9849 return indicatePessimisticFixpoint(); 9850 } 9851 } 9852 } 9853 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 9854 : ChangeStatus::CHANGED; 9855 } 9856 9857 ChangeStatus updateWithInstruction(Attributor &A, Instruction *Inst) { 9858 auto AssumedBefore = getAssumed(); 9859 SetTy Incoming; 9860 bool ContainsUndef; 9861 if (!fillSetWithConstantValues(A, IRPosition::value(*Inst), Incoming, 9862 ContainsUndef, /* ForSelf */ true)) 9863 return indicatePessimisticFixpoint(); 9864 if (ContainsUndef) { 9865 unionAssumedWithUndef(); 9866 } else { 9867 for (const auto &It : Incoming) 9868 unionAssumed(It); 9869 } 9870 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 9871 : ChangeStatus::CHANGED; 9872 } 9873 9874 /// See AbstractAttribute::updateImpl(...). 9875 ChangeStatus updateImpl(Attributor &A) override { 9876 Value &V = getAssociatedValue(); 9877 Instruction *I = dyn_cast<Instruction>(&V); 9878 9879 if (auto *ICI = dyn_cast<ICmpInst>(I)) 9880 return updateWithICmpInst(A, ICI); 9881 9882 if (auto *SI = dyn_cast<SelectInst>(I)) 9883 return updateWithSelectInst(A, SI); 9884 9885 if (auto *CI = dyn_cast<CastInst>(I)) 9886 return updateWithCastInst(A, CI); 9887 9888 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) 9889 return updateWithBinaryOperator(A, BinOp); 9890 9891 if (isa<PHINode>(I) || isa<LoadInst>(I)) 9892 return updateWithInstruction(A, I); 9893 9894 return indicatePessimisticFixpoint(); 9895 } 9896 9897 /// See AbstractAttribute::trackStatistics() 9898 void trackStatistics() const override { 9899 STATS_DECLTRACK_FLOATING_ATTR(potential_values) 9900 } 9901 }; 9902 9903 struct AAPotentialConstantValuesFunction : AAPotentialConstantValuesImpl { 9904 AAPotentialConstantValuesFunction(const IRPosition &IRP, Attributor &A) 9905 : AAPotentialConstantValuesImpl(IRP, A) {} 9906 9907 /// See AbstractAttribute::initialize(...). 9908 ChangeStatus updateImpl(Attributor &A) override { 9909 llvm_unreachable( 9910 "AAPotentialConstantValues(Function|CallSite)::updateImpl will " 9911 "not be called"); 9912 } 9913 9914 /// See AbstractAttribute::trackStatistics() 9915 void trackStatistics() const override { 9916 STATS_DECLTRACK_FN_ATTR(potential_values) 9917 } 9918 }; 9919 9920 struct AAPotentialConstantValuesCallSite : AAPotentialConstantValuesFunction { 9921 AAPotentialConstantValuesCallSite(const IRPosition &IRP, Attributor &A) 9922 : AAPotentialConstantValuesFunction(IRP, A) {} 9923 9924 /// See AbstractAttribute::trackStatistics() 9925 void trackStatistics() const override { 9926 STATS_DECLTRACK_CS_ATTR(potential_values) 9927 } 9928 }; 9929 9930 struct AAPotentialConstantValuesCallSiteReturned 9931 : AACallSiteReturnedFromReturned<AAPotentialConstantValues, 9932 AAPotentialConstantValuesImpl> { 9933 AAPotentialConstantValuesCallSiteReturned(const IRPosition &IRP, 9934 Attributor &A) 9935 : AACallSiteReturnedFromReturned<AAPotentialConstantValues, 9936 AAPotentialConstantValuesImpl>(IRP, A) {} 9937 9938 /// See AbstractAttribute::trackStatistics() 9939 void trackStatistics() const override { 9940 STATS_DECLTRACK_CSRET_ATTR(potential_values) 9941 } 9942 }; 9943 9944 struct AAPotentialConstantValuesCallSiteArgument 9945 : AAPotentialConstantValuesFloating { 9946 AAPotentialConstantValuesCallSiteArgument(const IRPosition &IRP, 9947 Attributor &A) 9948 : AAPotentialConstantValuesFloating(IRP, A) {} 9949 9950 /// See AbstractAttribute::initialize(..). 9951 void initialize(Attributor &A) override { 9952 AAPotentialConstantValuesImpl::initialize(A); 9953 if (isAtFixpoint()) 9954 return; 9955 9956 Value &V = getAssociatedValue(); 9957 9958 if (auto *C = dyn_cast<ConstantInt>(&V)) { 9959 unionAssumed(C->getValue()); 9960 indicateOptimisticFixpoint(); 9961 return; 9962 } 9963 9964 if (isa<UndefValue>(&V)) { 9965 unionAssumedWithUndef(); 9966 indicateOptimisticFixpoint(); 9967 return; 9968 } 9969 } 9970 9971 /// See AbstractAttribute::updateImpl(...). 9972 ChangeStatus updateImpl(Attributor &A) override { 9973 Value &V = getAssociatedValue(); 9974 auto AssumedBefore = getAssumed(); 9975 auto &AA = A.getAAFor<AAPotentialConstantValues>( 9976 *this, IRPosition::value(V), DepClassTy::REQUIRED); 9977 const auto &S = AA.getAssumed(); 9978 unionAssumed(S); 9979 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 9980 : ChangeStatus::CHANGED; 9981 } 9982 9983 /// See AbstractAttribute::trackStatistics() 9984 void trackStatistics() const override { 9985 STATS_DECLTRACK_CSARG_ATTR(potential_values) 9986 } 9987 }; 9988 9989 /// ------------------------ NoUndef Attribute --------------------------------- 9990 struct AANoUndefImpl : AANoUndef { 9991 AANoUndefImpl(const IRPosition &IRP, Attributor &A) : AANoUndef(IRP, A) {} 9992 9993 /// See AbstractAttribute::initialize(...). 9994 void initialize(Attributor &A) override { 9995 if (getIRPosition().hasAttr({Attribute::NoUndef})) { 9996 indicateOptimisticFixpoint(); 9997 return; 9998 } 9999 Value &V = getAssociatedValue(); 10000 if (isa<UndefValue>(V)) 10001 indicatePessimisticFixpoint(); 10002 else if (isa<FreezeInst>(V)) 10003 indicateOptimisticFixpoint(); 10004 else if (getPositionKind() != IRPosition::IRP_RETURNED && 10005 isGuaranteedNotToBeUndefOrPoison(&V)) 10006 indicateOptimisticFixpoint(); 10007 else 10008 AANoUndef::initialize(A); 10009 } 10010 10011 /// See followUsesInMBEC 10012 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I, 10013 AANoUndef::StateType &State) { 10014 const Value *UseV = U->get(); 10015 const DominatorTree *DT = nullptr; 10016 AssumptionCache *AC = nullptr; 10017 InformationCache &InfoCache = A.getInfoCache(); 10018 if (Function *F = getAnchorScope()) { 10019 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F); 10020 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F); 10021 } 10022 State.setKnown(isGuaranteedNotToBeUndefOrPoison(UseV, AC, I, DT)); 10023 bool TrackUse = false; 10024 // Track use for instructions which must produce undef or poison bits when 10025 // at least one operand contains such bits. 10026 if (isa<CastInst>(*I) || isa<GetElementPtrInst>(*I)) 10027 TrackUse = true; 10028 return TrackUse; 10029 } 10030 10031 /// See AbstractAttribute::getAsStr(). 10032 const std::string getAsStr() const override { 10033 return getAssumed() ? "noundef" : "may-undef-or-poison"; 10034 } 10035 10036 ChangeStatus manifest(Attributor &A) override { 10037 // We don't manifest noundef attribute for dead positions because the 10038 // associated values with dead positions would be replaced with undef 10039 // values. 10040 bool UsedAssumedInformation = false; 10041 if (A.isAssumedDead(getIRPosition(), nullptr, nullptr, 10042 UsedAssumedInformation)) 10043 return ChangeStatus::UNCHANGED; 10044 // A position whose simplified value does not have any value is 10045 // considered to be dead. We don't manifest noundef in such positions for 10046 // the same reason above. 10047 if (!A.getAssumedSimplified(getIRPosition(), *this, UsedAssumedInformation, 10048 AA::Interprocedural) 10049 .has_value()) 10050 return ChangeStatus::UNCHANGED; 10051 return AANoUndef::manifest(A); 10052 } 10053 }; 10054 10055 struct AANoUndefFloating : public AANoUndefImpl { 10056 AANoUndefFloating(const IRPosition &IRP, Attributor &A) 10057 : AANoUndefImpl(IRP, A) {} 10058 10059 /// See AbstractAttribute::initialize(...). 10060 void initialize(Attributor &A) override { 10061 AANoUndefImpl::initialize(A); 10062 if (!getState().isAtFixpoint()) 10063 if (Instruction *CtxI = getCtxI()) 10064 followUsesInMBEC(*this, A, getState(), *CtxI); 10065 } 10066 10067 /// See AbstractAttribute::updateImpl(...). 10068 ChangeStatus updateImpl(Attributor &A) override { 10069 10070 SmallVector<AA::ValueAndContext> Values; 10071 bool UsedAssumedInformation = false; 10072 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values, 10073 AA::AnyScope, UsedAssumedInformation)) { 10074 Values.push_back({getAssociatedValue(), getCtxI()}); 10075 } 10076 10077 StateType T; 10078 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool { 10079 const auto &AA = A.getAAFor<AANoUndef>(*this, IRPosition::value(V), 10080 DepClassTy::REQUIRED); 10081 if (this == &AA) { 10082 T.indicatePessimisticFixpoint(); 10083 } else { 10084 const AANoUndef::StateType &S = 10085 static_cast<const AANoUndef::StateType &>(AA.getState()); 10086 T ^= S; 10087 } 10088 return T.isValidState(); 10089 }; 10090 10091 for (const auto &VAC : Values) 10092 if (!VisitValueCB(*VAC.getValue(), VAC.getCtxI())) 10093 return indicatePessimisticFixpoint(); 10094 10095 return clampStateAndIndicateChange(getState(), T); 10096 } 10097 10098 /// See AbstractAttribute::trackStatistics() 10099 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) } 10100 }; 10101 10102 struct AANoUndefReturned final 10103 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl> { 10104 AANoUndefReturned(const IRPosition &IRP, Attributor &A) 10105 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl>(IRP, A) {} 10106 10107 /// See AbstractAttribute::trackStatistics() 10108 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) } 10109 }; 10110 10111 struct AANoUndefArgument final 10112 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl> { 10113 AANoUndefArgument(const IRPosition &IRP, Attributor &A) 10114 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl>(IRP, A) {} 10115 10116 /// See AbstractAttribute::trackStatistics() 10117 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noundef) } 10118 }; 10119 10120 struct AANoUndefCallSiteArgument final : AANoUndefFloating { 10121 AANoUndefCallSiteArgument(const IRPosition &IRP, Attributor &A) 10122 : AANoUndefFloating(IRP, A) {} 10123 10124 /// See AbstractAttribute::trackStatistics() 10125 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noundef) } 10126 }; 10127 10128 struct AANoUndefCallSiteReturned final 10129 : AACallSiteReturnedFromReturned<AANoUndef, AANoUndefImpl> { 10130 AANoUndefCallSiteReturned(const IRPosition &IRP, Attributor &A) 10131 : AACallSiteReturnedFromReturned<AANoUndef, AANoUndefImpl>(IRP, A) {} 10132 10133 /// See AbstractAttribute::trackStatistics() 10134 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) } 10135 }; 10136 10137 struct AACallEdgesImpl : public AACallEdges { 10138 AACallEdgesImpl(const IRPosition &IRP, Attributor &A) : AACallEdges(IRP, A) {} 10139 10140 const SetVector<Function *> &getOptimisticEdges() const override { 10141 return CalledFunctions; 10142 } 10143 10144 bool hasUnknownCallee() const override { return HasUnknownCallee; } 10145 10146 bool hasNonAsmUnknownCallee() const override { 10147 return HasUnknownCalleeNonAsm; 10148 } 10149 10150 const std::string getAsStr() const override { 10151 return "CallEdges[" + std::to_string(HasUnknownCallee) + "," + 10152 std::to_string(CalledFunctions.size()) + "]"; 10153 } 10154 10155 void trackStatistics() const override {} 10156 10157 protected: 10158 void addCalledFunction(Function *Fn, ChangeStatus &Change) { 10159 if (CalledFunctions.insert(Fn)) { 10160 Change = ChangeStatus::CHANGED; 10161 LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn->getName() 10162 << "\n"); 10163 } 10164 } 10165 10166 void setHasUnknownCallee(bool NonAsm, ChangeStatus &Change) { 10167 if (!HasUnknownCallee) 10168 Change = ChangeStatus::CHANGED; 10169 if (NonAsm && !HasUnknownCalleeNonAsm) 10170 Change = ChangeStatus::CHANGED; 10171 HasUnknownCalleeNonAsm |= NonAsm; 10172 HasUnknownCallee = true; 10173 } 10174 10175 private: 10176 /// Optimistic set of functions that might be called by this position. 10177 SetVector<Function *> CalledFunctions; 10178 10179 /// Is there any call with a unknown callee. 10180 bool HasUnknownCallee = false; 10181 10182 /// Is there any call with a unknown callee, excluding any inline asm. 10183 bool HasUnknownCalleeNonAsm = false; 10184 }; 10185 10186 struct AACallEdgesCallSite : public AACallEdgesImpl { 10187 AACallEdgesCallSite(const IRPosition &IRP, Attributor &A) 10188 : AACallEdgesImpl(IRP, A) {} 10189 /// See AbstractAttribute::updateImpl(...). 10190 ChangeStatus updateImpl(Attributor &A) override { 10191 ChangeStatus Change = ChangeStatus::UNCHANGED; 10192 10193 auto VisitValue = [&](Value &V, const Instruction *CtxI) -> bool { 10194 if (Function *Fn = dyn_cast<Function>(&V)) { 10195 addCalledFunction(Fn, Change); 10196 } else { 10197 LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n"); 10198 setHasUnknownCallee(true, Change); 10199 } 10200 10201 // Explore all values. 10202 return true; 10203 }; 10204 10205 SmallVector<AA::ValueAndContext> Values; 10206 // Process any value that we might call. 10207 auto ProcessCalledOperand = [&](Value *V, Instruction *CtxI) { 10208 bool UsedAssumedInformation = false; 10209 Values.clear(); 10210 if (!A.getAssumedSimplifiedValues(IRPosition::value(*V), *this, Values, 10211 AA::AnyScope, UsedAssumedInformation)) { 10212 Values.push_back({*V, CtxI}); 10213 } 10214 for (auto &VAC : Values) 10215 VisitValue(*VAC.getValue(), VAC.getCtxI()); 10216 }; 10217 10218 CallBase *CB = cast<CallBase>(getCtxI()); 10219 10220 if (auto *IA = dyn_cast<InlineAsm>(CB->getCalledOperand())) { 10221 if (IA->hasSideEffects() && 10222 !hasAssumption(*CB->getCaller(), "ompx_no_call_asm") && 10223 !hasAssumption(*CB, "ompx_no_call_asm")) { 10224 setHasUnknownCallee(false, Change); 10225 } 10226 return Change; 10227 } 10228 10229 // Process callee metadata if available. 10230 if (auto *MD = getCtxI()->getMetadata(LLVMContext::MD_callees)) { 10231 for (const auto &Op : MD->operands()) { 10232 Function *Callee = mdconst::dyn_extract_or_null<Function>(Op); 10233 if (Callee) 10234 addCalledFunction(Callee, Change); 10235 } 10236 return Change; 10237 } 10238 10239 // The most simple case. 10240 ProcessCalledOperand(CB->getCalledOperand(), CB); 10241 10242 // Process callback functions. 10243 SmallVector<const Use *, 4u> CallbackUses; 10244 AbstractCallSite::getCallbackUses(*CB, CallbackUses); 10245 for (const Use *U : CallbackUses) 10246 ProcessCalledOperand(U->get(), CB); 10247 10248 return Change; 10249 } 10250 }; 10251 10252 struct AACallEdgesFunction : public AACallEdgesImpl { 10253 AACallEdgesFunction(const IRPosition &IRP, Attributor &A) 10254 : AACallEdgesImpl(IRP, A) {} 10255 10256 /// See AbstractAttribute::updateImpl(...). 10257 ChangeStatus updateImpl(Attributor &A) override { 10258 ChangeStatus Change = ChangeStatus::UNCHANGED; 10259 10260 auto ProcessCallInst = [&](Instruction &Inst) { 10261 CallBase &CB = cast<CallBase>(Inst); 10262 10263 auto &CBEdges = A.getAAFor<AACallEdges>( 10264 *this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED); 10265 if (CBEdges.hasNonAsmUnknownCallee()) 10266 setHasUnknownCallee(true, Change); 10267 if (CBEdges.hasUnknownCallee()) 10268 setHasUnknownCallee(false, Change); 10269 10270 for (Function *F : CBEdges.getOptimisticEdges()) 10271 addCalledFunction(F, Change); 10272 10273 return true; 10274 }; 10275 10276 // Visit all callable instructions. 10277 bool UsedAssumedInformation = false; 10278 if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this, 10279 UsedAssumedInformation, 10280 /* CheckBBLivenessOnly */ true)) { 10281 // If we haven't looked at all call like instructions, assume that there 10282 // are unknown callees. 10283 setHasUnknownCallee(true, Change); 10284 } 10285 10286 return Change; 10287 } 10288 }; 10289 10290 /// -------------------AAInterFnReachability Attribute-------------------------- 10291 10292 struct AAInterFnReachabilityFunction 10293 : public CachedReachabilityAA<AAInterFnReachability, Function> { 10294 AAInterFnReachabilityFunction(const IRPosition &IRP, Attributor &A) 10295 : CachedReachabilityAA<AAInterFnReachability, Function>(IRP, A) {} 10296 10297 bool instructionCanReach( 10298 Attributor &A, const Instruction &From, const Function &To, 10299 const AA::InstExclusionSetTy *ExclusionSet, 10300 SmallPtrSet<const Function *, 16> *Visited) const override { 10301 assert(From.getFunction() == getAnchorScope() && "Queried the wrong AA!"); 10302 auto *NonConstThis = const_cast<AAInterFnReachabilityFunction *>(this); 10303 10304 RQITy StackRQI(A, From, To, ExclusionSet); 10305 typename RQITy::Reachable Result; 10306 if (RQITy *RQIPtr = NonConstThis->checkQueryCache(A, StackRQI, Result)) 10307 return NonConstThis->isReachableImpl(A, *RQIPtr); 10308 return Result == RQITy::Reachable::Yes; 10309 } 10310 10311 bool isReachableImpl(Attributor &A, RQITy &RQI) override { 10312 return isReachableImpl(A, RQI, nullptr); 10313 } 10314 10315 bool isReachableImpl(Attributor &A, RQITy &RQI, 10316 SmallPtrSet<const Function *, 16> *Visited) { 10317 10318 SmallPtrSet<const Function *, 16> LocalVisited; 10319 if (!Visited) 10320 Visited = &LocalVisited; 10321 10322 const auto &IntraFnReachability = A.getAAFor<AAIntraFnReachability>( 10323 *this, IRPosition::function(*RQI.From->getFunction()), 10324 DepClassTy::OPTIONAL); 10325 10326 // Determine call like instructions that we can reach from the inst. 10327 SmallVector<CallBase *> ReachableCallBases; 10328 auto CheckCallBase = [&](Instruction &CBInst) { 10329 if (IntraFnReachability.isAssumedReachable(A, *RQI.From, CBInst, 10330 RQI.ExclusionSet)) 10331 ReachableCallBases.push_back(cast<CallBase>(&CBInst)); 10332 return true; 10333 }; 10334 10335 bool UsedAssumedInformation = false; 10336 if (!A.checkForAllCallLikeInstructions(CheckCallBase, *this, 10337 UsedAssumedInformation, 10338 /* CheckBBLivenessOnly */ true)) 10339 return rememberResult(A, RQITy::Reachable::Yes, RQI); 10340 10341 for (CallBase *CB : ReachableCallBases) { 10342 auto &CBEdges = A.getAAFor<AACallEdges>( 10343 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL); 10344 if (!CBEdges.getState().isValidState()) 10345 return rememberResult(A, RQITy::Reachable::Yes, RQI); 10346 // TODO Check To backwards in this case. 10347 if (CBEdges.hasUnknownCallee()) 10348 return rememberResult(A, RQITy::Reachable::Yes, RQI); 10349 10350 for (Function *Fn : CBEdges.getOptimisticEdges()) { 10351 if (Fn == RQI.To) 10352 return rememberResult(A, RQITy::Reachable::Yes, RQI); 10353 if (!Visited->insert(Fn).second) 10354 continue; 10355 if (Fn->isDeclaration()) { 10356 if (Fn->hasFnAttribute(Attribute::NoCallback)) 10357 continue; 10358 // TODO Check To backwards in this case. 10359 return rememberResult(A, RQITy::Reachable::Yes, RQI); 10360 } 10361 10362 const AAInterFnReachability *InterFnReachability = this; 10363 if (Fn != getAnchorScope()) 10364 InterFnReachability = &A.getAAFor<AAInterFnReachability>( 10365 *this, IRPosition::function(*Fn), DepClassTy::OPTIONAL); 10366 10367 const Instruction &FnFirstInst = Fn->getEntryBlock().front(); 10368 if (InterFnReachability->instructionCanReach(A, FnFirstInst, *RQI.To, 10369 RQI.ExclusionSet, Visited)) 10370 return rememberResult(A, RQITy::Reachable::Yes, RQI); 10371 } 10372 } 10373 10374 return rememberResult(A, RQITy::Reachable::No, RQI); 10375 } 10376 10377 void trackStatistics() const override {} 10378 10379 private: 10380 SmallVector<RQITy *> QueryVector; 10381 DenseSet<RQITy *> QueryCache; 10382 }; 10383 } // namespace 10384 10385 template <typename AAType> 10386 static std::optional<Constant *> 10387 askForAssumedConstant(Attributor &A, const AbstractAttribute &QueryingAA, 10388 const IRPosition &IRP, Type &Ty) { 10389 if (!Ty.isIntegerTy()) 10390 return nullptr; 10391 10392 // This will also pass the call base context. 10393 const auto &AA = A.getAAFor<AAType>(QueryingAA, IRP, DepClassTy::NONE); 10394 10395 std::optional<Constant *> COpt = AA.getAssumedConstant(A); 10396 10397 if (!COpt.has_value()) { 10398 A.recordDependence(AA, QueryingAA, DepClassTy::OPTIONAL); 10399 return std::nullopt; 10400 } 10401 if (auto *C = *COpt) { 10402 A.recordDependence(AA, QueryingAA, DepClassTy::OPTIONAL); 10403 return C; 10404 } 10405 return nullptr; 10406 } 10407 10408 Value *AAPotentialValues::getSingleValue( 10409 Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP, 10410 SmallVectorImpl<AA::ValueAndContext> &Values) { 10411 Type &Ty = *IRP.getAssociatedType(); 10412 std::optional<Value *> V; 10413 for (auto &It : Values) { 10414 V = AA::combineOptionalValuesInAAValueLatice(V, It.getValue(), &Ty); 10415 if (V.has_value() && !*V) 10416 break; 10417 } 10418 if (!V.has_value()) 10419 return UndefValue::get(&Ty); 10420 return *V; 10421 } 10422 10423 namespace { 10424 struct AAPotentialValuesImpl : AAPotentialValues { 10425 using StateType = PotentialLLVMValuesState; 10426 10427 AAPotentialValuesImpl(const IRPosition &IRP, Attributor &A) 10428 : AAPotentialValues(IRP, A) {} 10429 10430 /// See AbstractAttribute::initialize(..). 10431 void initialize(Attributor &A) override { 10432 if (A.hasSimplificationCallback(getIRPosition())) { 10433 indicatePessimisticFixpoint(); 10434 return; 10435 } 10436 Value *Stripped = getAssociatedValue().stripPointerCasts(); 10437 auto *CE = dyn_cast<ConstantExpr>(Stripped); 10438 if (isa<Constant>(Stripped) && 10439 (!CE || CE->getOpcode() != Instruction::ICmp)) { 10440 addValue(A, getState(), *Stripped, getCtxI(), AA::AnyScope, 10441 getAnchorScope()); 10442 indicateOptimisticFixpoint(); 10443 return; 10444 } 10445 AAPotentialValues::initialize(A); 10446 } 10447 10448 /// See AbstractAttribute::getAsStr(). 10449 const std::string getAsStr() const override { 10450 std::string Str; 10451 llvm::raw_string_ostream OS(Str); 10452 OS << getState(); 10453 return OS.str(); 10454 } 10455 10456 template <typename AAType> 10457 static std::optional<Value *> askOtherAA(Attributor &A, 10458 const AbstractAttribute &AA, 10459 const IRPosition &IRP, Type &Ty) { 10460 if (isa<Constant>(IRP.getAssociatedValue())) 10461 return &IRP.getAssociatedValue(); 10462 std::optional<Constant *> C = askForAssumedConstant<AAType>(A, AA, IRP, Ty); 10463 if (!C) 10464 return std::nullopt; 10465 if (*C) 10466 if (auto *CC = AA::getWithType(**C, Ty)) 10467 return CC; 10468 return nullptr; 10469 } 10470 10471 void addValue(Attributor &A, StateType &State, Value &V, 10472 const Instruction *CtxI, AA::ValueScope S, 10473 Function *AnchorScope) const { 10474 10475 IRPosition ValIRP = IRPosition::value(V); 10476 if (auto *CB = dyn_cast_or_null<CallBase>(CtxI)) { 10477 for (const auto &U : CB->args()) { 10478 if (U.get() != &V) 10479 continue; 10480 ValIRP = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U)); 10481 break; 10482 } 10483 } 10484 10485 Value *VPtr = &V; 10486 if (ValIRP.getAssociatedType()->isIntegerTy()) { 10487 Type &Ty = *getAssociatedType(); 10488 std::optional<Value *> SimpleV = 10489 askOtherAA<AAValueConstantRange>(A, *this, ValIRP, Ty); 10490 if (SimpleV.has_value() && !*SimpleV) { 10491 auto &PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>( 10492 *this, ValIRP, DepClassTy::OPTIONAL); 10493 if (PotentialConstantsAA.isValidState()) { 10494 for (const auto &It : PotentialConstantsAA.getAssumedSet()) 10495 State.unionAssumed({{*ConstantInt::get(&Ty, It), nullptr}, S}); 10496 if (PotentialConstantsAA.undefIsContained()) 10497 State.unionAssumed({{*UndefValue::get(&Ty), nullptr}, S}); 10498 return; 10499 } 10500 } 10501 if (!SimpleV.has_value()) 10502 return; 10503 10504 if (*SimpleV) 10505 VPtr = *SimpleV; 10506 } 10507 10508 if (isa<ConstantInt>(VPtr)) 10509 CtxI = nullptr; 10510 if (!AA::isValidInScope(*VPtr, AnchorScope)) 10511 S = AA::ValueScope(S | AA::Interprocedural); 10512 10513 State.unionAssumed({{*VPtr, CtxI}, S}); 10514 } 10515 10516 /// Helper struct to tie a value+context pair together with the scope for 10517 /// which this is the simplified version. 10518 struct ItemInfo { 10519 AA::ValueAndContext I; 10520 AA::ValueScope S; 10521 10522 bool operator==(const ItemInfo &II) const { 10523 return II.I == I && II.S == S; 10524 }; 10525 bool operator<(const ItemInfo &II) const { 10526 if (I == II.I) 10527 return S < II.S; 10528 return I < II.I; 10529 }; 10530 }; 10531 10532 bool recurseForValue(Attributor &A, const IRPosition &IRP, AA::ValueScope S) { 10533 SmallMapVector<AA::ValueAndContext, int, 8> ValueScopeMap; 10534 for (auto CS : {AA::Intraprocedural, AA::Interprocedural}) { 10535 if (!(CS & S)) 10536 continue; 10537 10538 bool UsedAssumedInformation = false; 10539 SmallVector<AA::ValueAndContext> Values; 10540 if (!A.getAssumedSimplifiedValues(IRP, this, Values, CS, 10541 UsedAssumedInformation)) 10542 return false; 10543 10544 for (auto &It : Values) 10545 ValueScopeMap[It] += CS; 10546 } 10547 for (auto &It : ValueScopeMap) 10548 addValue(A, getState(), *It.first.getValue(), It.first.getCtxI(), 10549 AA::ValueScope(It.second), getAnchorScope()); 10550 10551 return true; 10552 } 10553 10554 void giveUpOnIntraprocedural(Attributor &A) { 10555 auto NewS = StateType::getBestState(getState()); 10556 for (const auto &It : getAssumedSet()) { 10557 if (It.second == AA::Intraprocedural) 10558 continue; 10559 addValue(A, NewS, *It.first.getValue(), It.first.getCtxI(), 10560 AA::Interprocedural, getAnchorScope()); 10561 } 10562 assert(!undefIsContained() && "Undef should be an explicit value!"); 10563 addValue(A, NewS, getAssociatedValue(), getCtxI(), AA::Intraprocedural, 10564 getAnchorScope()); 10565 getState() = NewS; 10566 } 10567 10568 /// See AbstractState::indicatePessimisticFixpoint(...). 10569 ChangeStatus indicatePessimisticFixpoint() override { 10570 getState() = StateType::getBestState(getState()); 10571 getState().unionAssumed({{getAssociatedValue(), getCtxI()}, AA::AnyScope}); 10572 AAPotentialValues::indicateOptimisticFixpoint(); 10573 return ChangeStatus::CHANGED; 10574 } 10575 10576 /// See AbstractAttribute::updateImpl(...). 10577 ChangeStatus updateImpl(Attributor &A) override { 10578 return indicatePessimisticFixpoint(); 10579 } 10580 10581 /// See AbstractAttribute::manifest(...). 10582 ChangeStatus manifest(Attributor &A) override { 10583 SmallVector<AA::ValueAndContext> Values; 10584 for (AA::ValueScope S : {AA::Interprocedural, AA::Intraprocedural}) { 10585 Values.clear(); 10586 if (!getAssumedSimplifiedValues(A, Values, S)) 10587 continue; 10588 Value &OldV = getAssociatedValue(); 10589 if (isa<UndefValue>(OldV)) 10590 continue; 10591 Value *NewV = getSingleValue(A, *this, getIRPosition(), Values); 10592 if (!NewV || NewV == &OldV) 10593 continue; 10594 if (getCtxI() && 10595 !AA::isValidAtPosition({*NewV, *getCtxI()}, A.getInfoCache())) 10596 continue; 10597 if (A.changeAfterManifest(getIRPosition(), *NewV)) 10598 return ChangeStatus::CHANGED; 10599 } 10600 return ChangeStatus::UNCHANGED; 10601 } 10602 10603 bool getAssumedSimplifiedValues(Attributor &A, 10604 SmallVectorImpl<AA::ValueAndContext> &Values, 10605 AA::ValueScope S) const override { 10606 if (!isValidState()) 10607 return false; 10608 for (const auto &It : getAssumedSet()) 10609 if (It.second & S) 10610 Values.push_back(It.first); 10611 assert(!undefIsContained() && "Undef should be an explicit value!"); 10612 return true; 10613 } 10614 }; 10615 10616 struct AAPotentialValuesFloating : AAPotentialValuesImpl { 10617 AAPotentialValuesFloating(const IRPosition &IRP, Attributor &A) 10618 : AAPotentialValuesImpl(IRP, A) {} 10619 10620 /// See AbstractAttribute::updateImpl(...). 10621 ChangeStatus updateImpl(Attributor &A) override { 10622 auto AssumedBefore = getAssumed(); 10623 10624 genericValueTraversal(A); 10625 10626 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED 10627 : ChangeStatus::CHANGED; 10628 } 10629 10630 /// Helper struct to remember which AAIsDead instances we actually used. 10631 struct LivenessInfo { 10632 const AAIsDead *LivenessAA = nullptr; 10633 bool AnyDead = false; 10634 }; 10635 10636 /// Check if \p Cmp is a comparison we can simplify. 10637 /// 10638 /// We handle multiple cases, one in which at least one operand is an 10639 /// (assumed) nullptr. If so, try to simplify it using AANonNull on the other 10640 /// operand. Return true if successful, in that case Worklist will be updated. 10641 bool handleCmp(Attributor &A, Value &Cmp, Value *LHS, Value *RHS, 10642 CmpInst::Predicate Pred, ItemInfo II, 10643 SmallVectorImpl<ItemInfo> &Worklist) { 10644 10645 // Simplify the operands first. 10646 bool UsedAssumedInformation = false; 10647 const auto &SimplifiedLHS = A.getAssumedSimplified( 10648 IRPosition::value(*LHS, getCallBaseContext()), *this, 10649 UsedAssumedInformation, AA::Intraprocedural); 10650 if (!SimplifiedLHS.has_value()) 10651 return true; 10652 if (!*SimplifiedLHS) 10653 return false; 10654 LHS = *SimplifiedLHS; 10655 10656 const auto &SimplifiedRHS = A.getAssumedSimplified( 10657 IRPosition::value(*RHS, getCallBaseContext()), *this, 10658 UsedAssumedInformation, AA::Intraprocedural); 10659 if (!SimplifiedRHS.has_value()) 10660 return true; 10661 if (!*SimplifiedRHS) 10662 return false; 10663 RHS = *SimplifiedRHS; 10664 10665 LLVMContext &Ctx = LHS->getContext(); 10666 // Handle the trivial case first in which we don't even need to think about 10667 // null or non-null. 10668 if (LHS == RHS && 10669 (CmpInst::isTrueWhenEqual(Pred) || CmpInst::isFalseWhenEqual(Pred))) { 10670 Constant *NewV = ConstantInt::get(Type::getInt1Ty(Ctx), 10671 CmpInst::isTrueWhenEqual(Pred)); 10672 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S, 10673 getAnchorScope()); 10674 return true; 10675 } 10676 10677 // From now on we only handle equalities (==, !=). 10678 if (!CmpInst::isEquality(Pred)) 10679 return false; 10680 10681 bool LHSIsNull = isa<ConstantPointerNull>(LHS); 10682 bool RHSIsNull = isa<ConstantPointerNull>(RHS); 10683 if (!LHSIsNull && !RHSIsNull) 10684 return false; 10685 10686 // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the 10687 // non-nullptr operand and if we assume it's non-null we can conclude the 10688 // result of the comparison. 10689 assert((LHSIsNull || RHSIsNull) && 10690 "Expected nullptr versus non-nullptr comparison at this point"); 10691 10692 // The index is the operand that we assume is not null. 10693 unsigned PtrIdx = LHSIsNull; 10694 auto &PtrNonNullAA = A.getAAFor<AANonNull>( 10695 *this, IRPosition::value(*(PtrIdx ? RHS : LHS)), DepClassTy::REQUIRED); 10696 if (!PtrNonNullAA.isAssumedNonNull()) 10697 return false; 10698 10699 // The new value depends on the predicate, true for != and false for ==. 10700 Constant *NewV = 10701 ConstantInt::get(Type::getInt1Ty(Ctx), Pred == CmpInst::ICMP_NE); 10702 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S, getAnchorScope()); 10703 return true; 10704 } 10705 10706 bool handleSelectInst(Attributor &A, SelectInst &SI, ItemInfo II, 10707 SmallVectorImpl<ItemInfo> &Worklist) { 10708 const Instruction *CtxI = II.I.getCtxI(); 10709 bool UsedAssumedInformation = false; 10710 10711 std::optional<Constant *> C = 10712 A.getAssumedConstant(*SI.getCondition(), *this, UsedAssumedInformation); 10713 bool NoValueYet = !C.has_value(); 10714 if (NoValueYet || isa_and_nonnull<UndefValue>(*C)) 10715 return true; 10716 if (auto *CI = dyn_cast_or_null<ConstantInt>(*C)) { 10717 if (CI->isZero()) 10718 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S}); 10719 else 10720 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S}); 10721 } else if (&SI == &getAssociatedValue()) { 10722 // We could not simplify the condition, assume both values. 10723 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S}); 10724 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S}); 10725 } else { 10726 std::optional<Value *> SimpleV = A.getAssumedSimplified( 10727 IRPosition::inst(SI), *this, UsedAssumedInformation, II.S); 10728 if (!SimpleV.has_value()) 10729 return true; 10730 if (*SimpleV) { 10731 addValue(A, getState(), **SimpleV, CtxI, II.S, getAnchorScope()); 10732 return true; 10733 } 10734 return false; 10735 } 10736 return true; 10737 } 10738 10739 bool handleLoadInst(Attributor &A, LoadInst &LI, ItemInfo II, 10740 SmallVectorImpl<ItemInfo> &Worklist) { 10741 SmallSetVector<Value *, 4> PotentialCopies; 10742 SmallSetVector<Instruction *, 4> PotentialValueOrigins; 10743 bool UsedAssumedInformation = false; 10744 if (!AA::getPotentiallyLoadedValues(A, LI, PotentialCopies, 10745 PotentialValueOrigins, *this, 10746 UsedAssumedInformation, 10747 /* OnlyExact */ true)) { 10748 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Failed to get potentially " 10749 "loaded values for load instruction " 10750 << LI << "\n"); 10751 return false; 10752 } 10753 10754 // Do not simplify loads that are only used in llvm.assume if we cannot also 10755 // remove all stores that may feed into the load. The reason is that the 10756 // assume is probably worth something as long as the stores are around. 10757 InformationCache &InfoCache = A.getInfoCache(); 10758 if (InfoCache.isOnlyUsedByAssume(LI)) { 10759 if (!llvm::all_of(PotentialValueOrigins, [&](Instruction *I) { 10760 if (!I) 10761 return true; 10762 if (auto *SI = dyn_cast<StoreInst>(I)) 10763 return A.isAssumedDead(SI->getOperandUse(0), this, 10764 /* LivenessAA */ nullptr, 10765 UsedAssumedInformation, 10766 /* CheckBBLivenessOnly */ false); 10767 return A.isAssumedDead(*I, this, /* LivenessAA */ nullptr, 10768 UsedAssumedInformation, 10769 /* CheckBBLivenessOnly */ false); 10770 })) { 10771 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Load is onl used by assumes " 10772 "and we cannot delete all the stores: " 10773 << LI << "\n"); 10774 return false; 10775 } 10776 } 10777 10778 // Values have to be dynamically unique or we loose the fact that a 10779 // single llvm::Value might represent two runtime values (e.g., 10780 // stack locations in different recursive calls). 10781 const Instruction *CtxI = II.I.getCtxI(); 10782 bool ScopeIsLocal = (II.S & AA::Intraprocedural); 10783 bool AllLocal = ScopeIsLocal; 10784 bool DynamicallyUnique = llvm::all_of(PotentialCopies, [&](Value *PC) { 10785 AllLocal &= AA::isValidInScope(*PC, getAnchorScope()); 10786 return AA::isDynamicallyUnique(A, *this, *PC); 10787 }); 10788 if (!DynamicallyUnique) { 10789 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Not all potentially loaded " 10790 "values are dynamically unique: " 10791 << LI << "\n"); 10792 return false; 10793 } 10794 10795 for (auto *PotentialCopy : PotentialCopies) { 10796 if (AllLocal) { 10797 Worklist.push_back({{*PotentialCopy, CtxI}, II.S}); 10798 } else { 10799 Worklist.push_back({{*PotentialCopy, CtxI}, AA::Interprocedural}); 10800 } 10801 } 10802 if (!AllLocal && ScopeIsLocal) 10803 addValue(A, getState(), LI, CtxI, AA::Intraprocedural, getAnchorScope()); 10804 return true; 10805 } 10806 10807 bool handlePHINode( 10808 Attributor &A, PHINode &PHI, ItemInfo II, 10809 SmallVectorImpl<ItemInfo> &Worklist, 10810 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) { 10811 auto GetLivenessInfo = [&](const Function &F) -> LivenessInfo & { 10812 LivenessInfo &LI = LivenessAAs[&F]; 10813 if (!LI.LivenessAA) 10814 LI.LivenessAA = &A.getAAFor<AAIsDead>(*this, IRPosition::function(F), 10815 DepClassTy::NONE); 10816 return LI; 10817 }; 10818 10819 if (&PHI == &getAssociatedValue()) { 10820 LivenessInfo &LI = GetLivenessInfo(*PHI.getFunction()); 10821 for (unsigned u = 0, e = PHI.getNumIncomingValues(); u < e; u++) { 10822 BasicBlock *IncomingBB = PHI.getIncomingBlock(u); 10823 if (LI.LivenessAA->isEdgeDead(IncomingBB, PHI.getParent())) { 10824 LI.AnyDead = true; 10825 continue; 10826 } 10827 Worklist.push_back( 10828 {{*PHI.getIncomingValue(u), IncomingBB->getTerminator()}, II.S}); 10829 } 10830 return true; 10831 } 10832 10833 bool UsedAssumedInformation = false; 10834 std::optional<Value *> SimpleV = A.getAssumedSimplified( 10835 IRPosition::inst(PHI), *this, UsedAssumedInformation, II.S); 10836 if (!SimpleV.has_value()) 10837 return true; 10838 if (!(*SimpleV)) 10839 return false; 10840 addValue(A, getState(), **SimpleV, &PHI, II.S, getAnchorScope()); 10841 return true; 10842 } 10843 10844 /// Use the generic, non-optimistic InstSimplfy functionality if we managed to 10845 /// simplify any operand of the instruction \p I. Return true if successful, 10846 /// in that case Worklist will be updated. 10847 bool handleGenericInst(Attributor &A, Instruction &I, ItemInfo II, 10848 SmallVectorImpl<ItemInfo> &Worklist) { 10849 bool SomeSimplified = false; 10850 bool UsedAssumedInformation = false; 10851 10852 SmallVector<Value *, 8> NewOps(I.getNumOperands()); 10853 int Idx = 0; 10854 for (Value *Op : I.operands()) { 10855 const auto &SimplifiedOp = A.getAssumedSimplified( 10856 IRPosition::value(*Op, getCallBaseContext()), *this, 10857 UsedAssumedInformation, AA::Intraprocedural); 10858 // If we are not sure about any operand we are not sure about the entire 10859 // instruction, we'll wait. 10860 if (!SimplifiedOp.has_value()) 10861 return true; 10862 10863 if (*SimplifiedOp) 10864 NewOps[Idx] = *SimplifiedOp; 10865 else 10866 NewOps[Idx] = Op; 10867 10868 SomeSimplified |= (NewOps[Idx] != Op); 10869 ++Idx; 10870 } 10871 10872 // We won't bother with the InstSimplify interface if we didn't simplify any 10873 // operand ourselves. 10874 if (!SomeSimplified) 10875 return false; 10876 10877 InformationCache &InfoCache = A.getInfoCache(); 10878 Function *F = I.getFunction(); 10879 const auto *DT = 10880 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F); 10881 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F); 10882 auto *AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F); 10883 OptimizationRemarkEmitter *ORE = nullptr; 10884 10885 const DataLayout &DL = I.getModule()->getDataLayout(); 10886 SimplifyQuery Q(DL, TLI, DT, AC, &I); 10887 Value *NewV = simplifyInstructionWithOperands(&I, NewOps, Q, ORE); 10888 if (!NewV || NewV == &I) 10889 return false; 10890 10891 LLVM_DEBUG(dbgs() << "Generic inst " << I << " assumed simplified to " 10892 << *NewV << "\n"); 10893 Worklist.push_back({{*NewV, II.I.getCtxI()}, II.S}); 10894 return true; 10895 } 10896 10897 bool simplifyInstruction( 10898 Attributor &A, Instruction &I, ItemInfo II, 10899 SmallVectorImpl<ItemInfo> &Worklist, 10900 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) { 10901 if (auto *CI = dyn_cast<CmpInst>(&I)) 10902 if (handleCmp(A, *CI, CI->getOperand(0), CI->getOperand(1), 10903 CI->getPredicate(), II, Worklist)) 10904 return true; 10905 10906 switch (I.getOpcode()) { 10907 case Instruction::Select: 10908 return handleSelectInst(A, cast<SelectInst>(I), II, Worklist); 10909 case Instruction::PHI: 10910 return handlePHINode(A, cast<PHINode>(I), II, Worklist, LivenessAAs); 10911 case Instruction::Load: 10912 return handleLoadInst(A, cast<LoadInst>(I), II, Worklist); 10913 default: 10914 return handleGenericInst(A, I, II, Worklist); 10915 }; 10916 return false; 10917 } 10918 10919 void genericValueTraversal(Attributor &A) { 10920 SmallMapVector<const Function *, LivenessInfo, 4> LivenessAAs; 10921 10922 Value *InitialV = &getAssociatedValue(); 10923 SmallSet<ItemInfo, 16> Visited; 10924 SmallVector<ItemInfo, 16> Worklist; 10925 Worklist.push_back({{*InitialV, getCtxI()}, AA::AnyScope}); 10926 10927 int Iteration = 0; 10928 do { 10929 ItemInfo II = Worklist.pop_back_val(); 10930 Value *V = II.I.getValue(); 10931 assert(V); 10932 const Instruction *CtxI = II.I.getCtxI(); 10933 AA::ValueScope S = II.S; 10934 10935 // Check if we should process the current value. To prevent endless 10936 // recursion keep a record of the values we followed! 10937 if (!Visited.insert(II).second) 10938 continue; 10939 10940 // Make sure we limit the compile time for complex expressions. 10941 if (Iteration++ >= MaxPotentialValuesIterations) { 10942 LLVM_DEBUG(dbgs() << "Generic value traversal reached iteration limit: " 10943 << Iteration << "!\n"); 10944 addValue(A, getState(), *V, CtxI, S, getAnchorScope()); 10945 continue; 10946 } 10947 10948 // Explicitly look through calls with a "returned" attribute if we do 10949 // not have a pointer as stripPointerCasts only works on them. 10950 Value *NewV = nullptr; 10951 if (V->getType()->isPointerTy()) { 10952 NewV = AA::getWithType(*V->stripPointerCasts(), *V->getType()); 10953 } else { 10954 auto *CB = dyn_cast<CallBase>(V); 10955 if (CB && CB->getCalledFunction()) { 10956 for (Argument &Arg : CB->getCalledFunction()->args()) 10957 if (Arg.hasReturnedAttr()) { 10958 NewV = CB->getArgOperand(Arg.getArgNo()); 10959 break; 10960 } 10961 } 10962 } 10963 if (NewV && NewV != V) { 10964 Worklist.push_back({{*NewV, CtxI}, S}); 10965 continue; 10966 } 10967 10968 if (auto *CE = dyn_cast<ConstantExpr>(V)) { 10969 if (CE->getOpcode() == Instruction::ICmp) 10970 if (handleCmp(A, *CE, CE->getOperand(0), CE->getOperand(1), 10971 CmpInst::Predicate(CE->getPredicate()), II, Worklist)) 10972 continue; 10973 } 10974 10975 if (auto *I = dyn_cast<Instruction>(V)) { 10976 if (simplifyInstruction(A, *I, II, Worklist, LivenessAAs)) 10977 continue; 10978 } 10979 10980 if (V != InitialV || isa<Argument>(V)) 10981 if (recurseForValue(A, IRPosition::value(*V), II.S)) 10982 continue; 10983 10984 // If we haven't stripped anything we give up. 10985 if (V == InitialV && CtxI == getCtxI()) { 10986 indicatePessimisticFixpoint(); 10987 return; 10988 } 10989 10990 addValue(A, getState(), *V, CtxI, S, getAnchorScope()); 10991 } while (!Worklist.empty()); 10992 10993 // If we actually used liveness information so we have to record a 10994 // dependence. 10995 for (auto &It : LivenessAAs) 10996 if (It.second.AnyDead) 10997 A.recordDependence(*It.second.LivenessAA, *this, DepClassTy::OPTIONAL); 10998 } 10999 11000 /// See AbstractAttribute::trackStatistics() 11001 void trackStatistics() const override { 11002 STATS_DECLTRACK_FLOATING_ATTR(potential_values) 11003 } 11004 }; 11005 11006 struct AAPotentialValuesArgument final : AAPotentialValuesImpl { 11007 using Base = AAPotentialValuesImpl; 11008 AAPotentialValuesArgument(const IRPosition &IRP, Attributor &A) 11009 : Base(IRP, A) {} 11010 11011 /// See AbstractAttribute::initialize(..). 11012 void initialize(Attributor &A) override { 11013 auto &Arg = cast<Argument>(getAssociatedValue()); 11014 if (Arg.hasPointeeInMemoryValueAttr()) 11015 indicatePessimisticFixpoint(); 11016 } 11017 11018 /// See AbstractAttribute::updateImpl(...). 11019 ChangeStatus updateImpl(Attributor &A) override { 11020 auto AssumedBefore = getAssumed(); 11021 11022 unsigned CSArgNo = getCallSiteArgNo(); 11023 11024 bool UsedAssumedInformation = false; 11025 SmallVector<AA::ValueAndContext> Values; 11026 auto CallSitePred = [&](AbstractCallSite ACS) { 11027 const auto CSArgIRP = IRPosition::callsite_argument(ACS, CSArgNo); 11028 if (CSArgIRP.getPositionKind() == IRP_INVALID) 11029 return false; 11030 11031 if (!A.getAssumedSimplifiedValues(CSArgIRP, this, Values, 11032 AA::Interprocedural, 11033 UsedAssumedInformation)) 11034 return false; 11035 11036 return isValidState(); 11037 }; 11038 11039 if (!A.checkForAllCallSites(CallSitePred, *this, 11040 /* RequireAllCallSites */ true, 11041 UsedAssumedInformation)) 11042 return indicatePessimisticFixpoint(); 11043 11044 Function *Fn = getAssociatedFunction(); 11045 bool AnyNonLocal = false; 11046 for (auto &It : Values) { 11047 if (isa<Constant>(It.getValue())) { 11048 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope, 11049 getAnchorScope()); 11050 continue; 11051 } 11052 if (!AA::isDynamicallyUnique(A, *this, *It.getValue())) 11053 return indicatePessimisticFixpoint(); 11054 11055 if (auto *Arg = dyn_cast<Argument>(It.getValue())) 11056 if (Arg->getParent() == Fn) { 11057 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope, 11058 getAnchorScope()); 11059 continue; 11060 } 11061 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::Interprocedural, 11062 getAnchorScope()); 11063 AnyNonLocal = true; 11064 } 11065 assert(!undefIsContained() && "Undef should be an explicit value!"); 11066 if (AnyNonLocal) 11067 giveUpOnIntraprocedural(A); 11068 11069 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED 11070 : ChangeStatus::CHANGED; 11071 } 11072 11073 /// See AbstractAttribute::trackStatistics() 11074 void trackStatistics() const override { 11075 STATS_DECLTRACK_ARG_ATTR(potential_values) 11076 } 11077 }; 11078 11079 struct AAPotentialValuesReturned 11080 : AAReturnedFromReturnedValues<AAPotentialValues, AAPotentialValuesImpl> { 11081 using Base = 11082 AAReturnedFromReturnedValues<AAPotentialValues, AAPotentialValuesImpl>; 11083 AAPotentialValuesReturned(const IRPosition &IRP, Attributor &A) 11084 : Base(IRP, A) {} 11085 11086 /// See AbstractAttribute::initialize(..). 11087 void initialize(Attributor &A) override { 11088 if (A.hasSimplificationCallback(getIRPosition())) 11089 indicatePessimisticFixpoint(); 11090 else 11091 AAPotentialValues::initialize(A); 11092 } 11093 11094 ChangeStatus manifest(Attributor &A) override { 11095 // We queried AAValueSimplify for the returned values so they will be 11096 // replaced if a simplified form was found. Nothing to do here. 11097 return ChangeStatus::UNCHANGED; 11098 } 11099 11100 ChangeStatus indicatePessimisticFixpoint() override { 11101 return AAPotentialValues::indicatePessimisticFixpoint(); 11102 } 11103 11104 /// See AbstractAttribute::trackStatistics() 11105 void trackStatistics() const override { 11106 STATS_DECLTRACK_FNRET_ATTR(potential_values) 11107 } 11108 }; 11109 11110 struct AAPotentialValuesFunction : AAPotentialValuesImpl { 11111 AAPotentialValuesFunction(const IRPosition &IRP, Attributor &A) 11112 : AAPotentialValuesImpl(IRP, A) {} 11113 11114 /// See AbstractAttribute::updateImpl(...). 11115 ChangeStatus updateImpl(Attributor &A) override { 11116 llvm_unreachable("AAPotentialValues(Function|CallSite)::updateImpl will " 11117 "not be called"); 11118 } 11119 11120 /// See AbstractAttribute::trackStatistics() 11121 void trackStatistics() const override { 11122 STATS_DECLTRACK_FN_ATTR(potential_values) 11123 } 11124 }; 11125 11126 struct AAPotentialValuesCallSite : AAPotentialValuesFunction { 11127 AAPotentialValuesCallSite(const IRPosition &IRP, Attributor &A) 11128 : AAPotentialValuesFunction(IRP, A) {} 11129 11130 /// See AbstractAttribute::trackStatistics() 11131 void trackStatistics() const override { 11132 STATS_DECLTRACK_CS_ATTR(potential_values) 11133 } 11134 }; 11135 11136 struct AAPotentialValuesCallSiteReturned : AAPotentialValuesImpl { 11137 AAPotentialValuesCallSiteReturned(const IRPosition &IRP, Attributor &A) 11138 : AAPotentialValuesImpl(IRP, A) {} 11139 11140 /// See AbstractAttribute::updateImpl(...). 11141 ChangeStatus updateImpl(Attributor &A) override { 11142 auto AssumedBefore = getAssumed(); 11143 11144 Function *Callee = getAssociatedFunction(); 11145 if (!Callee) 11146 return indicatePessimisticFixpoint(); 11147 11148 bool UsedAssumedInformation = false; 11149 auto *CB = cast<CallBase>(getCtxI()); 11150 if (CB->isMustTailCall() && 11151 !A.isAssumedDead(IRPosition::inst(*CB), this, nullptr, 11152 UsedAssumedInformation)) 11153 return indicatePessimisticFixpoint(); 11154 11155 SmallVector<AA::ValueAndContext> Values; 11156 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this, 11157 Values, AA::Intraprocedural, 11158 UsedAssumedInformation)) 11159 return indicatePessimisticFixpoint(); 11160 11161 Function *Caller = CB->getCaller(); 11162 11163 bool AnyNonLocal = false; 11164 for (auto &It : Values) { 11165 Value *V = It.getValue(); 11166 std::optional<Value *> CallerV = A.translateArgumentToCallSiteContent( 11167 V, *CB, *this, UsedAssumedInformation); 11168 if (!CallerV.has_value()) { 11169 // Nothing to do as long as no value was determined. 11170 continue; 11171 } 11172 V = *CallerV ? *CallerV : V; 11173 if (AA::isDynamicallyUnique(A, *this, *V) && 11174 AA::isValidInScope(*V, Caller)) { 11175 if (*CallerV) { 11176 SmallVector<AA::ValueAndContext> ArgValues; 11177 IRPosition IRP = IRPosition::value(*V); 11178 if (auto *Arg = dyn_cast<Argument>(V)) 11179 if (Arg->getParent() == CB->getCalledFunction()) 11180 IRP = IRPosition::callsite_argument(*CB, Arg->getArgNo()); 11181 if (recurseForValue(A, IRP, AA::AnyScope)) 11182 continue; 11183 } 11184 addValue(A, getState(), *V, CB, AA::AnyScope, getAnchorScope()); 11185 } else { 11186 AnyNonLocal = true; 11187 break; 11188 } 11189 } 11190 if (AnyNonLocal) { 11191 Values.clear(); 11192 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this, 11193 Values, AA::Interprocedural, 11194 UsedAssumedInformation)) 11195 return indicatePessimisticFixpoint(); 11196 AnyNonLocal = false; 11197 getState() = PotentialLLVMValuesState::getBestState(); 11198 for (auto &It : Values) { 11199 Value *V = It.getValue(); 11200 if (!AA::isDynamicallyUnique(A, *this, *V)) 11201 return indicatePessimisticFixpoint(); 11202 if (AA::isValidInScope(*V, Caller)) { 11203 addValue(A, getState(), *V, CB, AA::AnyScope, getAnchorScope()); 11204 } else { 11205 AnyNonLocal = true; 11206 addValue(A, getState(), *V, CB, AA::Interprocedural, 11207 getAnchorScope()); 11208 } 11209 } 11210 if (AnyNonLocal) 11211 giveUpOnIntraprocedural(A); 11212 } 11213 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED 11214 : ChangeStatus::CHANGED; 11215 } 11216 11217 ChangeStatus indicatePessimisticFixpoint() override { 11218 return AAPotentialValues::indicatePessimisticFixpoint(); 11219 } 11220 11221 /// See AbstractAttribute::trackStatistics() 11222 void trackStatistics() const override { 11223 STATS_DECLTRACK_CSRET_ATTR(potential_values) 11224 } 11225 }; 11226 11227 struct AAPotentialValuesCallSiteArgument : AAPotentialValuesFloating { 11228 AAPotentialValuesCallSiteArgument(const IRPosition &IRP, Attributor &A) 11229 : AAPotentialValuesFloating(IRP, A) {} 11230 11231 /// See AbstractAttribute::trackStatistics() 11232 void trackStatistics() const override { 11233 STATS_DECLTRACK_CSARG_ATTR(potential_values) 11234 } 11235 }; 11236 } // namespace 11237 11238 /// ---------------------- Assumption Propagation ------------------------------ 11239 namespace { 11240 struct AAAssumptionInfoImpl : public AAAssumptionInfo { 11241 AAAssumptionInfoImpl(const IRPosition &IRP, Attributor &A, 11242 const DenseSet<StringRef> &Known) 11243 : AAAssumptionInfo(IRP, A, Known) {} 11244 11245 bool hasAssumption(const StringRef Assumption) const override { 11246 return isValidState() && setContains(Assumption); 11247 } 11248 11249 /// See AbstractAttribute::getAsStr() 11250 const std::string getAsStr() const override { 11251 const SetContents &Known = getKnown(); 11252 const SetContents &Assumed = getAssumed(); 11253 11254 const std::string KnownStr = 11255 llvm::join(Known.getSet().begin(), Known.getSet().end(), ","); 11256 const std::string AssumedStr = 11257 (Assumed.isUniversal()) 11258 ? "Universal" 11259 : llvm::join(Assumed.getSet().begin(), Assumed.getSet().end(), ","); 11260 11261 return "Known [" + KnownStr + "]," + " Assumed [" + AssumedStr + "]"; 11262 } 11263 }; 11264 11265 /// Propagates assumption information from parent functions to all of their 11266 /// successors. An assumption can be propagated if the containing function 11267 /// dominates the called function. 11268 /// 11269 /// We start with a "known" set of assumptions already valid for the associated 11270 /// function and an "assumed" set that initially contains all possible 11271 /// assumptions. The assumed set is inter-procedurally updated by narrowing its 11272 /// contents as concrete values are known. The concrete values are seeded by the 11273 /// first nodes that are either entries into the call graph, or contains no 11274 /// assumptions. Each node is updated as the intersection of the assumed state 11275 /// with all of its predecessors. 11276 struct AAAssumptionInfoFunction final : AAAssumptionInfoImpl { 11277 AAAssumptionInfoFunction(const IRPosition &IRP, Attributor &A) 11278 : AAAssumptionInfoImpl(IRP, A, 11279 getAssumptions(*IRP.getAssociatedFunction())) {} 11280 11281 /// See AbstractAttribute::manifest(...). 11282 ChangeStatus manifest(Attributor &A) override { 11283 const auto &Assumptions = getKnown(); 11284 11285 // Don't manifest a universal set if it somehow made it here. 11286 if (Assumptions.isUniversal()) 11287 return ChangeStatus::UNCHANGED; 11288 11289 Function *AssociatedFunction = getAssociatedFunction(); 11290 11291 bool Changed = addAssumptions(*AssociatedFunction, Assumptions.getSet()); 11292 11293 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 11294 } 11295 11296 /// See AbstractAttribute::updateImpl(...). 11297 ChangeStatus updateImpl(Attributor &A) override { 11298 bool Changed = false; 11299 11300 auto CallSitePred = [&](AbstractCallSite ACS) { 11301 const auto &AssumptionAA = A.getAAFor<AAAssumptionInfo>( 11302 *this, IRPosition::callsite_function(*ACS.getInstruction()), 11303 DepClassTy::REQUIRED); 11304 // Get the set of assumptions shared by all of this function's callers. 11305 Changed |= getIntersection(AssumptionAA.getAssumed()); 11306 return !getAssumed().empty() || !getKnown().empty(); 11307 }; 11308 11309 bool UsedAssumedInformation = false; 11310 // Get the intersection of all assumptions held by this node's predecessors. 11311 // If we don't know all the call sites then this is either an entry into the 11312 // call graph or an empty node. This node is known to only contain its own 11313 // assumptions and can be propagated to its successors. 11314 if (!A.checkForAllCallSites(CallSitePred, *this, true, 11315 UsedAssumedInformation)) 11316 return indicatePessimisticFixpoint(); 11317 11318 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 11319 } 11320 11321 void trackStatistics() const override {} 11322 }; 11323 11324 /// Assumption Info defined for call sites. 11325 struct AAAssumptionInfoCallSite final : AAAssumptionInfoImpl { 11326 11327 AAAssumptionInfoCallSite(const IRPosition &IRP, Attributor &A) 11328 : AAAssumptionInfoImpl(IRP, A, getInitialAssumptions(IRP)) {} 11329 11330 /// See AbstractAttribute::initialize(...). 11331 void initialize(Attributor &A) override { 11332 const IRPosition &FnPos = IRPosition::function(*getAnchorScope()); 11333 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED); 11334 } 11335 11336 /// See AbstractAttribute::manifest(...). 11337 ChangeStatus manifest(Attributor &A) override { 11338 // Don't manifest a universal set if it somehow made it here. 11339 if (getKnown().isUniversal()) 11340 return ChangeStatus::UNCHANGED; 11341 11342 CallBase &AssociatedCall = cast<CallBase>(getAssociatedValue()); 11343 bool Changed = addAssumptions(AssociatedCall, getAssumed().getSet()); 11344 11345 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 11346 } 11347 11348 /// See AbstractAttribute::updateImpl(...). 11349 ChangeStatus updateImpl(Attributor &A) override { 11350 const IRPosition &FnPos = IRPosition::function(*getAnchorScope()); 11351 auto &AssumptionAA = 11352 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED); 11353 bool Changed = getIntersection(AssumptionAA.getAssumed()); 11354 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 11355 } 11356 11357 /// See AbstractAttribute::trackStatistics() 11358 void trackStatistics() const override {} 11359 11360 private: 11361 /// Helper to initialized the known set as all the assumptions this call and 11362 /// the callee contain. 11363 DenseSet<StringRef> getInitialAssumptions(const IRPosition &IRP) { 11364 const CallBase &CB = cast<CallBase>(IRP.getAssociatedValue()); 11365 auto Assumptions = getAssumptions(CB); 11366 if (const Function *F = CB.getCaller()) 11367 set_union(Assumptions, getAssumptions(*F)); 11368 if (Function *F = IRP.getAssociatedFunction()) 11369 set_union(Assumptions, getAssumptions(*F)); 11370 return Assumptions; 11371 } 11372 }; 11373 } // namespace 11374 11375 AACallGraphNode *AACallEdgeIterator::operator*() const { 11376 return static_cast<AACallGraphNode *>(const_cast<AACallEdges *>( 11377 &A.getOrCreateAAFor<AACallEdges>(IRPosition::function(**I)))); 11378 } 11379 11380 void AttributorCallGraph::print() { llvm::WriteGraph(outs(), this); } 11381 11382 /// ------------------------ UnderlyingObjects --------------------------------- 11383 11384 namespace { 11385 struct AAUnderlyingObjectsImpl 11386 : StateWrapper<BooleanState, AAUnderlyingObjects> { 11387 using BaseTy = StateWrapper<BooleanState, AAUnderlyingObjects>; 11388 AAUnderlyingObjectsImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {} 11389 11390 /// See AbstractAttribute::getAsStr(). 11391 const std::string getAsStr() const override { 11392 return std::string("UnderlyingObjects ") + 11393 (isValidState() 11394 ? (std::string("inter #") + 11395 std::to_string(InterAssumedUnderlyingObjects.size()) + 11396 " objs" + std::string(", intra #") + 11397 std::to_string(IntraAssumedUnderlyingObjects.size()) + 11398 " objs") 11399 : "<invalid>"); 11400 } 11401 11402 /// See AbstractAttribute::trackStatistics() 11403 void trackStatistics() const override {} 11404 11405 /// See AbstractAttribute::updateImpl(...). 11406 ChangeStatus updateImpl(Attributor &A) override { 11407 auto &Ptr = getAssociatedValue(); 11408 11409 auto DoUpdate = [&](SmallSetVector<Value *, 8> &UnderlyingObjects, 11410 AA::ValueScope Scope) { 11411 bool UsedAssumedInformation = false; 11412 SmallPtrSet<Value *, 8> SeenObjects; 11413 SmallVector<AA::ValueAndContext> Values; 11414 11415 if (!A.getAssumedSimplifiedValues(IRPosition::value(Ptr), *this, Values, 11416 Scope, UsedAssumedInformation)) 11417 return UnderlyingObjects.insert(&Ptr); 11418 11419 bool Changed = false; 11420 11421 for (unsigned I = 0; I < Values.size(); ++I) { 11422 auto &VAC = Values[I]; 11423 auto *Obj = VAC.getValue(); 11424 Value *UO = getUnderlyingObject(Obj); 11425 if (UO && UO != VAC.getValue() && SeenObjects.insert(UO).second) { 11426 const auto &OtherAA = A.getAAFor<AAUnderlyingObjects>( 11427 *this, IRPosition::value(*UO), DepClassTy::OPTIONAL); 11428 auto Pred = [&Values](Value &V) { 11429 Values.emplace_back(V, nullptr); 11430 return true; 11431 }; 11432 11433 if (!OtherAA.forallUnderlyingObjects(Pred, Scope)) 11434 llvm_unreachable( 11435 "The forall call should not return false at this position"); 11436 11437 continue; 11438 } 11439 11440 if (isa<SelectInst>(Obj) || isa<PHINode>(Obj)) { 11441 Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope); 11442 continue; 11443 } 11444 11445 Changed |= UnderlyingObjects.insert(Obj); 11446 } 11447 11448 return Changed; 11449 }; 11450 11451 bool Changed = false; 11452 Changed |= DoUpdate(IntraAssumedUnderlyingObjects, AA::Intraprocedural); 11453 Changed |= DoUpdate(InterAssumedUnderlyingObjects, AA::Interprocedural); 11454 11455 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 11456 } 11457 11458 bool forallUnderlyingObjects( 11459 function_ref<bool(Value &)> Pred, 11460 AA::ValueScope Scope = AA::Interprocedural) const override { 11461 if (!isValidState()) 11462 return Pred(getAssociatedValue()); 11463 11464 auto &AssumedUnderlyingObjects = Scope == AA::Intraprocedural 11465 ? IntraAssumedUnderlyingObjects 11466 : InterAssumedUnderlyingObjects; 11467 for (Value *Obj : AssumedUnderlyingObjects) 11468 if (!Pred(*Obj)) 11469 return false; 11470 11471 return true; 11472 } 11473 11474 private: 11475 /// Handle the case where the value is not the actual underlying value, such 11476 /// as a phi node or a select instruction. 11477 bool handleIndirect(Attributor &A, Value &V, 11478 SmallSetVector<Value *, 8> &UnderlyingObjects, 11479 AA::ValueScope Scope) { 11480 bool Changed = false; 11481 const auto &AA = A.getAAFor<AAUnderlyingObjects>( 11482 *this, IRPosition::value(V), DepClassTy::OPTIONAL); 11483 auto Pred = [&](Value &V) { 11484 Changed |= UnderlyingObjects.insert(&V); 11485 return true; 11486 }; 11487 if (!AA.forallUnderlyingObjects(Pred, Scope)) 11488 llvm_unreachable( 11489 "The forall call should not return false at this position"); 11490 return Changed; 11491 } 11492 11493 /// All the underlying objects collected so far via intra procedural scope. 11494 SmallSetVector<Value *, 8> IntraAssumedUnderlyingObjects; 11495 /// All the underlying objects collected so far via inter procedural scope. 11496 SmallSetVector<Value *, 8> InterAssumedUnderlyingObjects; 11497 }; 11498 11499 struct AAUnderlyingObjectsFloating final : AAUnderlyingObjectsImpl { 11500 AAUnderlyingObjectsFloating(const IRPosition &IRP, Attributor &A) 11501 : AAUnderlyingObjectsImpl(IRP, A) {} 11502 }; 11503 11504 struct AAUnderlyingObjectsArgument final : AAUnderlyingObjectsImpl { 11505 AAUnderlyingObjectsArgument(const IRPosition &IRP, Attributor &A) 11506 : AAUnderlyingObjectsImpl(IRP, A) {} 11507 }; 11508 11509 struct AAUnderlyingObjectsCallSite final : AAUnderlyingObjectsImpl { 11510 AAUnderlyingObjectsCallSite(const IRPosition &IRP, Attributor &A) 11511 : AAUnderlyingObjectsImpl(IRP, A) {} 11512 }; 11513 11514 struct AAUnderlyingObjectsCallSiteArgument final : AAUnderlyingObjectsImpl { 11515 AAUnderlyingObjectsCallSiteArgument(const IRPosition &IRP, Attributor &A) 11516 : AAUnderlyingObjectsImpl(IRP, A) {} 11517 }; 11518 11519 struct AAUnderlyingObjectsReturned final : AAUnderlyingObjectsImpl { 11520 AAUnderlyingObjectsReturned(const IRPosition &IRP, Attributor &A) 11521 : AAUnderlyingObjectsImpl(IRP, A) {} 11522 }; 11523 11524 struct AAUnderlyingObjectsCallSiteReturned final : AAUnderlyingObjectsImpl { 11525 AAUnderlyingObjectsCallSiteReturned(const IRPosition &IRP, Attributor &A) 11526 : AAUnderlyingObjectsImpl(IRP, A) {} 11527 }; 11528 11529 struct AAUnderlyingObjectsFunction final : AAUnderlyingObjectsImpl { 11530 AAUnderlyingObjectsFunction(const IRPosition &IRP, Attributor &A) 11531 : AAUnderlyingObjectsImpl(IRP, A) {} 11532 }; 11533 } 11534 11535 const char AAReturnedValues::ID = 0; 11536 const char AANoUnwind::ID = 0; 11537 const char AANoSync::ID = 0; 11538 const char AANoFree::ID = 0; 11539 const char AANonNull::ID = 0; 11540 const char AANoRecurse::ID = 0; 11541 const char AAWillReturn::ID = 0; 11542 const char AAUndefinedBehavior::ID = 0; 11543 const char AANoAlias::ID = 0; 11544 const char AAIntraFnReachability::ID = 0; 11545 const char AANoReturn::ID = 0; 11546 const char AAIsDead::ID = 0; 11547 const char AADereferenceable::ID = 0; 11548 const char AAAlign::ID = 0; 11549 const char AAInstanceInfo::ID = 0; 11550 const char AANoCapture::ID = 0; 11551 const char AAValueSimplify::ID = 0; 11552 const char AAHeapToStack::ID = 0; 11553 const char AAPrivatizablePtr::ID = 0; 11554 const char AAMemoryBehavior::ID = 0; 11555 const char AAMemoryLocation::ID = 0; 11556 const char AAValueConstantRange::ID = 0; 11557 const char AAPotentialConstantValues::ID = 0; 11558 const char AAPotentialValues::ID = 0; 11559 const char AANoUndef::ID = 0; 11560 const char AACallEdges::ID = 0; 11561 const char AAInterFnReachability::ID = 0; 11562 const char AAPointerInfo::ID = 0; 11563 const char AAAssumptionInfo::ID = 0; 11564 const char AAUnderlyingObjects::ID = 0; 11565 11566 // Macro magic to create the static generator function for attributes that 11567 // follow the naming scheme. 11568 11569 #define SWITCH_PK_INV(CLASS, PK, POS_NAME) \ 11570 case IRPosition::PK: \ 11571 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!"); 11572 11573 #define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \ 11574 case IRPosition::PK: \ 11575 AA = new (A.Allocator) CLASS##SUFFIX(IRP, A); \ 11576 ++NumAAs; \ 11577 break; 11578 11579 #define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \ 11580 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 11581 CLASS *AA = nullptr; \ 11582 switch (IRP.getPositionKind()) { \ 11583 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \ 11584 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \ 11585 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \ 11586 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \ 11587 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \ 11588 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \ 11589 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \ 11590 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \ 11591 } \ 11592 return *AA; \ 11593 } 11594 11595 #define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \ 11596 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 11597 CLASS *AA = nullptr; \ 11598 switch (IRP.getPositionKind()) { \ 11599 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \ 11600 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \ 11601 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \ 11602 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \ 11603 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \ 11604 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \ 11605 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \ 11606 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \ 11607 } \ 11608 return *AA; \ 11609 } 11610 11611 #define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \ 11612 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 11613 CLASS *AA = nullptr; \ 11614 switch (IRP.getPositionKind()) { \ 11615 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \ 11616 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \ 11617 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \ 11618 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \ 11619 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \ 11620 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \ 11621 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \ 11622 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \ 11623 } \ 11624 return *AA; \ 11625 } 11626 11627 #define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \ 11628 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 11629 CLASS *AA = nullptr; \ 11630 switch (IRP.getPositionKind()) { \ 11631 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \ 11632 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \ 11633 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \ 11634 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \ 11635 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \ 11636 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \ 11637 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \ 11638 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \ 11639 } \ 11640 return *AA; \ 11641 } 11642 11643 #define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \ 11644 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 11645 CLASS *AA = nullptr; \ 11646 switch (IRP.getPositionKind()) { \ 11647 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \ 11648 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \ 11649 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \ 11650 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \ 11651 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \ 11652 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \ 11653 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \ 11654 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \ 11655 } \ 11656 return *AA; \ 11657 } 11658 11659 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUnwind) 11660 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoSync) 11661 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoRecurse) 11662 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAWillReturn) 11663 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoReturn) 11664 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReturnedValues) 11665 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryLocation) 11666 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AACallEdges) 11667 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAssumptionInfo) 11668 11669 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonNull) 11670 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoAlias) 11671 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPrivatizablePtr) 11672 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADereferenceable) 11673 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAlign) 11674 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAInstanceInfo) 11675 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoCapture) 11676 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueConstantRange) 11677 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPotentialConstantValues) 11678 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPotentialValues) 11679 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUndef) 11680 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPointerInfo) 11681 11682 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify) 11683 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIsDead) 11684 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree) 11685 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAUnderlyingObjects) 11686 11687 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAHeapToStack) 11688 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAUndefinedBehavior) 11689 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIntraFnReachability) 11690 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAInterFnReachability) 11691 11692 CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryBehavior) 11693 11694 #undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION 11695 #undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION 11696 #undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION 11697 #undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION 11698 #undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION 11699 #undef SWITCH_PK_CREATE 11700 #undef SWITCH_PK_INV 11701