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/ADT/StringExtras.h" 28 #include "llvm/Analysis/AliasAnalysis.h" 29 #include "llvm/Analysis/AssumeBundleQueries.h" 30 #include "llvm/Analysis/AssumptionCache.h" 31 #include "llvm/Analysis/CaptureTracking.h" 32 #include "llvm/Analysis/CycleAnalysis.h" 33 #include "llvm/Analysis/InstructionSimplify.h" 34 #include "llvm/Analysis/LazyValueInfo.h" 35 #include "llvm/Analysis/MemoryBuiltins.h" 36 #include "llvm/Analysis/OptimizationRemarkEmitter.h" 37 #include "llvm/Analysis/ScalarEvolution.h" 38 #include "llvm/Analysis/TargetTransformInfo.h" 39 #include "llvm/Analysis/ValueTracking.h" 40 #include "llvm/IR/Argument.h" 41 #include "llvm/IR/Assumptions.h" 42 #include "llvm/IR/Attributes.h" 43 #include "llvm/IR/BasicBlock.h" 44 #include "llvm/IR/Constant.h" 45 #include "llvm/IR/Constants.h" 46 #include "llvm/IR/DataLayout.h" 47 #include "llvm/IR/DerivedTypes.h" 48 #include "llvm/IR/GlobalValue.h" 49 #include "llvm/IR/IRBuilder.h" 50 #include "llvm/IR/InlineAsm.h" 51 #include "llvm/IR/InstrTypes.h" 52 #include "llvm/IR/Instruction.h" 53 #include "llvm/IR/Instructions.h" 54 #include "llvm/IR/IntrinsicInst.h" 55 #include "llvm/IR/IntrinsicsAMDGPU.h" 56 #include "llvm/IR/IntrinsicsNVPTX.h" 57 #include "llvm/IR/LLVMContext.h" 58 #include "llvm/IR/NoFolder.h" 59 #include "llvm/IR/Value.h" 60 #include "llvm/IR/ValueHandle.h" 61 #include "llvm/Support/Alignment.h" 62 #include "llvm/Support/Casting.h" 63 #include "llvm/Support/CommandLine.h" 64 #include "llvm/Support/ErrorHandling.h" 65 #include "llvm/Support/GraphWriter.h" 66 #include "llvm/Support/MathExtras.h" 67 #include "llvm/Support/raw_ostream.h" 68 #include "llvm/Transforms/Utils/Local.h" 69 #include "llvm/Transforms/Utils/ValueMapper.h" 70 #include <cassert> 71 #include <numeric> 72 #include <optional> 73 74 using namespace llvm; 75 76 #define DEBUG_TYPE "attributor" 77 78 static cl::opt<bool> ManifestInternal( 79 "attributor-manifest-internal", cl::Hidden, 80 cl::desc("Manifest Attributor internal string attributes."), 81 cl::init(false)); 82 83 static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128), 84 cl::Hidden); 85 86 template <> 87 unsigned llvm::PotentialConstantIntValuesState::MaxPotentialValues = 0; 88 89 template <> unsigned llvm::PotentialLLVMValuesState::MaxPotentialValues = -1; 90 91 static cl::opt<unsigned, true> MaxPotentialValues( 92 "attributor-max-potential-values", cl::Hidden, 93 cl::desc("Maximum number of potential values to be " 94 "tracked for each position."), 95 cl::location(llvm::PotentialConstantIntValuesState::MaxPotentialValues), 96 cl::init(7)); 97 98 static cl::opt<int> MaxPotentialValuesIterations( 99 "attributor-max-potential-values-iterations", cl::Hidden, 100 cl::desc( 101 "Maximum number of iterations we keep dismantling potential values."), 102 cl::init(64)); 103 104 STATISTIC(NumAAs, "Number of abstract attributes created"); 105 106 // Some helper macros to deal with statistics tracking. 107 // 108 // Usage: 109 // For simple IR attribute tracking overload trackStatistics in the abstract 110 // attribute and choose the right STATS_DECLTRACK_********* macro, 111 // e.g.,: 112 // void trackStatistics() const override { 113 // STATS_DECLTRACK_ARG_ATTR(returned) 114 // } 115 // If there is a single "increment" side one can use the macro 116 // STATS_DECLTRACK with a custom message. If there are multiple increment 117 // sides, STATS_DECL and STATS_TRACK can also be used separately. 118 // 119 #define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \ 120 ("Number of " #TYPE " marked '" #NAME "'") 121 #define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME 122 #define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG); 123 #define STATS_DECL(NAME, TYPE, MSG) \ 124 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG); 125 #define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE)); 126 #define STATS_DECLTRACK(NAME, TYPE, MSG) \ 127 { \ 128 STATS_DECL(NAME, TYPE, MSG) \ 129 STATS_TRACK(NAME, TYPE) \ 130 } 131 #define STATS_DECLTRACK_ARG_ATTR(NAME) \ 132 STATS_DECLTRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME)) 133 #define STATS_DECLTRACK_CSARG_ATTR(NAME) \ 134 STATS_DECLTRACK(NAME, CSArguments, \ 135 BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME)) 136 #define STATS_DECLTRACK_FN_ATTR(NAME) \ 137 STATS_DECLTRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME)) 138 #define STATS_DECLTRACK_CS_ATTR(NAME) \ 139 STATS_DECLTRACK(NAME, CS, BUILD_STAT_MSG_IR_ATTR(call site, NAME)) 140 #define STATS_DECLTRACK_FNRET_ATTR(NAME) \ 141 STATS_DECLTRACK(NAME, FunctionReturn, \ 142 BUILD_STAT_MSG_IR_ATTR(function returns, NAME)) 143 #define STATS_DECLTRACK_CSRET_ATTR(NAME) \ 144 STATS_DECLTRACK(NAME, CSReturn, \ 145 BUILD_STAT_MSG_IR_ATTR(call site returns, NAME)) 146 #define STATS_DECLTRACK_FLOATING_ATTR(NAME) \ 147 STATS_DECLTRACK(NAME, Floating, \ 148 ("Number of floating values known to be '" #NAME "'")) 149 150 // Specialization of the operator<< for abstract attributes subclasses. This 151 // disambiguates situations where multiple operators are applicable. 152 namespace llvm { 153 #define PIPE_OPERATOR(CLASS) \ 154 raw_ostream &operator<<(raw_ostream &OS, const CLASS &AA) { \ 155 return OS << static_cast<const AbstractAttribute &>(AA); \ 156 } 157 158 PIPE_OPERATOR(AAIsDead) 159 PIPE_OPERATOR(AANoUnwind) 160 PIPE_OPERATOR(AANoSync) 161 PIPE_OPERATOR(AANoRecurse) 162 PIPE_OPERATOR(AANonConvergent) 163 PIPE_OPERATOR(AAWillReturn) 164 PIPE_OPERATOR(AANoReturn) 165 PIPE_OPERATOR(AANonNull) 166 PIPE_OPERATOR(AAMustProgress) 167 PIPE_OPERATOR(AANoAlias) 168 PIPE_OPERATOR(AADereferenceable) 169 PIPE_OPERATOR(AAAlign) 170 PIPE_OPERATOR(AAInstanceInfo) 171 PIPE_OPERATOR(AANoCapture) 172 PIPE_OPERATOR(AAValueSimplify) 173 PIPE_OPERATOR(AANoFree) 174 PIPE_OPERATOR(AAHeapToStack) 175 PIPE_OPERATOR(AAIntraFnReachability) 176 PIPE_OPERATOR(AAMemoryBehavior) 177 PIPE_OPERATOR(AAMemoryLocation) 178 PIPE_OPERATOR(AAValueConstantRange) 179 PIPE_OPERATOR(AAPrivatizablePtr) 180 PIPE_OPERATOR(AAUndefinedBehavior) 181 PIPE_OPERATOR(AAPotentialConstantValues) 182 PIPE_OPERATOR(AAPotentialValues) 183 PIPE_OPERATOR(AANoUndef) 184 PIPE_OPERATOR(AANoFPClass) 185 PIPE_OPERATOR(AACallEdges) 186 PIPE_OPERATOR(AAInterFnReachability) 187 PIPE_OPERATOR(AAPointerInfo) 188 PIPE_OPERATOR(AAAssumptionInfo) 189 PIPE_OPERATOR(AAUnderlyingObjects) 190 PIPE_OPERATOR(AAAddressSpace) 191 192 #undef PIPE_OPERATOR 193 194 template <> 195 ChangeStatus clampStateAndIndicateChange<DerefState>(DerefState &S, 196 const DerefState &R) { 197 ChangeStatus CS0 = 198 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState); 199 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState); 200 return CS0 | CS1; 201 } 202 203 } // namespace llvm 204 205 static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I, 206 bool HeaderOnly, Cycle **CPtr = nullptr) { 207 if (!CI) 208 return true; 209 auto *BB = I->getParent(); 210 auto *C = CI->getCycle(BB); 211 if (!C) 212 return false; 213 if (CPtr) 214 *CPtr = C; 215 return !HeaderOnly || BB == C->getHeader(); 216 } 217 218 /// Checks if a type could have padding bytes. 219 static bool isDenselyPacked(Type *Ty, const DataLayout &DL) { 220 // There is no size information, so be conservative. 221 if (!Ty->isSized()) 222 return false; 223 224 // If the alloc size is not equal to the storage size, then there are padding 225 // bytes. For x86_fp80 on x86-64, size: 80 alloc size: 128. 226 if (DL.getTypeSizeInBits(Ty) != DL.getTypeAllocSizeInBits(Ty)) 227 return false; 228 229 // FIXME: This isn't the right way to check for padding in vectors with 230 // non-byte-size elements. 231 if (VectorType *SeqTy = dyn_cast<VectorType>(Ty)) 232 return isDenselyPacked(SeqTy->getElementType(), DL); 233 234 // For array types, check for padding within members. 235 if (ArrayType *SeqTy = dyn_cast<ArrayType>(Ty)) 236 return isDenselyPacked(SeqTy->getElementType(), DL); 237 238 if (!isa<StructType>(Ty)) 239 return true; 240 241 // Check for padding within and between elements of a struct. 242 StructType *StructTy = cast<StructType>(Ty); 243 const StructLayout *Layout = DL.getStructLayout(StructTy); 244 uint64_t StartPos = 0; 245 for (unsigned I = 0, E = StructTy->getNumElements(); I < E; ++I) { 246 Type *ElTy = StructTy->getElementType(I); 247 if (!isDenselyPacked(ElTy, DL)) 248 return false; 249 if (StartPos != Layout->getElementOffsetInBits(I)) 250 return false; 251 StartPos += DL.getTypeAllocSizeInBits(ElTy); 252 } 253 254 return true; 255 } 256 257 /// Get pointer operand of memory accessing instruction. If \p I is 258 /// not a memory accessing instruction, return nullptr. If \p AllowVolatile, 259 /// is set to false and the instruction is volatile, return nullptr. 260 static const Value *getPointerOperand(const Instruction *I, 261 bool AllowVolatile) { 262 if (!AllowVolatile && I->isVolatile()) 263 return nullptr; 264 265 if (auto *LI = dyn_cast<LoadInst>(I)) { 266 return LI->getPointerOperand(); 267 } 268 269 if (auto *SI = dyn_cast<StoreInst>(I)) { 270 return SI->getPointerOperand(); 271 } 272 273 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(I)) { 274 return CXI->getPointerOperand(); 275 } 276 277 if (auto *RMWI = dyn_cast<AtomicRMWInst>(I)) { 278 return RMWI->getPointerOperand(); 279 } 280 281 return nullptr; 282 } 283 284 /// Helper function to create a pointer of type \p ResTy, based on \p Ptr, and 285 /// advanced by \p Offset bytes. To aid later analysis the method tries to build 286 /// getelement pointer instructions that traverse the natural type of \p Ptr if 287 /// possible. If that fails, the remaining offset is adjusted byte-wise, hence 288 /// through a cast to i8*. 289 /// 290 /// TODO: This could probably live somewhere more prominantly if it doesn't 291 /// already exist. 292 static Value *constructPointer(Type *ResTy, Type *PtrElemTy, Value *Ptr, 293 int64_t Offset, IRBuilder<NoFolder> &IRB, 294 const DataLayout &DL) { 295 assert(Offset >= 0 && "Negative offset not supported yet!"); 296 LLVM_DEBUG(dbgs() << "Construct pointer: " << *Ptr << " + " << Offset 297 << "-bytes as " << *ResTy << "\n"); 298 299 if (Offset) { 300 Type *Ty = PtrElemTy; 301 APInt IntOffset(DL.getIndexTypeSizeInBits(Ptr->getType()), Offset); 302 SmallVector<APInt> IntIndices = DL.getGEPIndicesForOffset(Ty, IntOffset); 303 304 SmallVector<Value *, 4> ValIndices; 305 std::string GEPName = Ptr->getName().str(); 306 for (const APInt &Index : IntIndices) { 307 ValIndices.push_back(IRB.getInt(Index)); 308 GEPName += "." + std::to_string(Index.getZExtValue()); 309 } 310 311 // Create a GEP for the indices collected above. 312 Ptr = IRB.CreateGEP(PtrElemTy, Ptr, ValIndices, GEPName); 313 314 // If an offset is left we use byte-wise adjustment. 315 if (IntOffset != 0) { 316 Ptr = IRB.CreateBitCast(Ptr, IRB.getInt8PtrTy()); 317 Ptr = IRB.CreateGEP(IRB.getInt8Ty(), Ptr, IRB.getInt(IntOffset), 318 GEPName + ".b" + Twine(IntOffset.getZExtValue())); 319 } 320 } 321 322 // Ensure the result has the requested type. 323 Ptr = IRB.CreatePointerBitCastOrAddrSpaceCast(Ptr, ResTy, 324 Ptr->getName() + ".cast"); 325 326 LLVM_DEBUG(dbgs() << "Constructed pointer: " << *Ptr << "\n"); 327 return Ptr; 328 } 329 330 static const Value * 331 stripAndAccumulateOffsets(Attributor &A, const AbstractAttribute &QueryingAA, 332 const Value *Val, const DataLayout &DL, APInt &Offset, 333 bool GetMinOffset, bool AllowNonInbounds, 334 bool UseAssumed = false) { 335 336 auto AttributorAnalysis = [&](Value &V, APInt &ROffset) -> bool { 337 const IRPosition &Pos = IRPosition::value(V); 338 // Only track dependence if we are going to use the assumed info. 339 const AAValueConstantRange *ValueConstantRangeAA = 340 A.getAAFor<AAValueConstantRange>(QueryingAA, Pos, 341 UseAssumed ? DepClassTy::OPTIONAL 342 : DepClassTy::NONE); 343 if (!ValueConstantRangeAA) 344 return false; 345 ConstantRange Range = UseAssumed ? ValueConstantRangeAA->getAssumed() 346 : ValueConstantRangeAA->getKnown(); 347 if (Range.isFullSet()) 348 return false; 349 350 // We can only use the lower part of the range because the upper part can 351 // be higher than what the value can really be. 352 if (GetMinOffset) 353 ROffset = Range.getSignedMin(); 354 else 355 ROffset = Range.getSignedMax(); 356 return true; 357 }; 358 359 return Val->stripAndAccumulateConstantOffsets(DL, Offset, AllowNonInbounds, 360 /* AllowInvariant */ true, 361 AttributorAnalysis); 362 } 363 364 static const Value * 365 getMinimalBaseOfPointer(Attributor &A, const AbstractAttribute &QueryingAA, 366 const Value *Ptr, int64_t &BytesOffset, 367 const DataLayout &DL, bool AllowNonInbounds = false) { 368 APInt OffsetAPInt(DL.getIndexTypeSizeInBits(Ptr->getType()), 0); 369 const Value *Base = 370 stripAndAccumulateOffsets(A, QueryingAA, Ptr, DL, OffsetAPInt, 371 /* GetMinOffset */ true, AllowNonInbounds); 372 373 BytesOffset = OffsetAPInt.getSExtValue(); 374 return Base; 375 } 376 377 /// Clamp the information known for all returned values of a function 378 /// (identified by \p QueryingAA) into \p S. 379 template <typename AAType, typename StateType = typename AAType::StateType, 380 Attribute::AttrKind IRAttributeKind = Attribute::None, 381 bool RecurseForSelectAndPHI = true> 382 static void clampReturnedValueStates( 383 Attributor &A, const AAType &QueryingAA, StateType &S, 384 const IRPosition::CallBaseContext *CBContext = nullptr) { 385 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for " 386 << QueryingAA << " into " << S << "\n"); 387 388 assert((QueryingAA.getIRPosition().getPositionKind() == 389 IRPosition::IRP_RETURNED || 390 QueryingAA.getIRPosition().getPositionKind() == 391 IRPosition::IRP_CALL_SITE_RETURNED) && 392 "Can only clamp returned value states for a function returned or call " 393 "site returned position!"); 394 395 // Use an optional state as there might not be any return values and we want 396 // to join (IntegerState::operator&) the state of all there are. 397 std::optional<StateType> T; 398 399 // Callback for each possibly returned value. 400 auto CheckReturnValue = [&](Value &RV) -> bool { 401 const IRPosition &RVPos = IRPosition::value(RV, CBContext); 402 // If possible, use the hasAssumedIRAttr interface. 403 if (IRAttributeKind != Attribute::None) { 404 bool IsKnown; 405 return AA::hasAssumedIRAttr<IRAttributeKind>( 406 A, &QueryingAA, RVPos, DepClassTy::REQUIRED, IsKnown); 407 } 408 409 const AAType *AA = 410 A.getAAFor<AAType>(QueryingAA, RVPos, DepClassTy::REQUIRED); 411 if (!AA) 412 return false; 413 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV 414 << " AA: " << AA->getAsStr(&A) << " @ " << RVPos << "\n"); 415 const StateType &AAS = AA->getState(); 416 if (!T) 417 T = StateType::getBestState(AAS); 418 *T &= AAS; 419 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T 420 << "\n"); 421 return T->isValidState(); 422 }; 423 424 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA, 425 AA::ValueScope::Intraprocedural, 426 RecurseForSelectAndPHI)) 427 S.indicatePessimisticFixpoint(); 428 else if (T) 429 S ^= *T; 430 } 431 432 namespace { 433 /// Helper class for generic deduction: return value -> returned position. 434 template <typename AAType, typename BaseType, 435 typename StateType = typename BaseType::StateType, 436 bool PropagateCallBaseContext = false, 437 Attribute::AttrKind IRAttributeKind = Attribute::None, 438 bool RecurseForSelectAndPHI = true> 439 struct AAReturnedFromReturnedValues : public BaseType { 440 AAReturnedFromReturnedValues(const IRPosition &IRP, Attributor &A) 441 : BaseType(IRP, A) {} 442 443 /// See AbstractAttribute::updateImpl(...). 444 ChangeStatus updateImpl(Attributor &A) override { 445 StateType S(StateType::getBestState(this->getState())); 446 clampReturnedValueStates<AAType, StateType, IRAttributeKind, RecurseForSelectAndPHI>( 447 A, *this, S, 448 PropagateCallBaseContext ? this->getCallBaseContext() : nullptr); 449 // TODO: If we know we visited all returned values, thus no are assumed 450 // dead, we can take the known information from the state T. 451 return clampStateAndIndicateChange<StateType>(this->getState(), S); 452 } 453 }; 454 455 /// Clamp the information known at all call sites for a given argument 456 /// (identified by \p QueryingAA) into \p S. 457 template <typename AAType, typename StateType = typename AAType::StateType, 458 Attribute::AttrKind IRAttributeKind = Attribute::None> 459 static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA, 460 StateType &S) { 461 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for " 462 << QueryingAA << " into " << S << "\n"); 463 464 assert(QueryingAA.getIRPosition().getPositionKind() == 465 IRPosition::IRP_ARGUMENT && 466 "Can only clamp call site argument states for an argument position!"); 467 468 // Use an optional state as there might not be any return values and we want 469 // to join (IntegerState::operator&) the state of all there are. 470 std::optional<StateType> T; 471 472 // The argument number which is also the call site argument number. 473 unsigned ArgNo = QueryingAA.getIRPosition().getCallSiteArgNo(); 474 475 auto CallSiteCheck = [&](AbstractCallSite ACS) { 476 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo); 477 // Check if a coresponding argument was found or if it is on not associated 478 // (which can happen for callback calls). 479 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID) 480 return false; 481 482 // If possible, use the hasAssumedIRAttr interface. 483 if (IRAttributeKind != Attribute::None) { 484 bool IsKnown; 485 return AA::hasAssumedIRAttr<IRAttributeKind>( 486 A, &QueryingAA, ACSArgPos, DepClassTy::REQUIRED, IsKnown); 487 } 488 489 const AAType *AA = 490 A.getAAFor<AAType>(QueryingAA, ACSArgPos, DepClassTy::REQUIRED); 491 if (!AA) 492 return false; 493 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction() 494 << " AA: " << AA->getAsStr(&A) << " @" << ACSArgPos 495 << "\n"); 496 const StateType &AAS = AA->getState(); 497 if (!T) 498 T = StateType::getBestState(AAS); 499 *T &= AAS; 500 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T 501 << "\n"); 502 return T->isValidState(); 503 }; 504 505 bool UsedAssumedInformation = false; 506 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true, 507 UsedAssumedInformation)) 508 S.indicatePessimisticFixpoint(); 509 else if (T) 510 S ^= *T; 511 } 512 513 /// This function is the bridge between argument position and the call base 514 /// context. 515 template <typename AAType, typename BaseType, 516 typename StateType = typename AAType::StateType, 517 Attribute::AttrKind IRAttributeKind = Attribute::None> 518 bool getArgumentStateFromCallBaseContext(Attributor &A, 519 BaseType &QueryingAttribute, 520 IRPosition &Pos, StateType &State) { 521 assert((Pos.getPositionKind() == IRPosition::IRP_ARGUMENT) && 522 "Expected an 'argument' position !"); 523 const CallBase *CBContext = Pos.getCallBaseContext(); 524 if (!CBContext) 525 return false; 526 527 int ArgNo = Pos.getCallSiteArgNo(); 528 assert(ArgNo >= 0 && "Invalid Arg No!"); 529 const IRPosition CBArgPos = IRPosition::callsite_argument(*CBContext, ArgNo); 530 531 // If possible, use the hasAssumedIRAttr interface. 532 if (IRAttributeKind != Attribute::None) { 533 bool IsKnown; 534 return AA::hasAssumedIRAttr<IRAttributeKind>( 535 A, &QueryingAttribute, CBArgPos, DepClassTy::REQUIRED, IsKnown); 536 } 537 538 const auto *AA = 539 A.getAAFor<AAType>(QueryingAttribute, CBArgPos, DepClassTy::REQUIRED); 540 if (!AA) 541 return false; 542 const StateType &CBArgumentState = 543 static_cast<const StateType &>(AA->getState()); 544 545 LLVM_DEBUG(dbgs() << "[Attributor] Briding Call site context to argument" 546 << "Position:" << Pos << "CB Arg state:" << CBArgumentState 547 << "\n"); 548 549 // NOTE: If we want to do call site grouping it should happen here. 550 State ^= CBArgumentState; 551 return true; 552 } 553 554 /// Helper class for generic deduction: call site argument -> argument position. 555 template <typename AAType, typename BaseType, 556 typename StateType = typename AAType::StateType, 557 bool BridgeCallBaseContext = false, 558 Attribute::AttrKind IRAttributeKind = Attribute::None> 559 struct AAArgumentFromCallSiteArguments : public BaseType { 560 AAArgumentFromCallSiteArguments(const IRPosition &IRP, Attributor &A) 561 : BaseType(IRP, A) {} 562 563 /// See AbstractAttribute::updateImpl(...). 564 ChangeStatus updateImpl(Attributor &A) override { 565 StateType S = StateType::getBestState(this->getState()); 566 567 if (BridgeCallBaseContext) { 568 bool Success = 569 getArgumentStateFromCallBaseContext<AAType, BaseType, StateType, 570 IRAttributeKind>( 571 A, *this, this->getIRPosition(), S); 572 if (Success) 573 return clampStateAndIndicateChange<StateType>(this->getState(), S); 574 } 575 clampCallSiteArgumentStates<AAType, StateType, IRAttributeKind>(A, *this, 576 S); 577 578 // TODO: If we know we visited all incoming values, thus no are assumed 579 // dead, we can take the known information from the state T. 580 return clampStateAndIndicateChange<StateType>(this->getState(), S); 581 } 582 }; 583 584 /// Helper class for generic replication: function returned -> cs returned. 585 template <typename AAType, typename BaseType, 586 typename StateType = typename BaseType::StateType, 587 bool IntroduceCallBaseContext = false, 588 Attribute::AttrKind IRAttributeKind = Attribute::None> 589 struct AACallSiteReturnedFromReturned : public BaseType { 590 AACallSiteReturnedFromReturned(const IRPosition &IRP, Attributor &A) 591 : BaseType(IRP, A) {} 592 593 /// See AbstractAttribute::updateImpl(...). 594 ChangeStatus updateImpl(Attributor &A) override { 595 assert(this->getIRPosition().getPositionKind() == 596 IRPosition::IRP_CALL_SITE_RETURNED && 597 "Can only wrap function returned positions for call site returned " 598 "positions!"); 599 auto &S = this->getState(); 600 601 const Function *AssociatedFunction = 602 this->getIRPosition().getAssociatedFunction(); 603 if (!AssociatedFunction) 604 return S.indicatePessimisticFixpoint(); 605 606 CallBase &CBContext = cast<CallBase>(this->getAnchorValue()); 607 if (IntroduceCallBaseContext) 608 LLVM_DEBUG(dbgs() << "[Attributor] Introducing call base context:" 609 << CBContext << "\n"); 610 611 IRPosition FnPos = IRPosition::returned( 612 *AssociatedFunction, IntroduceCallBaseContext ? &CBContext : nullptr); 613 614 // If possible, use the hasAssumedIRAttr interface. 615 if (IRAttributeKind != Attribute::None) { 616 bool IsKnown; 617 if (!AA::hasAssumedIRAttr<IRAttributeKind>(A, this, FnPos, 618 DepClassTy::REQUIRED, IsKnown)) 619 return S.indicatePessimisticFixpoint(); 620 return ChangeStatus::UNCHANGED; 621 } 622 623 const AAType *AA = A.getAAFor<AAType>(*this, FnPos, DepClassTy::REQUIRED); 624 if (!AA) 625 return S.indicatePessimisticFixpoint(); 626 return clampStateAndIndicateChange(S, AA->getState()); 627 } 628 }; 629 630 /// Helper function to accumulate uses. 631 template <class AAType, typename StateType = typename AAType::StateType> 632 static void followUsesInContext(AAType &AA, Attributor &A, 633 MustBeExecutedContextExplorer &Explorer, 634 const Instruction *CtxI, 635 SetVector<const Use *> &Uses, 636 StateType &State) { 637 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI); 638 for (unsigned u = 0; u < Uses.size(); ++u) { 639 const Use *U = Uses[u]; 640 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) { 641 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd); 642 if (Found && AA.followUseInMBEC(A, U, UserI, State)) 643 for (const Use &Us : UserI->uses()) 644 Uses.insert(&Us); 645 } 646 } 647 } 648 649 /// Use the must-be-executed-context around \p I to add information into \p S. 650 /// The AAType class is required to have `followUseInMBEC` method with the 651 /// following signature and behaviour: 652 /// 653 /// bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I) 654 /// U - Underlying use. 655 /// I - The user of the \p U. 656 /// Returns true if the value should be tracked transitively. 657 /// 658 template <class AAType, typename StateType = typename AAType::StateType> 659 static void followUsesInMBEC(AAType &AA, Attributor &A, StateType &S, 660 Instruction &CtxI) { 661 MustBeExecutedContextExplorer *Explorer = 662 A.getInfoCache().getMustBeExecutedContextExplorer(); 663 if (!Explorer) 664 return; 665 666 // Container for (transitive) uses of the associated value. 667 SetVector<const Use *> Uses; 668 for (const Use &U : AA.getIRPosition().getAssociatedValue().uses()) 669 Uses.insert(&U); 670 671 followUsesInContext<AAType>(AA, A, *Explorer, &CtxI, Uses, S); 672 673 if (S.isAtFixpoint()) 674 return; 675 676 SmallVector<const BranchInst *, 4> BrInsts; 677 auto Pred = [&](const Instruction *I) { 678 if (const BranchInst *Br = dyn_cast<BranchInst>(I)) 679 if (Br->isConditional()) 680 BrInsts.push_back(Br); 681 return true; 682 }; 683 684 // Here, accumulate conditional branch instructions in the context. We 685 // explore the child paths and collect the known states. The disjunction of 686 // those states can be merged to its own state. Let ParentState_i be a state 687 // to indicate the known information for an i-th branch instruction in the 688 // context. ChildStates are created for its successors respectively. 689 // 690 // ParentS_1 = ChildS_{1, 1} /\ ChildS_{1, 2} /\ ... /\ ChildS_{1, n_1} 691 // ParentS_2 = ChildS_{2, 1} /\ ChildS_{2, 2} /\ ... /\ ChildS_{2, n_2} 692 // ... 693 // ParentS_m = ChildS_{m, 1} /\ ChildS_{m, 2} /\ ... /\ ChildS_{m, n_m} 694 // 695 // Known State |= ParentS_1 \/ ParentS_2 \/... \/ ParentS_m 696 // 697 // FIXME: Currently, recursive branches are not handled. For example, we 698 // can't deduce that ptr must be dereferenced in below function. 699 // 700 // void f(int a, int c, int *ptr) { 701 // if(a) 702 // if (b) { 703 // *ptr = 0; 704 // } else { 705 // *ptr = 1; 706 // } 707 // else { 708 // if (b) { 709 // *ptr = 0; 710 // } else { 711 // *ptr = 1; 712 // } 713 // } 714 // } 715 716 Explorer->checkForAllContext(&CtxI, Pred); 717 for (const BranchInst *Br : BrInsts) { 718 StateType ParentState; 719 720 // The known state of the parent state is a conjunction of children's 721 // known states so it is initialized with a best state. 722 ParentState.indicateOptimisticFixpoint(); 723 724 for (const BasicBlock *BB : Br->successors()) { 725 StateType ChildState; 726 727 size_t BeforeSize = Uses.size(); 728 followUsesInContext(AA, A, *Explorer, &BB->front(), Uses, ChildState); 729 730 // Erase uses which only appear in the child. 731 for (auto It = Uses.begin() + BeforeSize; It != Uses.end();) 732 It = Uses.erase(It); 733 734 ParentState &= ChildState; 735 } 736 737 // Use only known state. 738 S += ParentState; 739 } 740 } 741 } // namespace 742 743 /// ------------------------ PointerInfo --------------------------------------- 744 745 namespace llvm { 746 namespace AA { 747 namespace PointerInfo { 748 749 struct State; 750 751 } // namespace PointerInfo 752 } // namespace AA 753 754 /// Helper for AA::PointerInfo::Access DenseMap/Set usage. 755 template <> 756 struct DenseMapInfo<AAPointerInfo::Access> : DenseMapInfo<Instruction *> { 757 using Access = AAPointerInfo::Access; 758 static inline Access getEmptyKey(); 759 static inline Access getTombstoneKey(); 760 static unsigned getHashValue(const Access &A); 761 static bool isEqual(const Access &LHS, const Access &RHS); 762 }; 763 764 /// Helper that allows RangeTy as a key in a DenseMap. 765 template <> struct DenseMapInfo<AA::RangeTy> { 766 static inline AA::RangeTy getEmptyKey() { 767 auto EmptyKey = DenseMapInfo<int64_t>::getEmptyKey(); 768 return AA::RangeTy{EmptyKey, EmptyKey}; 769 } 770 771 static inline AA::RangeTy getTombstoneKey() { 772 auto TombstoneKey = DenseMapInfo<int64_t>::getTombstoneKey(); 773 return AA::RangeTy{TombstoneKey, TombstoneKey}; 774 } 775 776 static unsigned getHashValue(const AA::RangeTy &Range) { 777 return detail::combineHashValue( 778 DenseMapInfo<int64_t>::getHashValue(Range.Offset), 779 DenseMapInfo<int64_t>::getHashValue(Range.Size)); 780 } 781 782 static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B) { 783 return A == B; 784 } 785 }; 786 787 /// Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign 788 /// but the instruction 789 struct AccessAsInstructionInfo : DenseMapInfo<Instruction *> { 790 using Base = DenseMapInfo<Instruction *>; 791 using Access = AAPointerInfo::Access; 792 static inline Access getEmptyKey(); 793 static inline Access getTombstoneKey(); 794 static unsigned getHashValue(const Access &A); 795 static bool isEqual(const Access &LHS, const Access &RHS); 796 }; 797 798 } // namespace llvm 799 800 /// A type to track pointer/struct usage and accesses for AAPointerInfo. 801 struct AA::PointerInfo::State : public AbstractState { 802 /// Return the best possible representable state. 803 static State getBestState(const State &SIS) { return State(); } 804 805 /// Return the worst possible representable state. 806 static State getWorstState(const State &SIS) { 807 State R; 808 R.indicatePessimisticFixpoint(); 809 return R; 810 } 811 812 State() = default; 813 State(State &&SIS) = default; 814 815 const State &getAssumed() const { return *this; } 816 817 /// See AbstractState::isValidState(). 818 bool isValidState() const override { return BS.isValidState(); } 819 820 /// See AbstractState::isAtFixpoint(). 821 bool isAtFixpoint() const override { return BS.isAtFixpoint(); } 822 823 /// See AbstractState::indicateOptimisticFixpoint(). 824 ChangeStatus indicateOptimisticFixpoint() override { 825 BS.indicateOptimisticFixpoint(); 826 return ChangeStatus::UNCHANGED; 827 } 828 829 /// See AbstractState::indicatePessimisticFixpoint(). 830 ChangeStatus indicatePessimisticFixpoint() override { 831 BS.indicatePessimisticFixpoint(); 832 return ChangeStatus::CHANGED; 833 } 834 835 State &operator=(const State &R) { 836 if (this == &R) 837 return *this; 838 BS = R.BS; 839 AccessList = R.AccessList; 840 OffsetBins = R.OffsetBins; 841 RemoteIMap = R.RemoteIMap; 842 return *this; 843 } 844 845 State &operator=(State &&R) { 846 if (this == &R) 847 return *this; 848 std::swap(BS, R.BS); 849 std::swap(AccessList, R.AccessList); 850 std::swap(OffsetBins, R.OffsetBins); 851 std::swap(RemoteIMap, R.RemoteIMap); 852 return *this; 853 } 854 855 /// Add a new Access to the state at offset \p Offset and with size \p Size. 856 /// The access is associated with \p I, writes \p Content (if anything), and 857 /// is of kind \p Kind. If an Access already exists for the same \p I and same 858 /// \p RemoteI, the two are combined, potentially losing information about 859 /// offset and size. The resulting access must now be moved from its original 860 /// OffsetBin to the bin for its new offset. 861 /// 862 /// \Returns CHANGED, if the state changed, UNCHANGED otherwise. 863 ChangeStatus addAccess(Attributor &A, const AAPointerInfo::RangeList &Ranges, 864 Instruction &I, std::optional<Value *> Content, 865 AAPointerInfo::AccessKind Kind, Type *Ty, 866 Instruction *RemoteI = nullptr); 867 868 using OffsetBinsTy = DenseMap<RangeTy, SmallSet<unsigned, 4>>; 869 870 using const_bin_iterator = OffsetBinsTy::const_iterator; 871 const_bin_iterator begin() const { return OffsetBins.begin(); } 872 const_bin_iterator end() const { return OffsetBins.end(); } 873 874 const AAPointerInfo::Access &getAccess(unsigned Index) const { 875 return AccessList[Index]; 876 } 877 878 protected: 879 // Every memory instruction results in an Access object. We maintain a list of 880 // all Access objects that we own, along with the following maps: 881 // 882 // - OffsetBins: RangeTy -> { Access } 883 // - RemoteIMap: RemoteI x LocalI -> Access 884 // 885 // A RemoteI is any instruction that accesses memory. RemoteI is different 886 // from LocalI if and only if LocalI is a call; then RemoteI is some 887 // instruction in the callgraph starting from LocalI. Multiple paths in the 888 // callgraph from LocalI to RemoteI may produce multiple accesses, but these 889 // are all combined into a single Access object. This may result in loss of 890 // information in RangeTy in the Access object. 891 SmallVector<AAPointerInfo::Access> AccessList; 892 OffsetBinsTy OffsetBins; 893 DenseMap<const Instruction *, SmallVector<unsigned>> RemoteIMap; 894 895 /// See AAPointerInfo::forallInterferingAccesses. 896 bool forallInterferingAccesses( 897 AA::RangeTy Range, 898 function_ref<bool(const AAPointerInfo::Access &, bool)> CB) const { 899 if (!isValidState()) 900 return false; 901 902 for (const auto &It : OffsetBins) { 903 AA::RangeTy ItRange = It.getFirst(); 904 if (!Range.mayOverlap(ItRange)) 905 continue; 906 bool IsExact = Range == ItRange && !Range.offsetOrSizeAreUnknown(); 907 for (auto Index : It.getSecond()) { 908 auto &Access = AccessList[Index]; 909 if (!CB(Access, IsExact)) 910 return false; 911 } 912 } 913 return true; 914 } 915 916 /// See AAPointerInfo::forallInterferingAccesses. 917 bool forallInterferingAccesses( 918 Instruction &I, 919 function_ref<bool(const AAPointerInfo::Access &, bool)> CB, 920 AA::RangeTy &Range) const { 921 if (!isValidState()) 922 return false; 923 924 auto LocalList = RemoteIMap.find(&I); 925 if (LocalList == RemoteIMap.end()) { 926 return true; 927 } 928 929 for (unsigned Index : LocalList->getSecond()) { 930 for (auto &R : AccessList[Index]) { 931 Range &= R; 932 if (Range.offsetAndSizeAreUnknown()) 933 break; 934 } 935 } 936 return forallInterferingAccesses(Range, CB); 937 } 938 939 private: 940 /// State to track fixpoint and validity. 941 BooleanState BS; 942 }; 943 944 ChangeStatus AA::PointerInfo::State::addAccess( 945 Attributor &A, const AAPointerInfo::RangeList &Ranges, Instruction &I, 946 std::optional<Value *> Content, AAPointerInfo::AccessKind Kind, Type *Ty, 947 Instruction *RemoteI) { 948 RemoteI = RemoteI ? RemoteI : &I; 949 950 // Check if we have an access for this instruction, if not, simply add it. 951 auto &LocalList = RemoteIMap[RemoteI]; 952 bool AccExists = false; 953 unsigned AccIndex = AccessList.size(); 954 for (auto Index : LocalList) { 955 auto &A = AccessList[Index]; 956 if (A.getLocalInst() == &I) { 957 AccExists = true; 958 AccIndex = Index; 959 break; 960 } 961 } 962 963 auto AddToBins = [&](const AAPointerInfo::RangeList &ToAdd) { 964 LLVM_DEBUG(if (ToAdd.size()) dbgs() 965 << "[AAPointerInfo] Inserting access in new offset bins\n";); 966 967 for (auto Key : ToAdd) { 968 LLVM_DEBUG(dbgs() << " key " << Key << "\n"); 969 OffsetBins[Key].insert(AccIndex); 970 } 971 }; 972 973 if (!AccExists) { 974 AccessList.emplace_back(&I, RemoteI, Ranges, Content, Kind, Ty); 975 assert((AccessList.size() == AccIndex + 1) && 976 "New Access should have been at AccIndex"); 977 LocalList.push_back(AccIndex); 978 AddToBins(AccessList[AccIndex].getRanges()); 979 return ChangeStatus::CHANGED; 980 } 981 982 // Combine the new Access with the existing Access, and then update the 983 // mapping in the offset bins. 984 AAPointerInfo::Access Acc(&I, RemoteI, Ranges, Content, Kind, Ty); 985 auto &Current = AccessList[AccIndex]; 986 auto Before = Current; 987 Current &= Acc; 988 if (Current == Before) 989 return ChangeStatus::UNCHANGED; 990 991 auto &ExistingRanges = Before.getRanges(); 992 auto &NewRanges = Current.getRanges(); 993 994 // Ranges that are in the old access but not the new access need to be removed 995 // from the offset bins. 996 AAPointerInfo::RangeList ToRemove; 997 AAPointerInfo::RangeList::set_difference(ExistingRanges, NewRanges, ToRemove); 998 LLVM_DEBUG(if (ToRemove.size()) dbgs() 999 << "[AAPointerInfo] Removing access from old offset bins\n";); 1000 1001 for (auto Key : ToRemove) { 1002 LLVM_DEBUG(dbgs() << " key " << Key << "\n"); 1003 assert(OffsetBins.count(Key) && "Existing Access must be in some bin."); 1004 auto &Bin = OffsetBins[Key]; 1005 assert(Bin.count(AccIndex) && 1006 "Expected bin to actually contain the Access."); 1007 Bin.erase(AccIndex); 1008 } 1009 1010 // Ranges that are in the new access but not the old access need to be added 1011 // to the offset bins. 1012 AAPointerInfo::RangeList ToAdd; 1013 AAPointerInfo::RangeList::set_difference(NewRanges, ExistingRanges, ToAdd); 1014 AddToBins(ToAdd); 1015 return ChangeStatus::CHANGED; 1016 } 1017 1018 namespace { 1019 1020 /// A helper containing a list of offsets computed for a Use. Ideally this 1021 /// list should be strictly ascending, but we ensure that only when we 1022 /// actually translate the list of offsets to a RangeList. 1023 struct OffsetInfo { 1024 using VecTy = SmallVector<int64_t>; 1025 using const_iterator = VecTy::const_iterator; 1026 VecTy Offsets; 1027 1028 const_iterator begin() const { return Offsets.begin(); } 1029 const_iterator end() const { return Offsets.end(); } 1030 1031 bool operator==(const OffsetInfo &RHS) const { 1032 return Offsets == RHS.Offsets; 1033 } 1034 1035 bool operator!=(const OffsetInfo &RHS) const { return !(*this == RHS); } 1036 1037 void insert(int64_t Offset) { Offsets.push_back(Offset); } 1038 bool isUnassigned() const { return Offsets.size() == 0; } 1039 1040 bool isUnknown() const { 1041 if (isUnassigned()) 1042 return false; 1043 if (Offsets.size() == 1) 1044 return Offsets.front() == AA::RangeTy::Unknown; 1045 return false; 1046 } 1047 1048 void setUnknown() { 1049 Offsets.clear(); 1050 Offsets.push_back(AA::RangeTy::Unknown); 1051 } 1052 1053 void addToAll(int64_t Inc) { 1054 for (auto &Offset : Offsets) { 1055 Offset += Inc; 1056 } 1057 } 1058 1059 /// Copy offsets from \p R into the current list. 1060 /// 1061 /// Ideally all lists should be strictly ascending, but we defer that to the 1062 /// actual use of the list. So we just blindly append here. 1063 void merge(const OffsetInfo &R) { Offsets.append(R.Offsets); } 1064 }; 1065 1066 #ifndef NDEBUG 1067 static raw_ostream &operator<<(raw_ostream &OS, const OffsetInfo &OI) { 1068 ListSeparator LS; 1069 OS << "["; 1070 for (auto Offset : OI) { 1071 OS << LS << Offset; 1072 } 1073 OS << "]"; 1074 return OS; 1075 } 1076 #endif // NDEBUG 1077 1078 struct AAPointerInfoImpl 1079 : public StateWrapper<AA::PointerInfo::State, AAPointerInfo> { 1080 using BaseTy = StateWrapper<AA::PointerInfo::State, AAPointerInfo>; 1081 AAPointerInfoImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {} 1082 1083 /// See AbstractAttribute::getAsStr(). 1084 const std::string getAsStr(Attributor *A) const override { 1085 return std::string("PointerInfo ") + 1086 (isValidState() ? (std::string("#") + 1087 std::to_string(OffsetBins.size()) + " bins") 1088 : "<invalid>"); 1089 } 1090 1091 /// See AbstractAttribute::manifest(...). 1092 ChangeStatus manifest(Attributor &A) override { 1093 return AAPointerInfo::manifest(A); 1094 } 1095 1096 bool forallInterferingAccesses( 1097 AA::RangeTy Range, 1098 function_ref<bool(const AAPointerInfo::Access &, bool)> CB) 1099 const override { 1100 return State::forallInterferingAccesses(Range, CB); 1101 } 1102 1103 bool forallInterferingAccesses( 1104 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I, 1105 bool FindInterferingWrites, bool FindInterferingReads, 1106 function_ref<bool(const Access &, bool)> UserCB, bool &HasBeenWrittenTo, 1107 AA::RangeTy &Range) const override { 1108 HasBeenWrittenTo = false; 1109 1110 SmallPtrSet<const Access *, 8> DominatingWrites; 1111 SmallVector<std::pair<const Access *, bool>, 8> InterferingAccesses; 1112 1113 Function &Scope = *I.getFunction(); 1114 bool IsKnownNoSync; 1115 bool IsAssumedNoSync = AA::hasAssumedIRAttr<Attribute::NoSync>( 1116 A, &QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL, 1117 IsKnownNoSync); 1118 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>( 1119 IRPosition::function(Scope), &QueryingAA, DepClassTy::NONE); 1120 bool AllInSameNoSyncFn = IsAssumedNoSync; 1121 bool InstIsExecutedByInitialThreadOnly = 1122 ExecDomainAA && ExecDomainAA->isExecutedByInitialThreadOnly(I); 1123 1124 // If the function is not ending in aligned barriers, we need the stores to 1125 // be in aligned barriers. The load being in one is not sufficient since the 1126 // store might be executed by a thread that disappears after, causing the 1127 // aligned barrier guarding the load to unblock and the load to read a value 1128 // that has no CFG path to the load. 1129 bool InstIsExecutedInAlignedRegion = 1130 FindInterferingReads && ExecDomainAA && 1131 ExecDomainAA->isExecutedInAlignedRegion(A, I); 1132 1133 if (InstIsExecutedInAlignedRegion || InstIsExecutedByInitialThreadOnly) 1134 A.recordDependence(*ExecDomainAA, QueryingAA, DepClassTy::OPTIONAL); 1135 1136 InformationCache &InfoCache = A.getInfoCache(); 1137 bool IsThreadLocalObj = 1138 AA::isAssumedThreadLocalObject(A, getAssociatedValue(), *this); 1139 1140 // Helper to determine if we need to consider threading, which we cannot 1141 // right now. However, if the function is (assumed) nosync or the thread 1142 // executing all instructions is the main thread only we can ignore 1143 // threading. Also, thread-local objects do not require threading reasoning. 1144 // Finally, we can ignore threading if either access is executed in an 1145 // aligned region. 1146 auto CanIgnoreThreadingForInst = [&](const Instruction &I) -> bool { 1147 if (IsThreadLocalObj || AllInSameNoSyncFn) 1148 return true; 1149 const auto *FnExecDomainAA = 1150 I.getFunction() == &Scope 1151 ? ExecDomainAA 1152 : A.lookupAAFor<AAExecutionDomain>( 1153 IRPosition::function(*I.getFunction()), &QueryingAA, 1154 DepClassTy::NONE); 1155 if (!FnExecDomainAA) 1156 return false; 1157 if (InstIsExecutedInAlignedRegion || 1158 (FindInterferingWrites && 1159 FnExecDomainAA->isExecutedInAlignedRegion(A, I))) { 1160 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL); 1161 return true; 1162 } 1163 if (InstIsExecutedByInitialThreadOnly && 1164 FnExecDomainAA->isExecutedByInitialThreadOnly(I)) { 1165 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL); 1166 return true; 1167 } 1168 return false; 1169 }; 1170 1171 // Helper to determine if the access is executed by the same thread as the 1172 // given instruction, for now it is sufficient to avoid any potential 1173 // threading effects as we cannot deal with them anyway. 1174 auto CanIgnoreThreading = [&](const Access &Acc) -> bool { 1175 return CanIgnoreThreadingForInst(*Acc.getRemoteInst()) || 1176 (Acc.getRemoteInst() != Acc.getLocalInst() && 1177 CanIgnoreThreadingForInst(*Acc.getLocalInst())); 1178 }; 1179 1180 // TODO: Use inter-procedural reachability and dominance. 1181 bool IsKnownNoRecurse; 1182 AA::hasAssumedIRAttr<Attribute::NoRecurse>( 1183 A, this, IRPosition::function(Scope), DepClassTy::OPTIONAL, 1184 IsKnownNoRecurse); 1185 1186 const bool UseDominanceReasoning = 1187 FindInterferingWrites && IsKnownNoRecurse; 1188 const DominatorTree *DT = 1189 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(Scope); 1190 1191 // Helper to check if a value has "kernel lifetime", that is it will not 1192 // outlive a GPU kernel. This is true for shared, constant, and local 1193 // globals on AMD and NVIDIA GPUs. 1194 auto HasKernelLifetime = [&](Value *V, Module &M) { 1195 if (!AA::isGPU(M)) 1196 return false; 1197 switch (AA::GPUAddressSpace(V->getType()->getPointerAddressSpace())) { 1198 case AA::GPUAddressSpace::Shared: 1199 case AA::GPUAddressSpace::Constant: 1200 case AA::GPUAddressSpace::Local: 1201 return true; 1202 default: 1203 return false; 1204 }; 1205 }; 1206 1207 // The IsLiveInCalleeCB will be used by the AA::isPotentiallyReachable query 1208 // to determine if we should look at reachability from the callee. For 1209 // certain pointers we know the lifetime and we do not have to step into the 1210 // callee to determine reachability as the pointer would be dead in the 1211 // callee. See the conditional initialization below. 1212 std::function<bool(const Function &)> IsLiveInCalleeCB; 1213 1214 if (auto *AI = dyn_cast<AllocaInst>(&getAssociatedValue())) { 1215 // If the alloca containing function is not recursive the alloca 1216 // must be dead in the callee. 1217 const Function *AIFn = AI->getFunction(); 1218 bool IsKnownNoRecurse; 1219 if (AA::hasAssumedIRAttr<Attribute::NoRecurse>( 1220 A, this, IRPosition::function(*AIFn), DepClassTy::OPTIONAL, 1221 IsKnownNoRecurse)) { 1222 IsLiveInCalleeCB = [AIFn](const Function &Fn) { return AIFn != &Fn; }; 1223 } 1224 } else if (auto *GV = dyn_cast<GlobalValue>(&getAssociatedValue())) { 1225 // If the global has kernel lifetime we can stop if we reach a kernel 1226 // as it is "dead" in the (unknown) callees. 1227 if (HasKernelLifetime(GV, *GV->getParent())) 1228 IsLiveInCalleeCB = [](const Function &Fn) { 1229 return !Fn.hasFnAttribute("kernel"); 1230 }; 1231 } 1232 1233 // Set of accesses/instructions that will overwrite the result and are 1234 // therefore blockers in the reachability traversal. 1235 AA::InstExclusionSetTy ExclusionSet; 1236 1237 auto AccessCB = [&](const Access &Acc, bool Exact) { 1238 if (Exact && Acc.isMustAccess() && Acc.getRemoteInst() != &I) { 1239 if (Acc.isWrite() || (isa<LoadInst>(I) && Acc.isWriteOrAssumption())) 1240 ExclusionSet.insert(Acc.getRemoteInst()); 1241 } 1242 1243 if ((!FindInterferingWrites || !Acc.isWriteOrAssumption()) && 1244 (!FindInterferingReads || !Acc.isRead())) 1245 return true; 1246 1247 bool Dominates = FindInterferingWrites && DT && Exact && 1248 Acc.isMustAccess() && 1249 (Acc.getRemoteInst()->getFunction() == &Scope) && 1250 DT->dominates(Acc.getRemoteInst(), &I); 1251 if (Dominates) 1252 DominatingWrites.insert(&Acc); 1253 1254 // Track if all interesting accesses are in the same `nosync` function as 1255 // the given instruction. 1256 AllInSameNoSyncFn &= Acc.getRemoteInst()->getFunction() == &Scope; 1257 1258 InterferingAccesses.push_back({&Acc, Exact}); 1259 return true; 1260 }; 1261 if (!State::forallInterferingAccesses(I, AccessCB, Range)) 1262 return false; 1263 1264 HasBeenWrittenTo = !DominatingWrites.empty(); 1265 1266 // Dominating writes form a chain, find the least/lowest member. 1267 Instruction *LeastDominatingWriteInst = nullptr; 1268 for (const Access *Acc : DominatingWrites) { 1269 if (!LeastDominatingWriteInst) { 1270 LeastDominatingWriteInst = Acc->getRemoteInst(); 1271 } else if (DT->dominates(LeastDominatingWriteInst, 1272 Acc->getRemoteInst())) { 1273 LeastDominatingWriteInst = Acc->getRemoteInst(); 1274 } 1275 } 1276 1277 // Helper to determine if we can skip a specific write access. 1278 auto CanSkipAccess = [&](const Access &Acc, bool Exact) { 1279 if (!CanIgnoreThreading(Acc)) 1280 return false; 1281 1282 // Check read (RAW) dependences and write (WAR) dependences as necessary. 1283 // If we successfully excluded all effects we are interested in, the 1284 // access can be skipped. 1285 bool ReadChecked = !FindInterferingReads; 1286 bool WriteChecked = !FindInterferingWrites; 1287 1288 // If the instruction cannot reach the access, the former does not 1289 // interfere with what the access reads. 1290 if (!ReadChecked) { 1291 if (!AA::isPotentiallyReachable(A, I, *Acc.getRemoteInst(), QueryingAA, 1292 &ExclusionSet, IsLiveInCalleeCB)) 1293 ReadChecked = true; 1294 } 1295 // If the instruction cannot be reach from the access, the latter does not 1296 // interfere with what the instruction reads. 1297 if (!WriteChecked) { 1298 if (!AA::isPotentiallyReachable(A, *Acc.getRemoteInst(), I, QueryingAA, 1299 &ExclusionSet, IsLiveInCalleeCB)) 1300 WriteChecked = true; 1301 } 1302 1303 // If we still might be affected by the write of the access but there are 1304 // dominating writes in the function of the instruction 1305 // (HasBeenWrittenTo), we can try to reason that the access is overwritten 1306 // by them. This would have happend above if they are all in the same 1307 // function, so we only check the inter-procedural case. Effectively, we 1308 // want to show that there is no call after the dominting write that might 1309 // reach the access, and when it returns reach the instruction with the 1310 // updated value. To this end, we iterate all call sites, check if they 1311 // might reach the instruction without going through another access 1312 // (ExclusionSet) and at the same time might reach the access. However, 1313 // that is all part of AAInterFnReachability. 1314 if (!WriteChecked && HasBeenWrittenTo && 1315 Acc.getRemoteInst()->getFunction() != &Scope) { 1316 1317 const auto *FnReachabilityAA = A.getAAFor<AAInterFnReachability>( 1318 QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL); 1319 1320 // Without going backwards in the call tree, can we reach the access 1321 // from the least dominating write. Do not allow to pass the instruction 1322 // itself either. 1323 bool Inserted = ExclusionSet.insert(&I).second; 1324 1325 if (!FnReachabilityAA || 1326 !FnReachabilityAA->instructionCanReach( 1327 A, *LeastDominatingWriteInst, 1328 *Acc.getRemoteInst()->getFunction(), &ExclusionSet)) 1329 WriteChecked = true; 1330 1331 if (Inserted) 1332 ExclusionSet.erase(&I); 1333 } 1334 1335 if (ReadChecked && WriteChecked) 1336 return true; 1337 1338 if (!DT || !UseDominanceReasoning) 1339 return false; 1340 if (!DominatingWrites.count(&Acc)) 1341 return false; 1342 return LeastDominatingWriteInst != Acc.getRemoteInst(); 1343 }; 1344 1345 // Run the user callback on all accesses we cannot skip and return if 1346 // that succeeded for all or not. 1347 for (auto &It : InterferingAccesses) { 1348 if ((!AllInSameNoSyncFn && !IsThreadLocalObj && !ExecDomainAA) || 1349 !CanSkipAccess(*It.first, It.second)) { 1350 if (!UserCB(*It.first, It.second)) 1351 return false; 1352 } 1353 } 1354 return true; 1355 } 1356 1357 ChangeStatus translateAndAddStateFromCallee(Attributor &A, 1358 const AAPointerInfo &OtherAA, 1359 CallBase &CB) { 1360 using namespace AA::PointerInfo; 1361 if (!OtherAA.getState().isValidState() || !isValidState()) 1362 return indicatePessimisticFixpoint(); 1363 1364 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA); 1365 bool IsByval = OtherAAImpl.getAssociatedArgument()->hasByValAttr(); 1366 1367 // Combine the accesses bin by bin. 1368 ChangeStatus Changed = ChangeStatus::UNCHANGED; 1369 const auto &State = OtherAAImpl.getState(); 1370 for (const auto &It : State) { 1371 for (auto Index : It.getSecond()) { 1372 const auto &RAcc = State.getAccess(Index); 1373 if (IsByval && !RAcc.isRead()) 1374 continue; 1375 bool UsedAssumedInformation = false; 1376 AccessKind AK = RAcc.getKind(); 1377 auto Content = A.translateArgumentToCallSiteContent( 1378 RAcc.getContent(), CB, *this, UsedAssumedInformation); 1379 AK = AccessKind(AK & (IsByval ? AccessKind::AK_R : AccessKind::AK_RW)); 1380 AK = AccessKind(AK | (RAcc.isMayAccess() ? AK_MAY : AK_MUST)); 1381 1382 Changed |= addAccess(A, RAcc.getRanges(), CB, Content, AK, 1383 RAcc.getType(), RAcc.getRemoteInst()); 1384 } 1385 } 1386 return Changed; 1387 } 1388 1389 ChangeStatus translateAndAddState(Attributor &A, const AAPointerInfo &OtherAA, 1390 const OffsetInfo &Offsets, CallBase &CB) { 1391 using namespace AA::PointerInfo; 1392 if (!OtherAA.getState().isValidState() || !isValidState()) 1393 return indicatePessimisticFixpoint(); 1394 1395 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA); 1396 1397 // Combine the accesses bin by bin. 1398 ChangeStatus Changed = ChangeStatus::UNCHANGED; 1399 const auto &State = OtherAAImpl.getState(); 1400 for (const auto &It : State) { 1401 for (auto Index : It.getSecond()) { 1402 const auto &RAcc = State.getAccess(Index); 1403 for (auto Offset : Offsets) { 1404 auto NewRanges = Offset == AA::RangeTy::Unknown 1405 ? AA::RangeTy::getUnknown() 1406 : RAcc.getRanges(); 1407 if (!NewRanges.isUnknown()) { 1408 NewRanges.addToAllOffsets(Offset); 1409 } 1410 Changed |= 1411 addAccess(A, NewRanges, CB, RAcc.getContent(), RAcc.getKind(), 1412 RAcc.getType(), RAcc.getRemoteInst()); 1413 } 1414 } 1415 } 1416 return Changed; 1417 } 1418 1419 /// Statistic tracking for all AAPointerInfo implementations. 1420 /// See AbstractAttribute::trackStatistics(). 1421 void trackPointerInfoStatistics(const IRPosition &IRP) const {} 1422 1423 /// Dump the state into \p O. 1424 void dumpState(raw_ostream &O) { 1425 for (auto &It : OffsetBins) { 1426 O << "[" << It.first.Offset << "-" << It.first.Offset + It.first.Size 1427 << "] : " << It.getSecond().size() << "\n"; 1428 for (auto AccIndex : It.getSecond()) { 1429 auto &Acc = AccessList[AccIndex]; 1430 O << " - " << Acc.getKind() << " - " << *Acc.getLocalInst() << "\n"; 1431 if (Acc.getLocalInst() != Acc.getRemoteInst()) 1432 O << " --> " << *Acc.getRemoteInst() 1433 << "\n"; 1434 if (!Acc.isWrittenValueYetUndetermined()) { 1435 if (isa_and_nonnull<Function>(Acc.getWrittenValue())) 1436 O << " - c: func " << Acc.getWrittenValue()->getName() 1437 << "\n"; 1438 else if (Acc.getWrittenValue()) 1439 O << " - c: " << *Acc.getWrittenValue() << "\n"; 1440 else 1441 O << " - c: <unknown>\n"; 1442 } 1443 } 1444 } 1445 } 1446 }; 1447 1448 struct AAPointerInfoFloating : public AAPointerInfoImpl { 1449 using AccessKind = AAPointerInfo::AccessKind; 1450 AAPointerInfoFloating(const IRPosition &IRP, Attributor &A) 1451 : AAPointerInfoImpl(IRP, A) {} 1452 1453 /// Deal with an access and signal if it was handled successfully. 1454 bool handleAccess(Attributor &A, Instruction &I, 1455 std::optional<Value *> Content, AccessKind Kind, 1456 SmallVectorImpl<int64_t> &Offsets, ChangeStatus &Changed, 1457 Type &Ty) { 1458 using namespace AA::PointerInfo; 1459 auto Size = AA::RangeTy::Unknown; 1460 const DataLayout &DL = A.getDataLayout(); 1461 TypeSize AccessSize = DL.getTypeStoreSize(&Ty); 1462 if (!AccessSize.isScalable()) 1463 Size = AccessSize.getFixedValue(); 1464 1465 // Make a strictly ascending list of offsets as required by addAccess() 1466 llvm::sort(Offsets); 1467 auto *Last = std::unique(Offsets.begin(), Offsets.end()); 1468 Offsets.erase(Last, Offsets.end()); 1469 1470 VectorType *VT = dyn_cast<VectorType>(&Ty); 1471 if (!VT || VT->getElementCount().isScalable() || 1472 !Content.value_or(nullptr) || !isa<Constant>(*Content) || 1473 (*Content)->getType() != VT || 1474 DL.getTypeStoreSize(VT->getElementType()).isScalable()) { 1475 Changed = Changed | addAccess(A, {Offsets, Size}, I, Content, Kind, &Ty); 1476 } else { 1477 // Handle vector stores with constant content element-wise. 1478 // TODO: We could look for the elements or create instructions 1479 // representing them. 1480 // TODO: We need to push the Content into the range abstraction 1481 // (AA::RangeTy) to allow different content values for different 1482 // ranges. ranges. Hence, support vectors storing different values. 1483 Type *ElementType = VT->getElementType(); 1484 int64_t ElementSize = DL.getTypeStoreSize(ElementType).getFixedValue(); 1485 auto *ConstContent = cast<Constant>(*Content); 1486 Type *Int32Ty = Type::getInt32Ty(ElementType->getContext()); 1487 SmallVector<int64_t> ElementOffsets(Offsets.begin(), Offsets.end()); 1488 1489 for (int i = 0, e = VT->getElementCount().getFixedValue(); i != e; ++i) { 1490 Value *ElementContent = ConstantExpr::getExtractElement( 1491 ConstContent, ConstantInt::get(Int32Ty, i)); 1492 1493 // Add the element access. 1494 Changed = Changed | addAccess(A, {ElementOffsets, ElementSize}, I, 1495 ElementContent, Kind, ElementType); 1496 1497 // Advance the offsets for the next element. 1498 for (auto &ElementOffset : ElementOffsets) 1499 ElementOffset += ElementSize; 1500 } 1501 } 1502 return true; 1503 }; 1504 1505 /// See AbstractAttribute::updateImpl(...). 1506 ChangeStatus updateImpl(Attributor &A) override; 1507 1508 /// If the indices to \p GEP can be traced to constants, incorporate all 1509 /// of these into \p UsrOI. 1510 /// 1511 /// \return true iff \p UsrOI is updated. 1512 bool collectConstantsForGEP(Attributor &A, const DataLayout &DL, 1513 OffsetInfo &UsrOI, const OffsetInfo &PtrOI, 1514 const GEPOperator *GEP); 1515 1516 /// See AbstractAttribute::trackStatistics() 1517 void trackStatistics() const override { 1518 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition()); 1519 } 1520 }; 1521 1522 bool AAPointerInfoFloating::collectConstantsForGEP(Attributor &A, 1523 const DataLayout &DL, 1524 OffsetInfo &UsrOI, 1525 const OffsetInfo &PtrOI, 1526 const GEPOperator *GEP) { 1527 unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType()); 1528 MapVector<Value *, APInt> VariableOffsets; 1529 APInt ConstantOffset(BitWidth, 0); 1530 1531 assert(!UsrOI.isUnknown() && !PtrOI.isUnknown() && 1532 "Don't look for constant values if the offset has already been " 1533 "determined to be unknown."); 1534 1535 if (!GEP->collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset)) { 1536 UsrOI.setUnknown(); 1537 return true; 1538 } 1539 1540 LLVM_DEBUG(dbgs() << "[AAPointerInfo] GEP offset is " 1541 << (VariableOffsets.empty() ? "" : "not") << " constant " 1542 << *GEP << "\n"); 1543 1544 auto Union = PtrOI; 1545 Union.addToAll(ConstantOffset.getSExtValue()); 1546 1547 // Each VI in VariableOffsets has a set of potential constant values. Every 1548 // combination of elements, picked one each from these sets, is separately 1549 // added to the original set of offsets, thus resulting in more offsets. 1550 for (const auto &VI : VariableOffsets) { 1551 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>( 1552 *this, IRPosition::value(*VI.first), DepClassTy::OPTIONAL); 1553 if (!PotentialConstantsAA || !PotentialConstantsAA->isValidState()) { 1554 UsrOI.setUnknown(); 1555 return true; 1556 } 1557 1558 // UndefValue is treated as a zero, which leaves Union as is. 1559 if (PotentialConstantsAA->undefIsContained()) 1560 continue; 1561 1562 // We need at least one constant in every set to compute an actual offset. 1563 // Otherwise, we end up pessimizing AAPointerInfo by respecting offsets that 1564 // don't actually exist. In other words, the absence of constant values 1565 // implies that the operation can be assumed dead for now. 1566 auto &AssumedSet = PotentialConstantsAA->getAssumedSet(); 1567 if (AssumedSet.empty()) 1568 return false; 1569 1570 OffsetInfo Product; 1571 for (const auto &ConstOffset : AssumedSet) { 1572 auto CopyPerOffset = Union; 1573 CopyPerOffset.addToAll(ConstOffset.getSExtValue() * 1574 VI.second.getZExtValue()); 1575 Product.merge(CopyPerOffset); 1576 } 1577 Union = Product; 1578 } 1579 1580 UsrOI = std::move(Union); 1581 return true; 1582 } 1583 1584 ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) { 1585 using namespace AA::PointerInfo; 1586 ChangeStatus Changed = ChangeStatus::UNCHANGED; 1587 const DataLayout &DL = A.getDataLayout(); 1588 Value &AssociatedValue = getAssociatedValue(); 1589 1590 DenseMap<Value *, OffsetInfo> OffsetInfoMap; 1591 OffsetInfoMap[&AssociatedValue].insert(0); 1592 1593 auto HandlePassthroughUser = [&](Value *Usr, Value *CurPtr, bool &Follow) { 1594 // One does not simply walk into a map and assign a reference to a possibly 1595 // new location. That can cause an invalidation before the assignment 1596 // happens, like so: 1597 // 1598 // OffsetInfoMap[Usr] = OffsetInfoMap[CurPtr]; /* bad idea! */ 1599 // 1600 // The RHS is a reference that may be invalidated by an insertion caused by 1601 // the LHS. So we ensure that the side-effect of the LHS happens first. 1602 auto &UsrOI = OffsetInfoMap[Usr]; 1603 auto &PtrOI = OffsetInfoMap[CurPtr]; 1604 assert(!PtrOI.isUnassigned() && 1605 "Cannot pass through if the input Ptr was not visited!"); 1606 UsrOI = PtrOI; 1607 Follow = true; 1608 return true; 1609 }; 1610 1611 const auto *F = getAnchorScope(); 1612 const auto *CI = 1613 F ? A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>(*F) 1614 : nullptr; 1615 const auto *TLI = 1616 F ? A.getInfoCache().getTargetLibraryInfoForFunction(*F) : nullptr; 1617 1618 auto UsePred = [&](const Use &U, bool &Follow) -> bool { 1619 Value *CurPtr = U.get(); 1620 User *Usr = U.getUser(); 1621 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Analyze " << *CurPtr << " in " << *Usr 1622 << "\n"); 1623 assert(OffsetInfoMap.count(CurPtr) && 1624 "The current pointer offset should have been seeded!"); 1625 1626 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Usr)) { 1627 if (CE->isCast()) 1628 return HandlePassthroughUser(Usr, CurPtr, Follow); 1629 if (CE->isCompare()) 1630 return true; 1631 if (!isa<GEPOperator>(CE)) { 1632 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled constant user " << *CE 1633 << "\n"); 1634 return false; 1635 } 1636 } 1637 if (auto *GEP = dyn_cast<GEPOperator>(Usr)) { 1638 // Note the order here, the Usr access might change the map, CurPtr is 1639 // already in it though. 1640 auto &UsrOI = OffsetInfoMap[Usr]; 1641 auto &PtrOI = OffsetInfoMap[CurPtr]; 1642 1643 if (UsrOI.isUnknown()) 1644 return true; 1645 1646 if (PtrOI.isUnknown()) { 1647 Follow = true; 1648 UsrOI.setUnknown(); 1649 return true; 1650 } 1651 1652 Follow = collectConstantsForGEP(A, DL, UsrOI, PtrOI, GEP); 1653 return true; 1654 } 1655 if (isa<PtrToIntInst>(Usr)) 1656 return false; 1657 if (isa<CastInst>(Usr) || isa<SelectInst>(Usr) || isa<ReturnInst>(Usr)) 1658 return HandlePassthroughUser(Usr, CurPtr, Follow); 1659 1660 // For PHIs we need to take care of the recurrence explicitly as the value 1661 // might change while we iterate through a loop. For now, we give up if 1662 // the PHI is not invariant. 1663 if (isa<PHINode>(Usr)) { 1664 // Note the order here, the Usr access might change the map, CurPtr is 1665 // already in it though. 1666 bool IsFirstPHIUser = !OffsetInfoMap.count(Usr); 1667 auto &UsrOI = OffsetInfoMap[Usr]; 1668 auto &PtrOI = OffsetInfoMap[CurPtr]; 1669 1670 // Check if the PHI operand has already an unknown offset as we can't 1671 // improve on that anymore. 1672 if (PtrOI.isUnknown()) { 1673 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand offset unknown " 1674 << *CurPtr << " in " << *Usr << "\n"); 1675 Follow = !UsrOI.isUnknown(); 1676 UsrOI.setUnknown(); 1677 return true; 1678 } 1679 1680 // Check if the PHI is invariant (so far). 1681 if (UsrOI == PtrOI) { 1682 assert(!PtrOI.isUnassigned() && 1683 "Cannot assign if the current Ptr was not visited!"); 1684 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant (so far)"); 1685 return true; 1686 } 1687 1688 // Check if the PHI operand can be traced back to AssociatedValue. 1689 APInt Offset( 1690 DL.getIndexSizeInBits(CurPtr->getType()->getPointerAddressSpace()), 1691 0); 1692 Value *CurPtrBase = CurPtr->stripAndAccumulateConstantOffsets( 1693 DL, Offset, /* AllowNonInbounds */ true); 1694 auto It = OffsetInfoMap.find(CurPtrBase); 1695 if (It == OffsetInfoMap.end()) { 1696 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand is too complex " 1697 << *CurPtr << " in " << *Usr << "\n"); 1698 UsrOI.setUnknown(); 1699 Follow = true; 1700 return true; 1701 } 1702 1703 // Check if the PHI operand is not dependent on the PHI itself. Every 1704 // recurrence is a cyclic net of PHIs in the data flow, and has an 1705 // equivalent Cycle in the control flow. One of those PHIs must be in the 1706 // header of that control flow Cycle. This is independent of the choice of 1707 // Cycles reported by CycleInfo. It is sufficient to check the PHIs in 1708 // every Cycle header; if such a node is marked unknown, this will 1709 // eventually propagate through the whole net of PHIs in the recurrence. 1710 if (mayBeInCycle(CI, cast<Instruction>(Usr), /* HeaderOnly */ true)) { 1711 auto BaseOI = It->getSecond(); 1712 BaseOI.addToAll(Offset.getZExtValue()); 1713 if (IsFirstPHIUser || BaseOI == UsrOI) { 1714 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant " << *CurPtr 1715 << " in " << *Usr << "\n"); 1716 return HandlePassthroughUser(Usr, CurPtr, Follow); 1717 } 1718 1719 LLVM_DEBUG( 1720 dbgs() << "[AAPointerInfo] PHI operand pointer offset mismatch " 1721 << *CurPtr << " in " << *Usr << "\n"); 1722 UsrOI.setUnknown(); 1723 Follow = true; 1724 return true; 1725 } 1726 1727 UsrOI.merge(PtrOI); 1728 Follow = true; 1729 return true; 1730 } 1731 1732 if (auto *LoadI = dyn_cast<LoadInst>(Usr)) { 1733 // If the access is to a pointer that may or may not be the associated 1734 // value, e.g. due to a PHI, we cannot assume it will be read. 1735 AccessKind AK = AccessKind::AK_R; 1736 if (getUnderlyingObject(CurPtr) == &AssociatedValue) 1737 AK = AccessKind(AK | AccessKind::AK_MUST); 1738 else 1739 AK = AccessKind(AK | AccessKind::AK_MAY); 1740 if (!handleAccess(A, *LoadI, /* Content */ nullptr, AK, 1741 OffsetInfoMap[CurPtr].Offsets, Changed, 1742 *LoadI->getType())) 1743 return false; 1744 1745 auto IsAssumption = [](Instruction &I) { 1746 if (auto *II = dyn_cast<IntrinsicInst>(&I)) 1747 return II->isAssumeLikeIntrinsic(); 1748 return false; 1749 }; 1750 1751 auto IsImpactedInRange = [&](Instruction *FromI, Instruction *ToI) { 1752 // Check if the assumption and the load are executed together without 1753 // memory modification. 1754 do { 1755 if (FromI->mayWriteToMemory() && !IsAssumption(*FromI)) 1756 return true; 1757 FromI = FromI->getNextNonDebugInstruction(); 1758 } while (FromI && FromI != ToI); 1759 return false; 1760 }; 1761 1762 BasicBlock *BB = LoadI->getParent(); 1763 auto IsValidAssume = [&](IntrinsicInst &IntrI) { 1764 if (IntrI.getIntrinsicID() != Intrinsic::assume) 1765 return false; 1766 BasicBlock *IntrBB = IntrI.getParent(); 1767 if (IntrI.getParent() == BB) { 1768 if (IsImpactedInRange(LoadI->getNextNonDebugInstruction(), &IntrI)) 1769 return false; 1770 } else { 1771 auto PredIt = pred_begin(IntrBB); 1772 if (PredIt == pred_end(IntrBB)) 1773 return false; 1774 if ((*PredIt) != BB) 1775 return false; 1776 if (++PredIt != pred_end(IntrBB)) 1777 return false; 1778 for (auto *SuccBB : successors(BB)) { 1779 if (SuccBB == IntrBB) 1780 continue; 1781 if (isa<UnreachableInst>(SuccBB->getTerminator())) 1782 continue; 1783 return false; 1784 } 1785 if (IsImpactedInRange(LoadI->getNextNonDebugInstruction(), 1786 BB->getTerminator())) 1787 return false; 1788 if (IsImpactedInRange(&IntrBB->front(), &IntrI)) 1789 return false; 1790 } 1791 return true; 1792 }; 1793 1794 std::pair<Value *, IntrinsicInst *> Assumption; 1795 for (const Use &LoadU : LoadI->uses()) { 1796 if (auto *CmpI = dyn_cast<CmpInst>(LoadU.getUser())) { 1797 if (!CmpI->isEquality() || !CmpI->isTrueWhenEqual()) 1798 continue; 1799 for (const Use &CmpU : CmpI->uses()) { 1800 if (auto *IntrI = dyn_cast<IntrinsicInst>(CmpU.getUser())) { 1801 if (!IsValidAssume(*IntrI)) 1802 continue; 1803 int Idx = CmpI->getOperandUse(0) == LoadU; 1804 Assumption = {CmpI->getOperand(Idx), IntrI}; 1805 break; 1806 } 1807 } 1808 } 1809 if (Assumption.first) 1810 break; 1811 } 1812 1813 // Check if we found an assumption associated with this load. 1814 if (!Assumption.first || !Assumption.second) 1815 return true; 1816 1817 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Assumption found " 1818 << *Assumption.second << ": " << *LoadI 1819 << " == " << *Assumption.first << "\n"); 1820 1821 return handleAccess( 1822 A, *Assumption.second, Assumption.first, AccessKind::AK_ASSUMPTION, 1823 OffsetInfoMap[CurPtr].Offsets, Changed, *LoadI->getType()); 1824 } 1825 1826 auto HandleStoreLike = [&](Instruction &I, Value *ValueOp, Type &ValueTy, 1827 ArrayRef<Value *> OtherOps, AccessKind AK) { 1828 for (auto *OtherOp : OtherOps) { 1829 if (OtherOp == CurPtr) { 1830 LLVM_DEBUG( 1831 dbgs() 1832 << "[AAPointerInfo] Escaping use in store like instruction " << I 1833 << "\n"); 1834 return false; 1835 } 1836 } 1837 1838 // If the access is to a pointer that may or may not be the associated 1839 // value, e.g. due to a PHI, we cannot assume it will be written. 1840 if (getUnderlyingObject(CurPtr) == &AssociatedValue) 1841 AK = AccessKind(AK | AccessKind::AK_MUST); 1842 else 1843 AK = AccessKind(AK | AccessKind::AK_MAY); 1844 bool UsedAssumedInformation = false; 1845 std::optional<Value *> Content = nullptr; 1846 if (ValueOp) 1847 Content = A.getAssumedSimplified( 1848 *ValueOp, *this, UsedAssumedInformation, AA::Interprocedural); 1849 return handleAccess(A, I, Content, AK, OffsetInfoMap[CurPtr].Offsets, 1850 Changed, ValueTy); 1851 }; 1852 1853 if (auto *StoreI = dyn_cast<StoreInst>(Usr)) 1854 return HandleStoreLike(*StoreI, StoreI->getValueOperand(), 1855 *StoreI->getValueOperand()->getType(), 1856 {StoreI->getValueOperand()}, AccessKind::AK_W); 1857 if (auto *RMWI = dyn_cast<AtomicRMWInst>(Usr)) 1858 return HandleStoreLike(*RMWI, nullptr, *RMWI->getValOperand()->getType(), 1859 {RMWI->getValOperand()}, AccessKind::AK_RW); 1860 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(Usr)) 1861 return HandleStoreLike( 1862 *CXI, nullptr, *CXI->getNewValOperand()->getType(), 1863 {CXI->getCompareOperand(), CXI->getNewValOperand()}, 1864 AccessKind::AK_RW); 1865 1866 if (auto *CB = dyn_cast<CallBase>(Usr)) { 1867 if (CB->isLifetimeStartOrEnd()) 1868 return true; 1869 if (getFreedOperand(CB, TLI) == U) 1870 return true; 1871 if (CB->isArgOperand(&U)) { 1872 unsigned ArgNo = CB->getArgOperandNo(&U); 1873 const auto *CSArgPI = A.getAAFor<AAPointerInfo>( 1874 *this, IRPosition::callsite_argument(*CB, ArgNo), 1875 DepClassTy::REQUIRED); 1876 if (!CSArgPI) 1877 return false; 1878 Changed = 1879 translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB) | 1880 Changed; 1881 return isValidState(); 1882 } 1883 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB 1884 << "\n"); 1885 // TODO: Allow some call uses 1886 return false; 1887 } 1888 1889 LLVM_DEBUG(dbgs() << "[AAPointerInfo] User not handled " << *Usr << "\n"); 1890 return false; 1891 }; 1892 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) { 1893 assert(OffsetInfoMap.count(OldU) && "Old use should be known already!"); 1894 if (OffsetInfoMap.count(NewU)) { 1895 LLVM_DEBUG({ 1896 if (!(OffsetInfoMap[NewU] == OffsetInfoMap[OldU])) { 1897 dbgs() << "[AAPointerInfo] Equivalent use callback failed: " 1898 << OffsetInfoMap[NewU] << " vs " << OffsetInfoMap[OldU] 1899 << "\n"; 1900 } 1901 }); 1902 return OffsetInfoMap[NewU] == OffsetInfoMap[OldU]; 1903 } 1904 OffsetInfoMap[NewU] = OffsetInfoMap[OldU]; 1905 return true; 1906 }; 1907 if (!A.checkForAllUses(UsePred, *this, AssociatedValue, 1908 /* CheckBBLivenessOnly */ true, DepClassTy::OPTIONAL, 1909 /* IgnoreDroppableUses */ true, EquivalentUseCB)) { 1910 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Check for all uses failed, abort!\n"); 1911 return indicatePessimisticFixpoint(); 1912 } 1913 1914 LLVM_DEBUG({ 1915 dbgs() << "Accesses by bin after update:\n"; 1916 dumpState(dbgs()); 1917 }); 1918 1919 return Changed; 1920 } 1921 1922 struct AAPointerInfoReturned final : AAPointerInfoImpl { 1923 AAPointerInfoReturned(const IRPosition &IRP, Attributor &A) 1924 : AAPointerInfoImpl(IRP, A) {} 1925 1926 /// See AbstractAttribute::updateImpl(...). 1927 ChangeStatus updateImpl(Attributor &A) override { 1928 return indicatePessimisticFixpoint(); 1929 } 1930 1931 /// See AbstractAttribute::trackStatistics() 1932 void trackStatistics() const override { 1933 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition()); 1934 } 1935 }; 1936 1937 struct AAPointerInfoArgument final : AAPointerInfoFloating { 1938 AAPointerInfoArgument(const IRPosition &IRP, Attributor &A) 1939 : AAPointerInfoFloating(IRP, A) {} 1940 1941 /// See AbstractAttribute::trackStatistics() 1942 void trackStatistics() const override { 1943 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition()); 1944 } 1945 }; 1946 1947 struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating { 1948 AAPointerInfoCallSiteArgument(const IRPosition &IRP, Attributor &A) 1949 : AAPointerInfoFloating(IRP, A) {} 1950 1951 /// See AbstractAttribute::updateImpl(...). 1952 ChangeStatus updateImpl(Attributor &A) override { 1953 using namespace AA::PointerInfo; 1954 // We handle memory intrinsics explicitly, at least the first (= 1955 // destination) and second (=source) arguments as we know how they are 1956 // accessed. 1957 if (auto *MI = dyn_cast_or_null<MemIntrinsic>(getCtxI())) { 1958 ConstantInt *Length = dyn_cast<ConstantInt>(MI->getLength()); 1959 int64_t LengthVal = AA::RangeTy::Unknown; 1960 if (Length) 1961 LengthVal = Length->getSExtValue(); 1962 unsigned ArgNo = getIRPosition().getCallSiteArgNo(); 1963 ChangeStatus Changed = ChangeStatus::UNCHANGED; 1964 if (ArgNo > 1) { 1965 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled memory intrinsic " 1966 << *MI << "\n"); 1967 return indicatePessimisticFixpoint(); 1968 } else { 1969 auto Kind = 1970 ArgNo == 0 ? AccessKind::AK_MUST_WRITE : AccessKind::AK_MUST_READ; 1971 Changed = 1972 Changed | addAccess(A, {0, LengthVal}, *MI, nullptr, Kind, nullptr); 1973 } 1974 LLVM_DEBUG({ 1975 dbgs() << "Accesses by bin after update:\n"; 1976 dumpState(dbgs()); 1977 }); 1978 1979 return Changed; 1980 } 1981 1982 // TODO: Once we have call site specific value information we can provide 1983 // call site specific liveness information and then it makes 1984 // sense to specialize attributes for call sites arguments instead of 1985 // redirecting requests to the callee argument. 1986 Argument *Arg = getAssociatedArgument(); 1987 if (Arg) { 1988 const IRPosition &ArgPos = IRPosition::argument(*Arg); 1989 auto *ArgAA = 1990 A.getAAFor<AAPointerInfo>(*this, ArgPos, DepClassTy::REQUIRED); 1991 if (ArgAA && ArgAA->getState().isValidState()) 1992 return translateAndAddStateFromCallee(A, *ArgAA, 1993 *cast<CallBase>(getCtxI())); 1994 if (!Arg->getParent()->isDeclaration()) 1995 return indicatePessimisticFixpoint(); 1996 } 1997 1998 bool IsKnownNoCapture; 1999 if (!AA::hasAssumedIRAttr<Attribute::NoCapture>( 2000 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoCapture)) 2001 return indicatePessimisticFixpoint(); 2002 2003 bool IsKnown = false; 2004 if (AA::isAssumedReadNone(A, getIRPosition(), *this, IsKnown)) 2005 return ChangeStatus::UNCHANGED; 2006 bool ReadOnly = AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown); 2007 auto Kind = 2008 ReadOnly ? AccessKind::AK_MAY_READ : AccessKind::AK_MAY_READ_WRITE; 2009 return addAccess(A, AA::RangeTy::getUnknown(), *getCtxI(), nullptr, Kind, 2010 nullptr); 2011 } 2012 2013 /// See AbstractAttribute::trackStatistics() 2014 void trackStatistics() const override { 2015 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition()); 2016 } 2017 }; 2018 2019 struct AAPointerInfoCallSiteReturned final : AAPointerInfoFloating { 2020 AAPointerInfoCallSiteReturned(const IRPosition &IRP, Attributor &A) 2021 : AAPointerInfoFloating(IRP, A) {} 2022 2023 /// See AbstractAttribute::trackStatistics() 2024 void trackStatistics() const override { 2025 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition()); 2026 } 2027 }; 2028 } // namespace 2029 2030 /// -----------------------NoUnwind Function Attribute-------------------------- 2031 2032 namespace { 2033 struct AANoUnwindImpl : AANoUnwind { 2034 AANoUnwindImpl(const IRPosition &IRP, Attributor &A) : AANoUnwind(IRP, A) {} 2035 2036 /// See AbstractAttribute::initialize(...). 2037 void initialize(Attributor &A) override { 2038 bool IsKnown; 2039 assert(!AA::hasAssumedIRAttr<Attribute::NoUnwind>( 2040 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown)); 2041 (void)IsKnown; 2042 } 2043 2044 const std::string getAsStr(Attributor *A) const override { 2045 return getAssumed() ? "nounwind" : "may-unwind"; 2046 } 2047 2048 /// See AbstractAttribute::updateImpl(...). 2049 ChangeStatus updateImpl(Attributor &A) override { 2050 auto Opcodes = { 2051 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr, 2052 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet, 2053 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume}; 2054 2055 auto CheckForNoUnwind = [&](Instruction &I) { 2056 if (!I.mayThrow(/* IncludePhaseOneUnwind */ true)) 2057 return true; 2058 2059 if (const auto *CB = dyn_cast<CallBase>(&I)) { 2060 bool IsKnownNoUnwind; 2061 return AA::hasAssumedIRAttr<Attribute::NoUnwind>( 2062 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED, 2063 IsKnownNoUnwind); 2064 } 2065 return false; 2066 }; 2067 2068 bool UsedAssumedInformation = false; 2069 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes, 2070 UsedAssumedInformation)) 2071 return indicatePessimisticFixpoint(); 2072 2073 return ChangeStatus::UNCHANGED; 2074 } 2075 }; 2076 2077 struct AANoUnwindFunction final : public AANoUnwindImpl { 2078 AANoUnwindFunction(const IRPosition &IRP, Attributor &A) 2079 : AANoUnwindImpl(IRP, A) {} 2080 2081 /// See AbstractAttribute::trackStatistics() 2082 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) } 2083 }; 2084 2085 /// NoUnwind attribute deduction for a call sites. 2086 struct AANoUnwindCallSite final : AANoUnwindImpl { 2087 AANoUnwindCallSite(const IRPosition &IRP, Attributor &A) 2088 : AANoUnwindImpl(IRP, A) {} 2089 2090 /// See AbstractAttribute::updateImpl(...). 2091 ChangeStatus updateImpl(Attributor &A) override { 2092 // TODO: Once we have call site specific value information we can provide 2093 // call site specific liveness information and then it makes 2094 // sense to specialize attributes for call sites arguments instead of 2095 // redirecting requests to the callee argument. 2096 Function *F = getAssociatedFunction(); 2097 const IRPosition &FnPos = IRPosition::function(*F); 2098 bool IsKnownNoUnwind; 2099 if (AA::hasAssumedIRAttr<Attribute::NoUnwind>( 2100 A, this, FnPos, DepClassTy::REQUIRED, IsKnownNoUnwind)) 2101 return ChangeStatus::UNCHANGED; 2102 return indicatePessimisticFixpoint(); 2103 } 2104 2105 /// See AbstractAttribute::trackStatistics() 2106 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); } 2107 }; 2108 } // namespace 2109 2110 /// ------------------------ NoSync Function Attribute ------------------------- 2111 2112 bool AANoSync::isAlignedBarrier(const CallBase &CB, bool ExecutedAligned) { 2113 switch (CB.getIntrinsicID()) { 2114 case Intrinsic::nvvm_barrier0: 2115 case Intrinsic::nvvm_barrier0_and: 2116 case Intrinsic::nvvm_barrier0_or: 2117 case Intrinsic::nvvm_barrier0_popc: 2118 return true; 2119 case Intrinsic::amdgcn_s_barrier: 2120 if (ExecutedAligned) 2121 return true; 2122 break; 2123 default: 2124 break; 2125 } 2126 return hasAssumption(CB, KnownAssumptionString("ompx_aligned_barrier")); 2127 } 2128 2129 bool AANoSync::isNonRelaxedAtomic(const Instruction *I) { 2130 if (!I->isAtomic()) 2131 return false; 2132 2133 if (auto *FI = dyn_cast<FenceInst>(I)) 2134 // All legal orderings for fence are stronger than monotonic. 2135 return FI->getSyncScopeID() != SyncScope::SingleThread; 2136 if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) { 2137 // Unordered is not a legal ordering for cmpxchg. 2138 return (AI->getSuccessOrdering() != AtomicOrdering::Monotonic || 2139 AI->getFailureOrdering() != AtomicOrdering::Monotonic); 2140 } 2141 2142 AtomicOrdering Ordering; 2143 switch (I->getOpcode()) { 2144 case Instruction::AtomicRMW: 2145 Ordering = cast<AtomicRMWInst>(I)->getOrdering(); 2146 break; 2147 case Instruction::Store: 2148 Ordering = cast<StoreInst>(I)->getOrdering(); 2149 break; 2150 case Instruction::Load: 2151 Ordering = cast<LoadInst>(I)->getOrdering(); 2152 break; 2153 default: 2154 llvm_unreachable( 2155 "New atomic operations need to be known in the attributor."); 2156 } 2157 2158 return (Ordering != AtomicOrdering::Unordered && 2159 Ordering != AtomicOrdering::Monotonic); 2160 } 2161 2162 /// Return true if this intrinsic is nosync. This is only used for intrinsics 2163 /// which would be nosync except that they have a volatile flag. All other 2164 /// intrinsics are simply annotated with the nosync attribute in Intrinsics.td. 2165 bool AANoSync::isNoSyncIntrinsic(const Instruction *I) { 2166 if (auto *MI = dyn_cast<MemIntrinsic>(I)) 2167 return !MI->isVolatile(); 2168 return false; 2169 } 2170 2171 namespace { 2172 struct AANoSyncImpl : AANoSync { 2173 AANoSyncImpl(const IRPosition &IRP, Attributor &A) : AANoSync(IRP, A) {} 2174 2175 /// See AbstractAttribute::initialize(...). 2176 void initialize(Attributor &A) override { 2177 bool IsKnown; 2178 assert(!AA::hasAssumedIRAttr<Attribute::NoSync>(A, nullptr, getIRPosition(), 2179 DepClassTy::NONE, IsKnown)); 2180 (void)IsKnown; 2181 } 2182 2183 const std::string getAsStr(Attributor *A) const override { 2184 return getAssumed() ? "nosync" : "may-sync"; 2185 } 2186 2187 /// See AbstractAttribute::updateImpl(...). 2188 ChangeStatus updateImpl(Attributor &A) override; 2189 }; 2190 2191 ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) { 2192 2193 auto CheckRWInstForNoSync = [&](Instruction &I) { 2194 return AA::isNoSyncInst(A, I, *this); 2195 }; 2196 2197 auto CheckForNoSync = [&](Instruction &I) { 2198 // At this point we handled all read/write effects and they are all 2199 // nosync, so they can be skipped. 2200 if (I.mayReadOrWriteMemory()) 2201 return true; 2202 2203 // non-convergent and readnone imply nosync. 2204 return !cast<CallBase>(I).isConvergent(); 2205 }; 2206 2207 bool UsedAssumedInformation = false; 2208 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this, 2209 UsedAssumedInformation) || 2210 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this, 2211 UsedAssumedInformation)) 2212 return indicatePessimisticFixpoint(); 2213 2214 return ChangeStatus::UNCHANGED; 2215 } 2216 2217 struct AANoSyncFunction final : public AANoSyncImpl { 2218 AANoSyncFunction(const IRPosition &IRP, Attributor &A) 2219 : AANoSyncImpl(IRP, A) {} 2220 2221 /// See AbstractAttribute::trackStatistics() 2222 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) } 2223 }; 2224 2225 /// NoSync attribute deduction for a call sites. 2226 struct AANoSyncCallSite final : AANoSyncImpl { 2227 AANoSyncCallSite(const IRPosition &IRP, Attributor &A) 2228 : AANoSyncImpl(IRP, A) {} 2229 2230 /// See AbstractAttribute::updateImpl(...). 2231 ChangeStatus updateImpl(Attributor &A) override { 2232 // TODO: Once we have call site specific value information we can provide 2233 // call site specific liveness information and then it makes 2234 // sense to specialize attributes for call sites arguments instead of 2235 // redirecting requests to the callee argument. 2236 Function *F = getAssociatedFunction(); 2237 const IRPosition &FnPos = IRPosition::function(*F); 2238 bool IsKnownNoSycn; 2239 if (AA::hasAssumedIRAttr<Attribute::NoSync>( 2240 A, this, FnPos, DepClassTy::REQUIRED, IsKnownNoSycn)) 2241 return ChangeStatus::UNCHANGED; 2242 return indicatePessimisticFixpoint(); 2243 } 2244 2245 /// See AbstractAttribute::trackStatistics() 2246 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); } 2247 }; 2248 } // namespace 2249 2250 /// ------------------------ No-Free Attributes ---------------------------- 2251 2252 namespace { 2253 struct AANoFreeImpl : public AANoFree { 2254 AANoFreeImpl(const IRPosition &IRP, Attributor &A) : AANoFree(IRP, A) {} 2255 2256 /// See AbstractAttribute::initialize(...). 2257 void initialize(Attributor &A) override { 2258 bool IsKnown; 2259 assert(!AA::hasAssumedIRAttr<Attribute::NoFree>(A, nullptr, getIRPosition(), 2260 DepClassTy::NONE, IsKnown)); 2261 (void)IsKnown; 2262 } 2263 2264 /// See AbstractAttribute::updateImpl(...). 2265 ChangeStatus updateImpl(Attributor &A) override { 2266 auto CheckForNoFree = [&](Instruction &I) { 2267 bool IsKnown; 2268 return AA::hasAssumedIRAttr<Attribute::NoFree>( 2269 A, this, IRPosition::callsite_function(cast<CallBase>(I)), 2270 DepClassTy::REQUIRED, IsKnown); 2271 }; 2272 2273 bool UsedAssumedInformation = false; 2274 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this, 2275 UsedAssumedInformation)) 2276 return indicatePessimisticFixpoint(); 2277 return ChangeStatus::UNCHANGED; 2278 } 2279 2280 /// See AbstractAttribute::getAsStr(). 2281 const std::string getAsStr(Attributor *A) const override { 2282 return getAssumed() ? "nofree" : "may-free"; 2283 } 2284 }; 2285 2286 struct AANoFreeFunction final : public AANoFreeImpl { 2287 AANoFreeFunction(const IRPosition &IRP, Attributor &A) 2288 : AANoFreeImpl(IRP, A) {} 2289 2290 /// See AbstractAttribute::trackStatistics() 2291 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) } 2292 }; 2293 2294 /// NoFree attribute deduction for a call sites. 2295 struct AANoFreeCallSite final : AANoFreeImpl { 2296 AANoFreeCallSite(const IRPosition &IRP, Attributor &A) 2297 : AANoFreeImpl(IRP, A) {} 2298 2299 /// See AbstractAttribute::updateImpl(...). 2300 ChangeStatus updateImpl(Attributor &A) override { 2301 // TODO: Once we have call site specific value information we can provide 2302 // call site specific liveness information and then it makes 2303 // sense to specialize attributes for call sites arguments instead of 2304 // redirecting requests to the callee argument. 2305 Function *F = getAssociatedFunction(); 2306 const IRPosition &FnPos = IRPosition::function(*F); 2307 bool IsKnown; 2308 if (AA::hasAssumedIRAttr<Attribute::NoFree>(A, this, FnPos, 2309 DepClassTy::REQUIRED, IsKnown)) 2310 return ChangeStatus::UNCHANGED; 2311 return indicatePessimisticFixpoint(); 2312 } 2313 2314 /// See AbstractAttribute::trackStatistics() 2315 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); } 2316 }; 2317 2318 /// NoFree attribute for floating values. 2319 struct AANoFreeFloating : AANoFreeImpl { 2320 AANoFreeFloating(const IRPosition &IRP, Attributor &A) 2321 : AANoFreeImpl(IRP, A) {} 2322 2323 /// See AbstractAttribute::trackStatistics() 2324 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)} 2325 2326 /// See Abstract Attribute::updateImpl(...). 2327 ChangeStatus updateImpl(Attributor &A) override { 2328 const IRPosition &IRP = getIRPosition(); 2329 2330 bool IsKnown; 2331 if (AA::hasAssumedIRAttr<Attribute::NoFree>(A, this, 2332 IRPosition::function_scope(IRP), 2333 DepClassTy::OPTIONAL, IsKnown)) 2334 return ChangeStatus::UNCHANGED; 2335 2336 Value &AssociatedValue = getIRPosition().getAssociatedValue(); 2337 auto Pred = [&](const Use &U, bool &Follow) -> bool { 2338 Instruction *UserI = cast<Instruction>(U.getUser()); 2339 if (auto *CB = dyn_cast<CallBase>(UserI)) { 2340 if (CB->isBundleOperand(&U)) 2341 return false; 2342 if (!CB->isArgOperand(&U)) 2343 return true; 2344 unsigned ArgNo = CB->getArgOperandNo(&U); 2345 2346 bool IsKnown; 2347 return AA::hasAssumedIRAttr<Attribute::NoFree>( 2348 A, this, IRPosition::callsite_argument(*CB, ArgNo), 2349 DepClassTy::REQUIRED, IsKnown); 2350 } 2351 2352 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) || 2353 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) { 2354 Follow = true; 2355 return true; 2356 } 2357 if (isa<StoreInst>(UserI) || isa<LoadInst>(UserI) || 2358 isa<ReturnInst>(UserI)) 2359 return true; 2360 2361 // Unknown user. 2362 return false; 2363 }; 2364 if (!A.checkForAllUses(Pred, *this, AssociatedValue)) 2365 return indicatePessimisticFixpoint(); 2366 2367 return ChangeStatus::UNCHANGED; 2368 } 2369 }; 2370 2371 /// NoFree attribute for a call site argument. 2372 struct AANoFreeArgument final : AANoFreeFloating { 2373 AANoFreeArgument(const IRPosition &IRP, Attributor &A) 2374 : AANoFreeFloating(IRP, A) {} 2375 2376 /// See AbstractAttribute::trackStatistics() 2377 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) } 2378 }; 2379 2380 /// NoFree attribute for call site arguments. 2381 struct AANoFreeCallSiteArgument final : AANoFreeFloating { 2382 AANoFreeCallSiteArgument(const IRPosition &IRP, Attributor &A) 2383 : AANoFreeFloating(IRP, A) {} 2384 2385 /// See AbstractAttribute::updateImpl(...). 2386 ChangeStatus updateImpl(Attributor &A) override { 2387 // TODO: Once we have call site specific value information we can provide 2388 // call site specific liveness information and then it makes 2389 // sense to specialize attributes for call sites arguments instead of 2390 // redirecting requests to the callee argument. 2391 Argument *Arg = getAssociatedArgument(); 2392 if (!Arg) 2393 return indicatePessimisticFixpoint(); 2394 const IRPosition &ArgPos = IRPosition::argument(*Arg); 2395 bool IsKnown; 2396 if (AA::hasAssumedIRAttr<Attribute::NoFree>(A, this, ArgPos, 2397 DepClassTy::REQUIRED, IsKnown)) 2398 return ChangeStatus::UNCHANGED; 2399 return indicatePessimisticFixpoint(); 2400 } 2401 2402 /// See AbstractAttribute::trackStatistics() 2403 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nofree)}; 2404 }; 2405 2406 /// NoFree attribute for function return value. 2407 struct AANoFreeReturned final : AANoFreeFloating { 2408 AANoFreeReturned(const IRPosition &IRP, Attributor &A) 2409 : AANoFreeFloating(IRP, A) { 2410 llvm_unreachable("NoFree is not applicable to function returns!"); 2411 } 2412 2413 /// See AbstractAttribute::initialize(...). 2414 void initialize(Attributor &A) override { 2415 llvm_unreachable("NoFree is not applicable to function returns!"); 2416 } 2417 2418 /// See AbstractAttribute::updateImpl(...). 2419 ChangeStatus updateImpl(Attributor &A) override { 2420 llvm_unreachable("NoFree is not applicable to function returns!"); 2421 } 2422 2423 /// See AbstractAttribute::trackStatistics() 2424 void trackStatistics() const override {} 2425 }; 2426 2427 /// NoFree attribute deduction for a call site return value. 2428 struct AANoFreeCallSiteReturned final : AANoFreeFloating { 2429 AANoFreeCallSiteReturned(const IRPosition &IRP, Attributor &A) 2430 : AANoFreeFloating(IRP, A) {} 2431 2432 ChangeStatus manifest(Attributor &A) override { 2433 return ChangeStatus::UNCHANGED; 2434 } 2435 /// See AbstractAttribute::trackStatistics() 2436 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) } 2437 }; 2438 } // namespace 2439 2440 /// ------------------------ NonNull Argument Attribute ------------------------ 2441 2442 bool AANonNull::isImpliedByIR(Attributor &A, const IRPosition &IRP, 2443 Attribute::AttrKind ImpliedAttributeKind, 2444 bool IgnoreSubsumingPositions) { 2445 SmallVector<Attribute::AttrKind, 2> AttrKinds; 2446 AttrKinds.push_back(Attribute::NonNull); 2447 if (!NullPointerIsDefined(IRP.getAnchorScope(), 2448 IRP.getAssociatedType()->getPointerAddressSpace())) 2449 AttrKinds.push_back(Attribute::Dereferenceable); 2450 if (A.hasAttr(IRP, AttrKinds, IgnoreSubsumingPositions, Attribute::NonNull)) 2451 return true; 2452 2453 if (IRP.getPositionKind() == IRP_RETURNED) 2454 return false; 2455 2456 DominatorTree *DT = nullptr; 2457 AssumptionCache *AC = nullptr; 2458 InformationCache &InfoCache = A.getInfoCache(); 2459 if (const Function *Fn = IRP.getAnchorScope()) { 2460 if (!Fn->isDeclaration()) { 2461 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*Fn); 2462 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*Fn); 2463 } 2464 } 2465 2466 if (!isKnownNonZero(&IRP.getAssociatedValue(), A.getDataLayout(), 0, AC, 2467 IRP.getCtxI(), DT)) 2468 return false; 2469 A.manifestAttrs(IRP, {Attribute::get(IRP.getAnchorValue().getContext(), 2470 Attribute::NonNull)}); 2471 return true; 2472 } 2473 2474 namespace { 2475 static int64_t getKnownNonNullAndDerefBytesForUse( 2476 Attributor &A, const AbstractAttribute &QueryingAA, Value &AssociatedValue, 2477 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) { 2478 TrackUse = false; 2479 2480 const Value *UseV = U->get(); 2481 if (!UseV->getType()->isPointerTy()) 2482 return 0; 2483 2484 // We need to follow common pointer manipulation uses to the accesses they 2485 // feed into. We can try to be smart to avoid looking through things we do not 2486 // like for now, e.g., non-inbounds GEPs. 2487 if (isa<CastInst>(I)) { 2488 TrackUse = true; 2489 return 0; 2490 } 2491 2492 if (isa<GetElementPtrInst>(I)) { 2493 TrackUse = true; 2494 return 0; 2495 } 2496 2497 Type *PtrTy = UseV->getType(); 2498 const Function *F = I->getFunction(); 2499 bool NullPointerIsDefined = 2500 F ? llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace()) : true; 2501 const DataLayout &DL = A.getInfoCache().getDL(); 2502 if (const auto *CB = dyn_cast<CallBase>(I)) { 2503 if (CB->isBundleOperand(U)) { 2504 if (RetainedKnowledge RK = getKnowledgeFromUse( 2505 U, {Attribute::NonNull, Attribute::Dereferenceable})) { 2506 IsNonNull |= 2507 (RK.AttrKind == Attribute::NonNull || !NullPointerIsDefined); 2508 return RK.ArgValue; 2509 } 2510 return 0; 2511 } 2512 2513 if (CB->isCallee(U)) { 2514 IsNonNull |= !NullPointerIsDefined; 2515 return 0; 2516 } 2517 2518 unsigned ArgNo = CB->getArgOperandNo(U); 2519 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo); 2520 // As long as we only use known information there is no need to track 2521 // dependences here. 2522 bool IsKnownNonNull; 2523 AA::hasAssumedIRAttr<Attribute::NonNull>(A, &QueryingAA, IRP, 2524 DepClassTy::NONE, IsKnownNonNull); 2525 IsNonNull |= IsKnownNonNull; 2526 auto *DerefAA = 2527 A.getAAFor<AADereferenceable>(QueryingAA, IRP, DepClassTy::NONE); 2528 return DerefAA ? DerefAA->getKnownDereferenceableBytes() : 0; 2529 } 2530 2531 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I); 2532 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile()) 2533 return 0; 2534 2535 int64_t Offset; 2536 const Value *Base = 2537 getMinimalBaseOfPointer(A, QueryingAA, Loc->Ptr, Offset, DL); 2538 if (Base && Base == &AssociatedValue) { 2539 int64_t DerefBytes = Loc->Size.getValue() + Offset; 2540 IsNonNull |= !NullPointerIsDefined; 2541 return std::max(int64_t(0), DerefBytes); 2542 } 2543 2544 /// Corner case when an offset is 0. 2545 Base = GetPointerBaseWithConstantOffset(Loc->Ptr, Offset, DL, 2546 /*AllowNonInbounds*/ true); 2547 if (Base && Base == &AssociatedValue && Offset == 0) { 2548 int64_t DerefBytes = Loc->Size.getValue(); 2549 IsNonNull |= !NullPointerIsDefined; 2550 return std::max(int64_t(0), DerefBytes); 2551 } 2552 2553 return 0; 2554 } 2555 2556 struct AANonNullImpl : AANonNull { 2557 AANonNullImpl(const IRPosition &IRP, Attributor &A) : AANonNull(IRP, A) {} 2558 2559 /// See AbstractAttribute::initialize(...). 2560 void initialize(Attributor &A) override { 2561 Value &V = *getAssociatedValue().stripPointerCasts(); 2562 if (isa<ConstantPointerNull>(V)) { 2563 indicatePessimisticFixpoint(); 2564 return; 2565 } 2566 2567 if (Instruction *CtxI = getCtxI()) 2568 followUsesInMBEC(*this, A, getState(), *CtxI); 2569 } 2570 2571 /// See followUsesInMBEC 2572 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I, 2573 AANonNull::StateType &State) { 2574 bool IsNonNull = false; 2575 bool TrackUse = false; 2576 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I, 2577 IsNonNull, TrackUse); 2578 State.setKnown(IsNonNull); 2579 return TrackUse; 2580 } 2581 2582 /// See AbstractAttribute::getAsStr(). 2583 const std::string getAsStr(Attributor *A) const override { 2584 return getAssumed() ? "nonnull" : "may-null"; 2585 } 2586 }; 2587 2588 /// NonNull attribute for a floating value. 2589 struct AANonNullFloating : public AANonNullImpl { 2590 AANonNullFloating(const IRPosition &IRP, Attributor &A) 2591 : AANonNullImpl(IRP, A) {} 2592 2593 /// See AbstractAttribute::updateImpl(...). 2594 ChangeStatus updateImpl(Attributor &A) override { 2595 auto CheckIRP = [&](const IRPosition &IRP) { 2596 bool IsKnownNonNull; 2597 return AA::hasAssumedIRAttr<Attribute::NonNull>( 2598 A, *this, IRP, DepClassTy::OPTIONAL, IsKnownNonNull); 2599 }; 2600 2601 bool Stripped; 2602 bool UsedAssumedInformation = false; 2603 Value *AssociatedValue = &getAssociatedValue(); 2604 SmallVector<AA::ValueAndContext> Values; 2605 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values, 2606 AA::AnyScope, UsedAssumedInformation)) 2607 Stripped = false; 2608 else 2609 Stripped = 2610 Values.size() != 1 || Values.front().getValue() != AssociatedValue; 2611 2612 if (!Stripped) { 2613 // If we haven't stripped anything we might still be able to use a 2614 // different AA, but only if the IRP changes. Effectively when we 2615 // interpret this not as a call site value but as a floating/argument 2616 // value. 2617 const IRPosition AVIRP = IRPosition::value(*AssociatedValue); 2618 if (AVIRP == getIRPosition() || !CheckIRP(AVIRP)) 2619 return indicatePessimisticFixpoint(); 2620 return ChangeStatus::UNCHANGED; 2621 } 2622 2623 for (const auto &VAC : Values) 2624 if (!CheckIRP(IRPosition::value(*VAC.getValue()))) 2625 return indicatePessimisticFixpoint(); 2626 2627 return ChangeStatus::UNCHANGED; 2628 } 2629 2630 /// See AbstractAttribute::trackStatistics() 2631 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) } 2632 }; 2633 2634 /// NonNull attribute for function return value. 2635 struct AANonNullReturned final 2636 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType, 2637 false, AANonNull::IRAttributeKind> { 2638 AANonNullReturned(const IRPosition &IRP, Attributor &A) 2639 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType, 2640 false, Attribute::NonNull>(IRP, A) {} 2641 2642 /// See AbstractAttribute::getAsStr(). 2643 const std::string getAsStr(Attributor *A) const override { 2644 return getAssumed() ? "nonnull" : "may-null"; 2645 } 2646 2647 /// See AbstractAttribute::trackStatistics() 2648 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) } 2649 }; 2650 2651 /// NonNull attribute for function argument. 2652 struct AANonNullArgument final 2653 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl, 2654 AANonNull::StateType, false, 2655 AANonNull::IRAttributeKind> { 2656 AANonNullArgument(const IRPosition &IRP, Attributor &A) 2657 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl, 2658 AANonNull::StateType, false, 2659 AANonNull::IRAttributeKind>(IRP, A) {} 2660 2661 /// See AbstractAttribute::trackStatistics() 2662 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) } 2663 }; 2664 2665 struct AANonNullCallSiteArgument final : AANonNullFloating { 2666 AANonNullCallSiteArgument(const IRPosition &IRP, Attributor &A) 2667 : AANonNullFloating(IRP, A) {} 2668 2669 /// See AbstractAttribute::trackStatistics() 2670 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) } 2671 }; 2672 2673 /// NonNull attribute for a call site return position. 2674 struct AANonNullCallSiteReturned final 2675 : AACallSiteReturnedFromReturned<AANonNull, AANonNullImpl, 2676 AANonNull::StateType, false, 2677 AANonNull::IRAttributeKind> { 2678 AANonNullCallSiteReturned(const IRPosition &IRP, Attributor &A) 2679 : AACallSiteReturnedFromReturned<AANonNull, AANonNullImpl, 2680 AANonNull::StateType, false, 2681 AANonNull::IRAttributeKind>(IRP, A) {} 2682 2683 /// See AbstractAttribute::trackStatistics() 2684 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) } 2685 }; 2686 } // namespace 2687 2688 /// ------------------------ Must-Progress Attributes -------------------------- 2689 namespace { 2690 struct AAMustProgressImpl : public AAMustProgress { 2691 AAMustProgressImpl(const IRPosition &IRP, Attributor &A) 2692 : AAMustProgress(IRP, A) {} 2693 2694 /// See AbstractAttribute::initialize(...). 2695 void initialize(Attributor &A) override { 2696 bool IsKnown; 2697 assert(!AA::hasAssumedIRAttr<Attribute::MustProgress>( 2698 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown)); 2699 (void)IsKnown; 2700 } 2701 2702 /// See AbstractAttribute::getAsStr() 2703 const std::string getAsStr(Attributor *A) const override { 2704 return getAssumed() ? "mustprogress" : "may-not-progress"; 2705 } 2706 }; 2707 2708 struct AAMustProgressFunction final : AAMustProgressImpl { 2709 AAMustProgressFunction(const IRPosition &IRP, Attributor &A) 2710 : AAMustProgressImpl(IRP, A) {} 2711 2712 /// See AbstractAttribute::updateImpl(...). 2713 ChangeStatus updateImpl(Attributor &A) override { 2714 bool IsKnown; 2715 if (AA::hasAssumedIRAttr<Attribute::WillReturn>( 2716 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnown)) { 2717 if (IsKnown) 2718 return indicateOptimisticFixpoint(); 2719 return ChangeStatus::UNCHANGED; 2720 } 2721 2722 auto CheckForMustProgress = [&](AbstractCallSite ACS) { 2723 IRPosition IPos = IRPosition::callsite_function(*ACS.getInstruction()); 2724 bool IsKnownMustProgress; 2725 return AA::hasAssumedIRAttr<Attribute::MustProgress>( 2726 A, this, IPos, DepClassTy::REQUIRED, IsKnownMustProgress, 2727 /* IgnoreSubsumingPositions */ true); 2728 }; 2729 2730 bool AllCallSitesKnown = true; 2731 if (!A.checkForAllCallSites(CheckForMustProgress, *this, 2732 /* RequireAllCallSites */ true, 2733 AllCallSitesKnown)) 2734 return indicatePessimisticFixpoint(); 2735 2736 return ChangeStatus::UNCHANGED; 2737 } 2738 2739 /// See AbstractAttribute::trackStatistics() 2740 void trackStatistics() const override { 2741 STATS_DECLTRACK_FN_ATTR(mustprogress) 2742 } 2743 }; 2744 2745 /// MustProgress attribute deduction for a call sites. 2746 struct AAMustProgressCallSite final : AAMustProgressImpl { 2747 AAMustProgressCallSite(const IRPosition &IRP, Attributor &A) 2748 : AAMustProgressImpl(IRP, A) {} 2749 2750 /// See AbstractAttribute::updateImpl(...). 2751 ChangeStatus updateImpl(Attributor &A) override { 2752 // TODO: Once we have call site specific value information we can provide 2753 // call site specific liveness information and then it makes 2754 // sense to specialize attributes for call sites arguments instead of 2755 // redirecting requests to the callee argument. 2756 const IRPosition &FnPos = IRPosition::function(*getAnchorScope()); 2757 bool IsKnownMustProgress; 2758 if (!AA::hasAssumedIRAttr<Attribute::MustProgress>( 2759 A, this, FnPos, DepClassTy::REQUIRED, IsKnownMustProgress)) 2760 return indicatePessimisticFixpoint(); 2761 return ChangeStatus::UNCHANGED; 2762 } 2763 2764 /// See AbstractAttribute::trackStatistics() 2765 void trackStatistics() const override { 2766 STATS_DECLTRACK_CS_ATTR(mustprogress); 2767 } 2768 }; 2769 } // namespace 2770 2771 /// ------------------------ No-Recurse Attributes ---------------------------- 2772 2773 namespace { 2774 struct AANoRecurseImpl : public AANoRecurse { 2775 AANoRecurseImpl(const IRPosition &IRP, Attributor &A) : AANoRecurse(IRP, A) {} 2776 2777 /// See AbstractAttribute::initialize(...). 2778 void initialize(Attributor &A) override { 2779 bool IsKnown; 2780 assert(!AA::hasAssumedIRAttr<Attribute::NoRecurse>( 2781 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown)); 2782 (void)IsKnown; 2783 } 2784 2785 /// See AbstractAttribute::getAsStr() 2786 const std::string getAsStr(Attributor *A) const override { 2787 return getAssumed() ? "norecurse" : "may-recurse"; 2788 } 2789 }; 2790 2791 struct AANoRecurseFunction final : AANoRecurseImpl { 2792 AANoRecurseFunction(const IRPosition &IRP, Attributor &A) 2793 : AANoRecurseImpl(IRP, A) {} 2794 2795 /// See AbstractAttribute::updateImpl(...). 2796 ChangeStatus updateImpl(Attributor &A) override { 2797 2798 // If all live call sites are known to be no-recurse, we are as well. 2799 auto CallSitePred = [&](AbstractCallSite ACS) { 2800 bool IsKnownNoRecurse; 2801 if (!AA::hasAssumedIRAttr<Attribute::NoRecurse>( 2802 A, this, 2803 IRPosition::function(*ACS.getInstruction()->getFunction()), 2804 DepClassTy::NONE, IsKnownNoRecurse)) 2805 return false; 2806 return IsKnownNoRecurse; 2807 }; 2808 bool UsedAssumedInformation = false; 2809 if (A.checkForAllCallSites(CallSitePred, *this, true, 2810 UsedAssumedInformation)) { 2811 // If we know all call sites and all are known no-recurse, we are done. 2812 // If all known call sites, which might not be all that exist, are known 2813 // to be no-recurse, we are not done but we can continue to assume 2814 // no-recurse. If one of the call sites we have not visited will become 2815 // live, another update is triggered. 2816 if (!UsedAssumedInformation) 2817 indicateOptimisticFixpoint(); 2818 return ChangeStatus::UNCHANGED; 2819 } 2820 2821 const AAInterFnReachability *EdgeReachability = 2822 A.getAAFor<AAInterFnReachability>(*this, getIRPosition(), 2823 DepClassTy::REQUIRED); 2824 if (EdgeReachability && EdgeReachability->canReach(A, *getAnchorScope())) 2825 return indicatePessimisticFixpoint(); 2826 return ChangeStatus::UNCHANGED; 2827 } 2828 2829 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) } 2830 }; 2831 2832 /// NoRecurse attribute deduction for a call sites. 2833 struct AANoRecurseCallSite final : AANoRecurseImpl { 2834 AANoRecurseCallSite(const IRPosition &IRP, Attributor &A) 2835 : AANoRecurseImpl(IRP, A) {} 2836 2837 /// See AbstractAttribute::updateImpl(...). 2838 ChangeStatus updateImpl(Attributor &A) override { 2839 // TODO: Once we have call site specific value information we can provide 2840 // call site specific liveness information and then it makes 2841 // sense to specialize attributes for call sites arguments instead of 2842 // redirecting requests to the callee argument. 2843 Function *F = getAssociatedFunction(); 2844 const IRPosition &FnPos = IRPosition::function(*F); 2845 bool IsKnownNoRecurse; 2846 if (!AA::hasAssumedIRAttr<Attribute::NoRecurse>( 2847 A, this, FnPos, DepClassTy::REQUIRED, IsKnownNoRecurse)) 2848 return indicatePessimisticFixpoint(); 2849 return ChangeStatus::UNCHANGED; 2850 } 2851 2852 /// See AbstractAttribute::trackStatistics() 2853 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); } 2854 }; 2855 } // namespace 2856 2857 /// ------------------------ No-Convergent Attribute -------------------------- 2858 2859 namespace { 2860 struct AANonConvergentImpl : public AANonConvergent { 2861 AANonConvergentImpl(const IRPosition &IRP, Attributor &A) 2862 : AANonConvergent(IRP, A) {} 2863 2864 /// See AbstractAttribute::getAsStr() 2865 const std::string getAsStr(Attributor *A) const override { 2866 return getAssumed() ? "non-convergent" : "may-be-convergent"; 2867 } 2868 }; 2869 2870 struct AANonConvergentFunction final : AANonConvergentImpl { 2871 AANonConvergentFunction(const IRPosition &IRP, Attributor &A) 2872 : AANonConvergentImpl(IRP, A) {} 2873 2874 /// See AbstractAttribute::updateImpl(...). 2875 ChangeStatus updateImpl(Attributor &A) override { 2876 // If all function calls are known to not be convergent, we are not 2877 // convergent. 2878 auto CalleeIsNotConvergent = [&](Instruction &Inst) { 2879 CallBase &CB = cast<CallBase>(Inst); 2880 auto *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand()); 2881 if (!Callee || Callee->isIntrinsic()) { 2882 return false; 2883 } 2884 if (Callee->isDeclaration()) { 2885 return !Callee->hasFnAttribute(Attribute::Convergent); 2886 } 2887 const auto *ConvergentAA = A.getAAFor<AANonConvergent>( 2888 *this, IRPosition::function(*Callee), DepClassTy::REQUIRED); 2889 return ConvergentAA && ConvergentAA->isAssumedNotConvergent(); 2890 }; 2891 2892 bool UsedAssumedInformation = false; 2893 if (!A.checkForAllCallLikeInstructions(CalleeIsNotConvergent, *this, 2894 UsedAssumedInformation)) { 2895 return indicatePessimisticFixpoint(); 2896 } 2897 return ChangeStatus::UNCHANGED; 2898 } 2899 2900 ChangeStatus manifest(Attributor &A) override { 2901 if (isKnownNotConvergent() && 2902 A.hasAttr(getIRPosition(), Attribute::Convergent)) { 2903 A.removeAttrs(getIRPosition(), {Attribute::Convergent}); 2904 return ChangeStatus::CHANGED; 2905 } 2906 return ChangeStatus::UNCHANGED; 2907 } 2908 2909 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(convergent) } 2910 }; 2911 } // namespace 2912 2913 /// -------------------- Undefined-Behavior Attributes ------------------------ 2914 2915 namespace { 2916 struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { 2917 AAUndefinedBehaviorImpl(const IRPosition &IRP, Attributor &A) 2918 : AAUndefinedBehavior(IRP, A) {} 2919 2920 /// See AbstractAttribute::updateImpl(...). 2921 // through a pointer (i.e. also branches etc.) 2922 ChangeStatus updateImpl(Attributor &A) override { 2923 const size_t UBPrevSize = KnownUBInsts.size(); 2924 const size_t NoUBPrevSize = AssumedNoUBInsts.size(); 2925 2926 auto InspectMemAccessInstForUB = [&](Instruction &I) { 2927 // Lang ref now states volatile store is not UB, let's skip them. 2928 if (I.isVolatile() && I.mayWriteToMemory()) 2929 return true; 2930 2931 // Skip instructions that are already saved. 2932 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I)) 2933 return true; 2934 2935 // If we reach here, we know we have an instruction 2936 // that accesses memory through a pointer operand, 2937 // for which getPointerOperand() should give it to us. 2938 Value *PtrOp = 2939 const_cast<Value *>(getPointerOperand(&I, /* AllowVolatile */ true)); 2940 assert(PtrOp && 2941 "Expected pointer operand of memory accessing instruction"); 2942 2943 // Either we stopped and the appropriate action was taken, 2944 // or we got back a simplified value to continue. 2945 std::optional<Value *> SimplifiedPtrOp = 2946 stopOnUndefOrAssumed(A, PtrOp, &I); 2947 if (!SimplifiedPtrOp || !*SimplifiedPtrOp) 2948 return true; 2949 const Value *PtrOpVal = *SimplifiedPtrOp; 2950 2951 // A memory access through a pointer is considered UB 2952 // only if the pointer has constant null value. 2953 // TODO: Expand it to not only check constant values. 2954 if (!isa<ConstantPointerNull>(PtrOpVal)) { 2955 AssumedNoUBInsts.insert(&I); 2956 return true; 2957 } 2958 const Type *PtrTy = PtrOpVal->getType(); 2959 2960 // Because we only consider instructions inside functions, 2961 // assume that a parent function exists. 2962 const Function *F = I.getFunction(); 2963 2964 // A memory access using constant null pointer is only considered UB 2965 // if null pointer is _not_ defined for the target platform. 2966 if (llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace())) 2967 AssumedNoUBInsts.insert(&I); 2968 else 2969 KnownUBInsts.insert(&I); 2970 return true; 2971 }; 2972 2973 auto InspectBrInstForUB = [&](Instruction &I) { 2974 // A conditional branch instruction is considered UB if it has `undef` 2975 // condition. 2976 2977 // Skip instructions that are already saved. 2978 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I)) 2979 return true; 2980 2981 // We know we have a branch instruction. 2982 auto *BrInst = cast<BranchInst>(&I); 2983 2984 // Unconditional branches are never considered UB. 2985 if (BrInst->isUnconditional()) 2986 return true; 2987 2988 // Either we stopped and the appropriate action was taken, 2989 // or we got back a simplified value to continue. 2990 std::optional<Value *> SimplifiedCond = 2991 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst); 2992 if (!SimplifiedCond || !*SimplifiedCond) 2993 return true; 2994 AssumedNoUBInsts.insert(&I); 2995 return true; 2996 }; 2997 2998 auto InspectCallSiteForUB = [&](Instruction &I) { 2999 // Check whether a callsite always cause UB or not 3000 3001 // Skip instructions that are already saved. 3002 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I)) 3003 return true; 3004 3005 // Check nonnull and noundef argument attribute violation for each 3006 // callsite. 3007 CallBase &CB = cast<CallBase>(I); 3008 auto *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand()); 3009 if (!Callee) 3010 return true; 3011 for (unsigned idx = 0; idx < CB.arg_size(); idx++) { 3012 // If current argument is known to be simplified to null pointer and the 3013 // corresponding argument position is known to have nonnull attribute, 3014 // the argument is poison. Furthermore, if the argument is poison and 3015 // the position is known to have noundef attriubte, this callsite is 3016 // considered UB. 3017 if (idx >= Callee->arg_size()) 3018 break; 3019 Value *ArgVal = CB.getArgOperand(idx); 3020 if (!ArgVal) 3021 continue; 3022 // Here, we handle three cases. 3023 // (1) Not having a value means it is dead. (we can replace the value 3024 // with undef) 3025 // (2) Simplified to undef. The argument violate noundef attriubte. 3026 // (3) Simplified to null pointer where known to be nonnull. 3027 // The argument is a poison value and violate noundef attribute. 3028 IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx); 3029 bool IsKnownNoUndef; 3030 AA::hasAssumedIRAttr<Attribute::NoUndef>( 3031 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNoUndef); 3032 if (!IsKnownNoUndef) 3033 continue; 3034 bool UsedAssumedInformation = false; 3035 std::optional<Value *> SimplifiedVal = 3036 A.getAssumedSimplified(IRPosition::value(*ArgVal), *this, 3037 UsedAssumedInformation, AA::Interprocedural); 3038 if (UsedAssumedInformation) 3039 continue; 3040 if (SimplifiedVal && !*SimplifiedVal) 3041 return true; 3042 if (!SimplifiedVal || isa<UndefValue>(**SimplifiedVal)) { 3043 KnownUBInsts.insert(&I); 3044 continue; 3045 } 3046 if (!ArgVal->getType()->isPointerTy() || 3047 !isa<ConstantPointerNull>(**SimplifiedVal)) 3048 continue; 3049 bool IsKnownNonNull; 3050 AA::hasAssumedIRAttr<Attribute::NonNull>( 3051 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNonNull); 3052 if (IsKnownNonNull) 3053 KnownUBInsts.insert(&I); 3054 } 3055 return true; 3056 }; 3057 3058 auto InspectReturnInstForUB = [&](Instruction &I) { 3059 auto &RI = cast<ReturnInst>(I); 3060 // Either we stopped and the appropriate action was taken, 3061 // or we got back a simplified return value to continue. 3062 std::optional<Value *> SimplifiedRetValue = 3063 stopOnUndefOrAssumed(A, RI.getReturnValue(), &I); 3064 if (!SimplifiedRetValue || !*SimplifiedRetValue) 3065 return true; 3066 3067 // Check if a return instruction always cause UB or not 3068 // Note: It is guaranteed that the returned position of the anchor 3069 // scope has noundef attribute when this is called. 3070 // We also ensure the return position is not "assumed dead" 3071 // because the returned value was then potentially simplified to 3072 // `undef` in AAReturnedValues without removing the `noundef` 3073 // attribute yet. 3074 3075 // When the returned position has noundef attriubte, UB occurs in the 3076 // following cases. 3077 // (1) Returned value is known to be undef. 3078 // (2) The value is known to be a null pointer and the returned 3079 // position has nonnull attribute (because the returned value is 3080 // poison). 3081 if (isa<ConstantPointerNull>(*SimplifiedRetValue)) { 3082 bool IsKnownNonNull; 3083 AA::hasAssumedIRAttr<Attribute::NonNull>( 3084 A, this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE, 3085 IsKnownNonNull); 3086 if (IsKnownNonNull) 3087 KnownUBInsts.insert(&I); 3088 } 3089 3090 return true; 3091 }; 3092 3093 bool UsedAssumedInformation = false; 3094 A.checkForAllInstructions(InspectMemAccessInstForUB, *this, 3095 {Instruction::Load, Instruction::Store, 3096 Instruction::AtomicCmpXchg, 3097 Instruction::AtomicRMW}, 3098 UsedAssumedInformation, 3099 /* CheckBBLivenessOnly */ true); 3100 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::Br}, 3101 UsedAssumedInformation, 3102 /* CheckBBLivenessOnly */ true); 3103 A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this, 3104 UsedAssumedInformation); 3105 3106 // If the returned position of the anchor scope has noundef attriubte, check 3107 // all returned instructions. 3108 if (!getAnchorScope()->getReturnType()->isVoidTy()) { 3109 const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope()); 3110 if (!A.isAssumedDead(ReturnIRP, this, nullptr, UsedAssumedInformation)) { 3111 bool IsKnownNoUndef; 3112 AA::hasAssumedIRAttr<Attribute::NoUndef>( 3113 A, this, ReturnIRP, DepClassTy::NONE, IsKnownNoUndef); 3114 if (IsKnownNoUndef) 3115 A.checkForAllInstructions(InspectReturnInstForUB, *this, 3116 {Instruction::Ret}, UsedAssumedInformation, 3117 /* CheckBBLivenessOnly */ true); 3118 } 3119 } 3120 3121 if (NoUBPrevSize != AssumedNoUBInsts.size() || 3122 UBPrevSize != KnownUBInsts.size()) 3123 return ChangeStatus::CHANGED; 3124 return ChangeStatus::UNCHANGED; 3125 } 3126 3127 bool isKnownToCauseUB(Instruction *I) const override { 3128 return KnownUBInsts.count(I); 3129 } 3130 3131 bool isAssumedToCauseUB(Instruction *I) const override { 3132 // In simple words, if an instruction is not in the assumed to _not_ 3133 // cause UB, then it is assumed UB (that includes those 3134 // in the KnownUBInsts set). The rest is boilerplate 3135 // is to ensure that it is one of the instructions we test 3136 // for UB. 3137 3138 switch (I->getOpcode()) { 3139 case Instruction::Load: 3140 case Instruction::Store: 3141 case Instruction::AtomicCmpXchg: 3142 case Instruction::AtomicRMW: 3143 return !AssumedNoUBInsts.count(I); 3144 case Instruction::Br: { 3145 auto *BrInst = cast<BranchInst>(I); 3146 if (BrInst->isUnconditional()) 3147 return false; 3148 return !AssumedNoUBInsts.count(I); 3149 } break; 3150 default: 3151 return false; 3152 } 3153 return false; 3154 } 3155 3156 ChangeStatus manifest(Attributor &A) override { 3157 if (KnownUBInsts.empty()) 3158 return ChangeStatus::UNCHANGED; 3159 for (Instruction *I : KnownUBInsts) 3160 A.changeToUnreachableAfterManifest(I); 3161 return ChangeStatus::CHANGED; 3162 } 3163 3164 /// See AbstractAttribute::getAsStr() 3165 const std::string getAsStr(Attributor *A) const override { 3166 return getAssumed() ? "undefined-behavior" : "no-ub"; 3167 } 3168 3169 /// Note: The correctness of this analysis depends on the fact that the 3170 /// following 2 sets will stop changing after some point. 3171 /// "Change" here means that their size changes. 3172 /// The size of each set is monotonically increasing 3173 /// (we only add items to them) and it is upper bounded by the number of 3174 /// instructions in the processed function (we can never save more 3175 /// elements in either set than this number). Hence, at some point, 3176 /// they will stop increasing. 3177 /// Consequently, at some point, both sets will have stopped 3178 /// changing, effectively making the analysis reach a fixpoint. 3179 3180 /// Note: These 2 sets are disjoint and an instruction can be considered 3181 /// one of 3 things: 3182 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in 3183 /// the KnownUBInsts set. 3184 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior 3185 /// has a reason to assume it). 3186 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior 3187 /// could not find a reason to assume or prove that it can cause UB, 3188 /// hence it assumes it doesn't. We have a set for these instructions 3189 /// so that we don't reprocess them in every update. 3190 /// Note however that instructions in this set may cause UB. 3191 3192 protected: 3193 /// A set of all live instructions _known_ to cause UB. 3194 SmallPtrSet<Instruction *, 8> KnownUBInsts; 3195 3196 private: 3197 /// A set of all the (live) instructions that are assumed to _not_ cause UB. 3198 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts; 3199 3200 // Should be called on updates in which if we're processing an instruction 3201 // \p I that depends on a value \p V, one of the following has to happen: 3202 // - If the value is assumed, then stop. 3203 // - If the value is known but undef, then consider it UB. 3204 // - Otherwise, do specific processing with the simplified value. 3205 // We return std::nullopt in the first 2 cases to signify that an appropriate 3206 // action was taken and the caller should stop. 3207 // Otherwise, we return the simplified value that the caller should 3208 // use for specific processing. 3209 std::optional<Value *> stopOnUndefOrAssumed(Attributor &A, Value *V, 3210 Instruction *I) { 3211 bool UsedAssumedInformation = false; 3212 std::optional<Value *> SimplifiedV = 3213 A.getAssumedSimplified(IRPosition::value(*V), *this, 3214 UsedAssumedInformation, AA::Interprocedural); 3215 if (!UsedAssumedInformation) { 3216 // Don't depend on assumed values. 3217 if (!SimplifiedV) { 3218 // If it is known (which we tested above) but it doesn't have a value, 3219 // then we can assume `undef` and hence the instruction is UB. 3220 KnownUBInsts.insert(I); 3221 return std::nullopt; 3222 } 3223 if (!*SimplifiedV) 3224 return nullptr; 3225 V = *SimplifiedV; 3226 } 3227 if (isa<UndefValue>(V)) { 3228 KnownUBInsts.insert(I); 3229 return std::nullopt; 3230 } 3231 return V; 3232 } 3233 }; 3234 3235 struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl { 3236 AAUndefinedBehaviorFunction(const IRPosition &IRP, Attributor &A) 3237 : AAUndefinedBehaviorImpl(IRP, A) {} 3238 3239 /// See AbstractAttribute::trackStatistics() 3240 void trackStatistics() const override { 3241 STATS_DECL(UndefinedBehaviorInstruction, Instruction, 3242 "Number of instructions known to have UB"); 3243 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) += 3244 KnownUBInsts.size(); 3245 } 3246 }; 3247 } // namespace 3248 3249 /// ------------------------ Will-Return Attributes ---------------------------- 3250 3251 namespace { 3252 // Helper function that checks whether a function has any cycle which we don't 3253 // know if it is bounded or not. 3254 // Loops with maximum trip count are considered bounded, any other cycle not. 3255 static bool mayContainUnboundedCycle(Function &F, Attributor &A) { 3256 ScalarEvolution *SE = 3257 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(F); 3258 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(F); 3259 // If either SCEV or LoopInfo is not available for the function then we assume 3260 // any cycle to be unbounded cycle. 3261 // We use scc_iterator which uses Tarjan algorithm to find all the maximal 3262 // SCCs.To detect if there's a cycle, we only need to find the maximal ones. 3263 if (!SE || !LI) { 3264 for (scc_iterator<Function *> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI) 3265 if (SCCI.hasCycle()) 3266 return true; 3267 return false; 3268 } 3269 3270 // If there's irreducible control, the function may contain non-loop cycles. 3271 if (mayContainIrreducibleControl(F, LI)) 3272 return true; 3273 3274 // Any loop that does not have a max trip count is considered unbounded cycle. 3275 for (auto *L : LI->getLoopsInPreorder()) { 3276 if (!SE->getSmallConstantMaxTripCount(L)) 3277 return true; 3278 } 3279 return false; 3280 } 3281 3282 struct AAWillReturnImpl : public AAWillReturn { 3283 AAWillReturnImpl(const IRPosition &IRP, Attributor &A) 3284 : AAWillReturn(IRP, A) {} 3285 3286 /// See AbstractAttribute::initialize(...). 3287 void initialize(Attributor &A) override { 3288 bool IsKnown; 3289 assert(!AA::hasAssumedIRAttr<Attribute::WillReturn>( 3290 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown)); 3291 (void)IsKnown; 3292 } 3293 3294 /// Check for `mustprogress` and `readonly` as they imply `willreturn`. 3295 bool isImpliedByMustprogressAndReadonly(Attributor &A, bool KnownOnly) { 3296 if (!A.hasAttr(getIRPosition(), {Attribute::MustProgress})) 3297 return false; 3298 3299 bool IsKnown; 3300 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown)) 3301 return IsKnown || !KnownOnly; 3302 return false; 3303 } 3304 3305 /// See AbstractAttribute::updateImpl(...). 3306 ChangeStatus updateImpl(Attributor &A) override { 3307 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false)) 3308 return ChangeStatus::UNCHANGED; 3309 3310 auto CheckForWillReturn = [&](Instruction &I) { 3311 IRPosition IPos = IRPosition::callsite_function(cast<CallBase>(I)); 3312 bool IsKnown; 3313 if (AA::hasAssumedIRAttr<Attribute::WillReturn>( 3314 A, this, IPos, DepClassTy::REQUIRED, IsKnown)) { 3315 if (IsKnown) 3316 return true; 3317 } else { 3318 return false; 3319 } 3320 bool IsKnownNoRecurse; 3321 return AA::hasAssumedIRAttr<Attribute::NoRecurse>( 3322 A, this, IPos, DepClassTy::REQUIRED, IsKnownNoRecurse); 3323 }; 3324 3325 bool UsedAssumedInformation = false; 3326 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this, 3327 UsedAssumedInformation)) 3328 return indicatePessimisticFixpoint(); 3329 3330 return ChangeStatus::UNCHANGED; 3331 } 3332 3333 /// See AbstractAttribute::getAsStr() 3334 const std::string getAsStr(Attributor *A) const override { 3335 return getAssumed() ? "willreturn" : "may-noreturn"; 3336 } 3337 }; 3338 3339 struct AAWillReturnFunction final : AAWillReturnImpl { 3340 AAWillReturnFunction(const IRPosition &IRP, Attributor &A) 3341 : AAWillReturnImpl(IRP, A) {} 3342 3343 /// See AbstractAttribute::initialize(...). 3344 void initialize(Attributor &A) override { 3345 AAWillReturnImpl::initialize(A); 3346 3347 Function *F = getAnchorScope(); 3348 assert(F && "Did expect an anchor function"); 3349 if (F->isDeclaration() || mayContainUnboundedCycle(*F, A)) 3350 indicatePessimisticFixpoint(); 3351 } 3352 3353 /// See AbstractAttribute::trackStatistics() 3354 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) } 3355 }; 3356 3357 /// WillReturn attribute deduction for a call sites. 3358 struct AAWillReturnCallSite final : AAWillReturnImpl { 3359 AAWillReturnCallSite(const IRPosition &IRP, Attributor &A) 3360 : AAWillReturnImpl(IRP, A) {} 3361 3362 /// See AbstractAttribute::updateImpl(...). 3363 ChangeStatus updateImpl(Attributor &A) override { 3364 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false)) 3365 return ChangeStatus::UNCHANGED; 3366 3367 // TODO: Once we have call site specific value information we can provide 3368 // call site specific liveness information and then it makes 3369 // sense to specialize attributes for call sites arguments instead of 3370 // redirecting requests to the callee argument. 3371 Function *F = getAssociatedFunction(); 3372 const IRPosition &FnPos = IRPosition::function(*F); 3373 bool IsKnown; 3374 if (AA::hasAssumedIRAttr<Attribute::WillReturn>( 3375 A, this, FnPos, DepClassTy::REQUIRED, IsKnown)) 3376 return ChangeStatus::UNCHANGED; 3377 return indicatePessimisticFixpoint(); 3378 } 3379 3380 /// See AbstractAttribute::trackStatistics() 3381 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); } 3382 }; 3383 } // namespace 3384 3385 /// -------------------AAIntraFnReachability Attribute-------------------------- 3386 3387 /// All information associated with a reachability query. This boilerplate code 3388 /// is used by both AAIntraFnReachability and AAInterFnReachability, with 3389 /// different \p ToTy values. 3390 template <typename ToTy> struct ReachabilityQueryInfo { 3391 enum class Reachable { 3392 No, 3393 Yes, 3394 }; 3395 3396 /// Start here, 3397 const Instruction *From = nullptr; 3398 /// reach this place, 3399 const ToTy *To = nullptr; 3400 /// without going through any of these instructions, 3401 const AA::InstExclusionSetTy *ExclusionSet = nullptr; 3402 /// and remember if it worked: 3403 Reachable Result = Reachable::No; 3404 3405 ReachabilityQueryInfo(const Instruction *From, const ToTy *To) 3406 : From(From), To(To) {} 3407 3408 /// Constructor replacement to ensure unique and stable sets are used for the 3409 /// cache. 3410 ReachabilityQueryInfo(Attributor &A, const Instruction &From, const ToTy &To, 3411 const AA::InstExclusionSetTy *ES, bool MakeUnique) 3412 : From(&From), To(&To), ExclusionSet(ES) { 3413 3414 if (!ES || ES->empty()) { 3415 ExclusionSet = nullptr; 3416 } else if (MakeUnique) { 3417 ExclusionSet = A.getInfoCache().getOrCreateUniqueBlockExecutionSet(ES); 3418 } 3419 } 3420 3421 ReachabilityQueryInfo(const ReachabilityQueryInfo &RQI) 3422 : From(RQI.From), To(RQI.To), ExclusionSet(RQI.ExclusionSet) {} 3423 }; 3424 3425 namespace llvm { 3426 template <typename ToTy> struct DenseMapInfo<ReachabilityQueryInfo<ToTy> *> { 3427 using InstSetDMI = DenseMapInfo<const AA::InstExclusionSetTy *>; 3428 using PairDMI = DenseMapInfo<std::pair<const Instruction *, const ToTy *>>; 3429 3430 static ReachabilityQueryInfo<ToTy> EmptyKey; 3431 static ReachabilityQueryInfo<ToTy> TombstoneKey; 3432 3433 static inline ReachabilityQueryInfo<ToTy> *getEmptyKey() { return &EmptyKey; } 3434 static inline ReachabilityQueryInfo<ToTy> *getTombstoneKey() { 3435 return &TombstoneKey; 3436 } 3437 static unsigned getHashValue(const ReachabilityQueryInfo<ToTy> *RQI) { 3438 unsigned H = PairDMI ::getHashValue({RQI->From, RQI->To}); 3439 H += InstSetDMI::getHashValue(RQI->ExclusionSet); 3440 return H; 3441 } 3442 static bool isEqual(const ReachabilityQueryInfo<ToTy> *LHS, 3443 const ReachabilityQueryInfo<ToTy> *RHS) { 3444 if (!PairDMI::isEqual({LHS->From, LHS->To}, {RHS->From, RHS->To})) 3445 return false; 3446 return InstSetDMI::isEqual(LHS->ExclusionSet, RHS->ExclusionSet); 3447 } 3448 }; 3449 3450 #define DefineKeys(ToTy) \ 3451 template <> \ 3452 ReachabilityQueryInfo<ToTy> \ 3453 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::EmptyKey = \ 3454 ReachabilityQueryInfo<ToTy>( \ 3455 DenseMapInfo<const Instruction *>::getEmptyKey(), \ 3456 DenseMapInfo<const ToTy *>::getEmptyKey()); \ 3457 template <> \ 3458 ReachabilityQueryInfo<ToTy> \ 3459 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::TombstoneKey = \ 3460 ReachabilityQueryInfo<ToTy>( \ 3461 DenseMapInfo<const Instruction *>::getTombstoneKey(), \ 3462 DenseMapInfo<const ToTy *>::getTombstoneKey()); 3463 3464 DefineKeys(Instruction) DefineKeys(Function) 3465 #undef DefineKeys 3466 3467 } // namespace llvm 3468 3469 namespace { 3470 3471 template <typename BaseTy, typename ToTy> 3472 struct CachedReachabilityAA : public BaseTy { 3473 using RQITy = ReachabilityQueryInfo<ToTy>; 3474 3475 CachedReachabilityAA(const IRPosition &IRP, Attributor &A) : BaseTy(IRP, A) {} 3476 3477 /// See AbstractAttribute::isQueryAA. 3478 bool isQueryAA() const override { return true; } 3479 3480 /// See AbstractAttribute::updateImpl(...). 3481 ChangeStatus updateImpl(Attributor &A) override { 3482 ChangeStatus Changed = ChangeStatus::UNCHANGED; 3483 InUpdate = true; 3484 for (unsigned u = 0, e = QueryVector.size(); u < e; ++u) { 3485 RQITy *RQI = QueryVector[u]; 3486 if (RQI->Result == RQITy::Reachable::No && isReachableImpl(A, *RQI)) 3487 Changed = ChangeStatus::CHANGED; 3488 } 3489 InUpdate = false; 3490 return Changed; 3491 } 3492 3493 virtual bool isReachableImpl(Attributor &A, RQITy &RQI) = 0; 3494 3495 bool rememberResult(Attributor &A, typename RQITy::Reachable Result, 3496 RQITy &RQI, bool UsedExclusionSet) { 3497 RQI.Result = Result; 3498 3499 // Remove the temporary RQI from the cache. 3500 if (!InUpdate) 3501 QueryCache.erase(&RQI); 3502 3503 // Insert a plain RQI (w/o exclusion set) if that makes sense. Two options: 3504 // 1) If it is reachable, it doesn't matter if we have an exclusion set for 3505 // this query. 2) We did not use the exclusion set, potentially because 3506 // there is none. 3507 if (Result == RQITy::Reachable::Yes || !UsedExclusionSet) { 3508 RQITy PlainRQI(RQI.From, RQI.To); 3509 if (!QueryCache.count(&PlainRQI)) { 3510 RQITy *RQIPtr = new (A.Allocator) RQITy(RQI.From, RQI.To); 3511 RQIPtr->Result = Result; 3512 QueryVector.push_back(RQIPtr); 3513 QueryCache.insert(RQIPtr); 3514 } 3515 } 3516 3517 // Check if we need to insert a new permanent RQI with the exclusion set. 3518 if (!InUpdate && Result != RQITy::Reachable::Yes && UsedExclusionSet) { 3519 assert((!RQI.ExclusionSet || !RQI.ExclusionSet->empty()) && 3520 "Did not expect empty set!"); 3521 RQITy *RQIPtr = new (A.Allocator) 3522 RQITy(A, *RQI.From, *RQI.To, RQI.ExclusionSet, true); 3523 assert(RQIPtr->Result == RQITy::Reachable::No && "Already reachable?"); 3524 RQIPtr->Result = Result; 3525 assert(!QueryCache.count(RQIPtr)); 3526 QueryVector.push_back(RQIPtr); 3527 QueryCache.insert(RQIPtr); 3528 } 3529 3530 if (Result == RQITy::Reachable::No && !InUpdate) 3531 A.registerForUpdate(*this); 3532 return Result == RQITy::Reachable::Yes; 3533 } 3534 3535 const std::string getAsStr(Attributor *A) const override { 3536 // TODO: Return the number of reachable queries. 3537 return "#queries(" + std::to_string(QueryVector.size()) + ")"; 3538 } 3539 3540 bool checkQueryCache(Attributor &A, RQITy &StackRQI, 3541 typename RQITy::Reachable &Result) { 3542 if (!this->getState().isValidState()) { 3543 Result = RQITy::Reachable::Yes; 3544 return true; 3545 } 3546 3547 // If we have an exclusion set we might be able to find our answer by 3548 // ignoring it first. 3549 if (StackRQI.ExclusionSet) { 3550 RQITy PlainRQI(StackRQI.From, StackRQI.To); 3551 auto It = QueryCache.find(&PlainRQI); 3552 if (It != QueryCache.end() && (*It)->Result == RQITy::Reachable::No) { 3553 Result = RQITy::Reachable::No; 3554 return true; 3555 } 3556 } 3557 3558 auto It = QueryCache.find(&StackRQI); 3559 if (It != QueryCache.end()) { 3560 Result = (*It)->Result; 3561 return true; 3562 } 3563 3564 // Insert a temporary for recursive queries. We will replace it with a 3565 // permanent entry later. 3566 QueryCache.insert(&StackRQI); 3567 return false; 3568 } 3569 3570 private: 3571 bool InUpdate = false; 3572 SmallVector<RQITy *> QueryVector; 3573 DenseSet<RQITy *> QueryCache; 3574 }; 3575 3576 struct AAIntraFnReachabilityFunction final 3577 : public CachedReachabilityAA<AAIntraFnReachability, Instruction> { 3578 using Base = CachedReachabilityAA<AAIntraFnReachability, Instruction>; 3579 AAIntraFnReachabilityFunction(const IRPosition &IRP, Attributor &A) 3580 : Base(IRP, A) {} 3581 3582 bool isAssumedReachable( 3583 Attributor &A, const Instruction &From, const Instruction &To, 3584 const AA::InstExclusionSetTy *ExclusionSet) const override { 3585 auto *NonConstThis = const_cast<AAIntraFnReachabilityFunction *>(this); 3586 if (&From == &To) 3587 return true; 3588 3589 RQITy StackRQI(A, From, To, ExclusionSet, false); 3590 typename RQITy::Reachable Result; 3591 if (!NonConstThis->checkQueryCache(A, StackRQI, Result)) 3592 return NonConstThis->isReachableImpl(A, StackRQI); 3593 return Result == RQITy::Reachable::Yes; 3594 } 3595 3596 ChangeStatus updateImpl(Attributor &A) override { 3597 // We only depend on liveness. DeadEdges is all we care about, check if any 3598 // of them changed. 3599 auto *LivenessAA = 3600 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL); 3601 if (LivenessAA && llvm::all_of(DeadEdges, [&](const auto &DeadEdge) { 3602 return LivenessAA->isEdgeDead(DeadEdge.first, DeadEdge.second); 3603 })) { 3604 return ChangeStatus::UNCHANGED; 3605 } 3606 DeadEdges.clear(); 3607 return Base::updateImpl(A); 3608 } 3609 3610 bool isReachableImpl(Attributor &A, RQITy &RQI) override { 3611 const Instruction *Origin = RQI.From; 3612 bool UsedExclusionSet = false; 3613 3614 auto WillReachInBlock = [&](const Instruction &From, const Instruction &To, 3615 const AA::InstExclusionSetTy *ExclusionSet) { 3616 const Instruction *IP = &From; 3617 while (IP && IP != &To) { 3618 if (ExclusionSet && IP != Origin && ExclusionSet->count(IP)) { 3619 UsedExclusionSet = true; 3620 break; 3621 } 3622 IP = IP->getNextNode(); 3623 } 3624 return IP == &To; 3625 }; 3626 3627 const BasicBlock *FromBB = RQI.From->getParent(); 3628 const BasicBlock *ToBB = RQI.To->getParent(); 3629 assert(FromBB->getParent() == ToBB->getParent() && 3630 "Not an intra-procedural query!"); 3631 3632 // Check intra-block reachability, however, other reaching paths are still 3633 // possible. 3634 if (FromBB == ToBB && 3635 WillReachInBlock(*RQI.From, *RQI.To, RQI.ExclusionSet)) 3636 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet); 3637 3638 // Check if reaching the ToBB block is sufficient or if even that would not 3639 // ensure reaching the target. In the latter case we are done. 3640 if (!WillReachInBlock(ToBB->front(), *RQI.To, RQI.ExclusionSet)) 3641 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet); 3642 3643 SmallPtrSet<const BasicBlock *, 16> ExclusionBlocks; 3644 if (RQI.ExclusionSet) 3645 for (auto *I : *RQI.ExclusionSet) 3646 ExclusionBlocks.insert(I->getParent()); 3647 3648 // Check if we make it out of the FromBB block at all. 3649 if (ExclusionBlocks.count(FromBB) && 3650 !WillReachInBlock(*RQI.From, *FromBB->getTerminator(), 3651 RQI.ExclusionSet)) 3652 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet); 3653 3654 SmallPtrSet<const BasicBlock *, 16> Visited; 3655 SmallVector<const BasicBlock *, 16> Worklist; 3656 Worklist.push_back(FromBB); 3657 3658 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> LocalDeadEdges; 3659 auto *LivenessAA = 3660 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL); 3661 while (!Worklist.empty()) { 3662 const BasicBlock *BB = Worklist.pop_back_val(); 3663 if (!Visited.insert(BB).second) 3664 continue; 3665 for (const BasicBlock *SuccBB : successors(BB)) { 3666 if (LivenessAA && LivenessAA->isEdgeDead(BB, SuccBB)) { 3667 LocalDeadEdges.insert({BB, SuccBB}); 3668 continue; 3669 } 3670 // We checked before if we just need to reach the ToBB block. 3671 if (SuccBB == ToBB) 3672 return rememberResult(A, RQITy::Reachable::Yes, RQI, 3673 UsedExclusionSet); 3674 if (ExclusionBlocks.count(SuccBB)) { 3675 UsedExclusionSet = true; 3676 continue; 3677 } 3678 Worklist.push_back(SuccBB); 3679 } 3680 } 3681 3682 DeadEdges.insert(LocalDeadEdges.begin(), LocalDeadEdges.end()); 3683 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet); 3684 } 3685 3686 /// See AbstractAttribute::trackStatistics() 3687 void trackStatistics() const override {} 3688 3689 private: 3690 // Set of assumed dead edges we used in the last query. If any changes we 3691 // update the state. 3692 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> DeadEdges; 3693 }; 3694 } // namespace 3695 3696 /// ------------------------ NoAlias Argument Attribute ------------------------ 3697 3698 bool AANoAlias::isImpliedByIR(Attributor &A, const IRPosition &IRP, 3699 Attribute::AttrKind ImpliedAttributeKind, 3700 bool IgnoreSubsumingPositions) { 3701 assert(ImpliedAttributeKind == Attribute::NoAlias && 3702 "Unexpected attribute kind"); 3703 Value *Val = &IRP.getAssociatedValue(); 3704 if (IRP.getPositionKind() != IRP_CALL_SITE_ARGUMENT) { 3705 if (isa<AllocaInst>(Val)) 3706 return true; 3707 } else { 3708 IgnoreSubsumingPositions = true; 3709 } 3710 3711 if (isa<UndefValue>(Val)) 3712 return true; 3713 3714 if (isa<ConstantPointerNull>(Val) && 3715 !NullPointerIsDefined(IRP.getAnchorScope(), 3716 Val->getType()->getPointerAddressSpace())) 3717 return true; 3718 3719 if (A.hasAttr(IRP, {Attribute::ByVal, Attribute::NoAlias}, 3720 IgnoreSubsumingPositions, Attribute::NoAlias)) 3721 return true; 3722 3723 return false; 3724 } 3725 3726 namespace { 3727 struct AANoAliasImpl : AANoAlias { 3728 AANoAliasImpl(const IRPosition &IRP, Attributor &A) : AANoAlias(IRP, A) { 3729 assert(getAssociatedType()->isPointerTy() && 3730 "Noalias is a pointer attribute"); 3731 } 3732 3733 const std::string getAsStr(Attributor *A) const override { 3734 return getAssumed() ? "noalias" : "may-alias"; 3735 } 3736 }; 3737 3738 /// NoAlias attribute for a floating value. 3739 struct AANoAliasFloating final : AANoAliasImpl { 3740 AANoAliasFloating(const IRPosition &IRP, Attributor &A) 3741 : AANoAliasImpl(IRP, A) {} 3742 3743 /// See AbstractAttribute::updateImpl(...). 3744 ChangeStatus updateImpl(Attributor &A) override { 3745 // TODO: Implement this. 3746 return indicatePessimisticFixpoint(); 3747 } 3748 3749 /// See AbstractAttribute::trackStatistics() 3750 void trackStatistics() const override { 3751 STATS_DECLTRACK_FLOATING_ATTR(noalias) 3752 } 3753 }; 3754 3755 /// NoAlias attribute for an argument. 3756 struct AANoAliasArgument final 3757 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl, 3758 AANoAlias::StateType, false, 3759 Attribute::NoAlias> { 3760 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl, 3761 AANoAlias::StateType, false, 3762 Attribute::NoAlias>; 3763 AANoAliasArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {} 3764 3765 /// See AbstractAttribute::update(...). 3766 ChangeStatus updateImpl(Attributor &A) override { 3767 // We have to make sure no-alias on the argument does not break 3768 // synchronization when this is a callback argument, see also [1] below. 3769 // If synchronization cannot be affected, we delegate to the base updateImpl 3770 // function, otherwise we give up for now. 3771 3772 // If the function is no-sync, no-alias cannot break synchronization. 3773 bool IsKnownNoSycn; 3774 if (AA::hasAssumedIRAttr<Attribute::NoSync>( 3775 A, this, IRPosition::function_scope(getIRPosition()), 3776 DepClassTy::OPTIONAL, IsKnownNoSycn)) 3777 return Base::updateImpl(A); 3778 3779 // If the argument is read-only, no-alias cannot break synchronization. 3780 bool IsKnown; 3781 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown)) 3782 return Base::updateImpl(A); 3783 3784 // If the argument is never passed through callbacks, no-alias cannot break 3785 // synchronization. 3786 bool UsedAssumedInformation = false; 3787 if (A.checkForAllCallSites( 3788 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this, 3789 true, UsedAssumedInformation)) 3790 return Base::updateImpl(A); 3791 3792 // TODO: add no-alias but make sure it doesn't break synchronization by 3793 // introducing fake uses. See: 3794 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel, 3795 // International Workshop on OpenMP 2018, 3796 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf 3797 3798 return indicatePessimisticFixpoint(); 3799 } 3800 3801 /// See AbstractAttribute::trackStatistics() 3802 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) } 3803 }; 3804 3805 struct AANoAliasCallSiteArgument final : AANoAliasImpl { 3806 AANoAliasCallSiteArgument(const IRPosition &IRP, Attributor &A) 3807 : AANoAliasImpl(IRP, A) {} 3808 3809 /// Determine if the underlying value may alias with the call site argument 3810 /// \p OtherArgNo of \p ICS (= the underlying call site). 3811 bool mayAliasWithArgument(Attributor &A, AAResults *&AAR, 3812 const AAMemoryBehavior &MemBehaviorAA, 3813 const CallBase &CB, unsigned OtherArgNo) { 3814 // We do not need to worry about aliasing with the underlying IRP. 3815 if (this->getCalleeArgNo() == (int)OtherArgNo) 3816 return false; 3817 3818 // If it is not a pointer or pointer vector we do not alias. 3819 const Value *ArgOp = CB.getArgOperand(OtherArgNo); 3820 if (!ArgOp->getType()->isPtrOrPtrVectorTy()) 3821 return false; 3822 3823 auto *CBArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>( 3824 *this, IRPosition::callsite_argument(CB, OtherArgNo), DepClassTy::NONE); 3825 3826 // If the argument is readnone, there is no read-write aliasing. 3827 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadNone()) { 3828 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL); 3829 return false; 3830 } 3831 3832 // If the argument is readonly and the underlying value is readonly, there 3833 // is no read-write aliasing. 3834 bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly(); 3835 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadOnly() && 3836 IsReadOnly) { 3837 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL); 3838 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL); 3839 return false; 3840 } 3841 3842 // We have to utilize actual alias analysis queries so we need the object. 3843 if (!AAR) 3844 AAR = A.getInfoCache().getAnalysisResultForFunction<AAManager>( 3845 *getAnchorScope()); 3846 3847 // Try to rule it out at the call site. 3848 bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp); 3849 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between " 3850 "callsite arguments: " 3851 << getAssociatedValue() << " " << *ArgOp << " => " 3852 << (IsAliasing ? "" : "no-") << "alias \n"); 3853 3854 return IsAliasing; 3855 } 3856 3857 bool isKnownNoAliasDueToNoAliasPreservation( 3858 Attributor &A, AAResults *&AAR, const AAMemoryBehavior &MemBehaviorAA) { 3859 // We can deduce "noalias" if the following conditions hold. 3860 // (i) Associated value is assumed to be noalias in the definition. 3861 // (ii) Associated value is assumed to be no-capture in all the uses 3862 // possibly executed before this callsite. 3863 // (iii) There is no other pointer argument which could alias with the 3864 // value. 3865 3866 auto IsDereferenceableOrNull = [&](Value *O, const DataLayout &DL) { 3867 const auto *DerefAA = A.getAAFor<AADereferenceable>( 3868 *this, IRPosition::value(*O), DepClassTy::OPTIONAL); 3869 return DerefAA ? DerefAA->getAssumedDereferenceableBytes() : 0; 3870 }; 3871 3872 const IRPosition &VIRP = IRPosition::value(getAssociatedValue()); 3873 const Function *ScopeFn = VIRP.getAnchorScope(); 3874 // Check whether the value is captured in the scope using AANoCapture. 3875 // Look at CFG and check only uses possibly executed before this 3876 // callsite. 3877 auto UsePred = [&](const Use &U, bool &Follow) -> bool { 3878 Instruction *UserI = cast<Instruction>(U.getUser()); 3879 3880 // If UserI is the curr instruction and there is a single potential use of 3881 // the value in UserI we allow the use. 3882 // TODO: We should inspect the operands and allow those that cannot alias 3883 // with the value. 3884 if (UserI == getCtxI() && UserI->getNumOperands() == 1) 3885 return true; 3886 3887 if (ScopeFn) { 3888 if (auto *CB = dyn_cast<CallBase>(UserI)) { 3889 if (CB->isArgOperand(&U)) { 3890 3891 unsigned ArgNo = CB->getArgOperandNo(&U); 3892 3893 bool IsKnownNoCapture; 3894 if (AA::hasAssumedIRAttr<Attribute::NoCapture>( 3895 A, this, IRPosition::callsite_argument(*CB, ArgNo), 3896 DepClassTy::OPTIONAL, IsKnownNoCapture)) 3897 return true; 3898 } 3899 } 3900 3901 if (!AA::isPotentiallyReachable( 3902 A, *UserI, *getCtxI(), *this, /* ExclusionSet */ nullptr, 3903 [ScopeFn](const Function &Fn) { return &Fn != ScopeFn; })) 3904 return true; 3905 } 3906 3907 // TODO: We should track the capturing uses in AANoCapture but the problem 3908 // is CGSCC runs. For those we would need to "allow" AANoCapture for 3909 // a value in the module slice. 3910 switch (DetermineUseCaptureKind(U, IsDereferenceableOrNull)) { 3911 case UseCaptureKind::NO_CAPTURE: 3912 return true; 3913 case UseCaptureKind::MAY_CAPTURE: 3914 LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *UserI 3915 << "\n"); 3916 return false; 3917 case UseCaptureKind::PASSTHROUGH: 3918 Follow = true; 3919 return true; 3920 } 3921 llvm_unreachable("unknown UseCaptureKind"); 3922 }; 3923 3924 bool IsKnownNoCapture; 3925 const AANoCapture *NoCaptureAA = nullptr; 3926 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>( 3927 A, this, VIRP, DepClassTy::NONE, IsKnownNoCapture, false, &NoCaptureAA); 3928 if (!IsAssumedNoCapture && 3929 (!NoCaptureAA || !NoCaptureAA->isAssumedNoCaptureMaybeReturned())) { 3930 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) { 3931 LLVM_DEBUG( 3932 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue() 3933 << " cannot be noalias as it is potentially captured\n"); 3934 return false; 3935 } 3936 } 3937 if (NoCaptureAA) 3938 A.recordDependence(*NoCaptureAA, *this, DepClassTy::OPTIONAL); 3939 3940 // Check there is no other pointer argument which could alias with the 3941 // value passed at this call site. 3942 // TODO: AbstractCallSite 3943 const auto &CB = cast<CallBase>(getAnchorValue()); 3944 for (unsigned OtherArgNo = 0; OtherArgNo < CB.arg_size(); OtherArgNo++) 3945 if (mayAliasWithArgument(A, AAR, MemBehaviorAA, CB, OtherArgNo)) 3946 return false; 3947 3948 return true; 3949 } 3950 3951 /// See AbstractAttribute::updateImpl(...). 3952 ChangeStatus updateImpl(Attributor &A) override { 3953 // If the argument is readnone we are done as there are no accesses via the 3954 // argument. 3955 auto *MemBehaviorAA = 3956 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE); 3957 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) { 3958 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL); 3959 return ChangeStatus::UNCHANGED; 3960 } 3961 3962 bool IsKnownNoAlias; 3963 const IRPosition &VIRP = IRPosition::value(getAssociatedValue()); 3964 if (!AA::hasAssumedIRAttr<Attribute::NoAlias>( 3965 A, this, VIRP, DepClassTy::REQUIRED, IsKnownNoAlias)) { 3966 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue() 3967 << " is not no-alias at the definition\n"); 3968 return indicatePessimisticFixpoint(); 3969 } 3970 3971 AAResults *AAR = nullptr; 3972 if (MemBehaviorAA && 3973 isKnownNoAliasDueToNoAliasPreservation(A, AAR, *MemBehaviorAA)) { 3974 LLVM_DEBUG( 3975 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n"); 3976 return ChangeStatus::UNCHANGED; 3977 } 3978 3979 return indicatePessimisticFixpoint(); 3980 } 3981 3982 /// See AbstractAttribute::trackStatistics() 3983 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) } 3984 }; 3985 3986 /// NoAlias attribute for function return value. 3987 struct AANoAliasReturned final : AANoAliasImpl { 3988 AANoAliasReturned(const IRPosition &IRP, Attributor &A) 3989 : AANoAliasImpl(IRP, A) {} 3990 3991 /// See AbstractAttribute::updateImpl(...). 3992 ChangeStatus updateImpl(Attributor &A) override { 3993 3994 auto CheckReturnValue = [&](Value &RV) -> bool { 3995 if (Constant *C = dyn_cast<Constant>(&RV)) 3996 if (C->isNullValue() || isa<UndefValue>(C)) 3997 return true; 3998 3999 /// For now, we can only deduce noalias if we have call sites. 4000 /// FIXME: add more support. 4001 if (!isa<CallBase>(&RV)) 4002 return false; 4003 4004 const IRPosition &RVPos = IRPosition::value(RV); 4005 bool IsKnownNoAlias; 4006 if (!AA::hasAssumedIRAttr<Attribute::NoAlias>( 4007 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoAlias)) 4008 return false; 4009 4010 bool IsKnownNoCapture; 4011 const AANoCapture *NoCaptureAA = nullptr; 4012 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>( 4013 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoCapture, false, 4014 &NoCaptureAA); 4015 return IsAssumedNoCapture || 4016 (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned()); 4017 }; 4018 4019 if (!A.checkForAllReturnedValues(CheckReturnValue, *this)) 4020 return indicatePessimisticFixpoint(); 4021 4022 return ChangeStatus::UNCHANGED; 4023 } 4024 4025 /// See AbstractAttribute::trackStatistics() 4026 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) } 4027 }; 4028 4029 /// NoAlias attribute deduction for a call site return value. 4030 struct AANoAliasCallSiteReturned final : AANoAliasImpl { 4031 AANoAliasCallSiteReturned(const IRPosition &IRP, Attributor &A) 4032 : AANoAliasImpl(IRP, A) {} 4033 4034 /// See AbstractAttribute::updateImpl(...). 4035 ChangeStatus updateImpl(Attributor &A) override { 4036 // TODO: Once we have call site specific value information we can provide 4037 // call site specific liveness information and then it makes 4038 // sense to specialize attributes for call sites arguments instead of 4039 // redirecting requests to the callee argument. 4040 Function *F = getAssociatedFunction(); 4041 const IRPosition &FnPos = IRPosition::returned(*F); 4042 bool IsKnownNoAlias; 4043 if (!AA::hasAssumedIRAttr<Attribute::NoAlias>( 4044 A, this, FnPos, DepClassTy::REQUIRED, IsKnownNoAlias)) 4045 return indicatePessimisticFixpoint(); 4046 return ChangeStatus::UNCHANGED; 4047 } 4048 4049 /// See AbstractAttribute::trackStatistics() 4050 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); } 4051 }; 4052 } // namespace 4053 4054 /// -------------------AAIsDead Function Attribute----------------------- 4055 4056 namespace { 4057 struct AAIsDeadValueImpl : public AAIsDead { 4058 AAIsDeadValueImpl(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {} 4059 4060 /// See AAIsDead::isAssumedDead(). 4061 bool isAssumedDead() const override { return isAssumed(IS_DEAD); } 4062 4063 /// See AAIsDead::isKnownDead(). 4064 bool isKnownDead() const override { return isKnown(IS_DEAD); } 4065 4066 /// See AAIsDead::isAssumedDead(BasicBlock *). 4067 bool isAssumedDead(const BasicBlock *BB) const override { return false; } 4068 4069 /// See AAIsDead::isKnownDead(BasicBlock *). 4070 bool isKnownDead(const BasicBlock *BB) const override { return false; } 4071 4072 /// See AAIsDead::isAssumedDead(Instruction *I). 4073 bool isAssumedDead(const Instruction *I) const override { 4074 return I == getCtxI() && isAssumedDead(); 4075 } 4076 4077 /// See AAIsDead::isKnownDead(Instruction *I). 4078 bool isKnownDead(const Instruction *I) const override { 4079 return isAssumedDead(I) && isKnownDead(); 4080 } 4081 4082 /// See AbstractAttribute::getAsStr(). 4083 const std::string getAsStr(Attributor *A) const override { 4084 return isAssumedDead() ? "assumed-dead" : "assumed-live"; 4085 } 4086 4087 /// Check if all uses are assumed dead. 4088 bool areAllUsesAssumedDead(Attributor &A, Value &V) { 4089 // Callers might not check the type, void has no uses. 4090 if (V.getType()->isVoidTy() || V.use_empty()) 4091 return true; 4092 4093 // If we replace a value with a constant there are no uses left afterwards. 4094 if (!isa<Constant>(V)) { 4095 if (auto *I = dyn_cast<Instruction>(&V)) 4096 if (!A.isRunOn(*I->getFunction())) 4097 return false; 4098 bool UsedAssumedInformation = false; 4099 std::optional<Constant *> C = 4100 A.getAssumedConstant(V, *this, UsedAssumedInformation); 4101 if (!C || *C) 4102 return true; 4103 } 4104 4105 auto UsePred = [&](const Use &U, bool &Follow) { return false; }; 4106 // Explicitly set the dependence class to required because we want a long 4107 // chain of N dependent instructions to be considered live as soon as one is 4108 // without going through N update cycles. This is not required for 4109 // correctness. 4110 return A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ false, 4111 DepClassTy::REQUIRED, 4112 /* IgnoreDroppableUses */ false); 4113 } 4114 4115 /// Determine if \p I is assumed to be side-effect free. 4116 bool isAssumedSideEffectFree(Attributor &A, Instruction *I) { 4117 if (!I || wouldInstructionBeTriviallyDead(I)) 4118 return true; 4119 4120 auto *CB = dyn_cast<CallBase>(I); 4121 if (!CB || isa<IntrinsicInst>(CB)) 4122 return false; 4123 4124 const IRPosition &CallIRP = IRPosition::callsite_function(*CB); 4125 4126 bool IsKnownNoUnwind; 4127 if (!AA::hasAssumedIRAttr<Attribute::NoUnwind>( 4128 A, this, CallIRP, DepClassTy::OPTIONAL, IsKnownNoUnwind)) 4129 return false; 4130 4131 bool IsKnown; 4132 return AA::isAssumedReadOnly(A, CallIRP, *this, IsKnown); 4133 } 4134 }; 4135 4136 struct AAIsDeadFloating : public AAIsDeadValueImpl { 4137 AAIsDeadFloating(const IRPosition &IRP, Attributor &A) 4138 : AAIsDeadValueImpl(IRP, A) {} 4139 4140 /// See AbstractAttribute::initialize(...). 4141 void initialize(Attributor &A) override { 4142 AAIsDeadValueImpl::initialize(A); 4143 4144 if (isa<UndefValue>(getAssociatedValue())) { 4145 indicatePessimisticFixpoint(); 4146 return; 4147 } 4148 4149 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()); 4150 if (!isAssumedSideEffectFree(A, I)) { 4151 if (!isa_and_nonnull<StoreInst>(I) && !isa_and_nonnull<FenceInst>(I)) 4152 indicatePessimisticFixpoint(); 4153 else 4154 removeAssumedBits(HAS_NO_EFFECT); 4155 } 4156 } 4157 4158 bool isDeadFence(Attributor &A, FenceInst &FI) { 4159 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>( 4160 IRPosition::function(*FI.getFunction()), *this, DepClassTy::NONE); 4161 if (!ExecDomainAA || !ExecDomainAA->isNoOpFence(FI)) 4162 return false; 4163 A.recordDependence(*ExecDomainAA, *this, DepClassTy::OPTIONAL); 4164 return true; 4165 } 4166 4167 bool isDeadStore(Attributor &A, StoreInst &SI, 4168 SmallSetVector<Instruction *, 8> *AssumeOnlyInst = nullptr) { 4169 // Lang ref now states volatile store is not UB/dead, let's skip them. 4170 if (SI.isVolatile()) 4171 return false; 4172 4173 // If we are collecting assumes to be deleted we are in the manifest stage. 4174 // It's problematic to collect the potential copies again now so we use the 4175 // cached ones. 4176 bool UsedAssumedInformation = false; 4177 if (!AssumeOnlyInst) { 4178 PotentialCopies.clear(); 4179 if (!AA::getPotentialCopiesOfStoredValue(A, SI, PotentialCopies, *this, 4180 UsedAssumedInformation)) { 4181 LLVM_DEBUG( 4182 dbgs() 4183 << "[AAIsDead] Could not determine potential copies of store!\n"); 4184 return false; 4185 } 4186 } 4187 LLVM_DEBUG(dbgs() << "[AAIsDead] Store has " << PotentialCopies.size() 4188 << " potential copies.\n"); 4189 4190 InformationCache &InfoCache = A.getInfoCache(); 4191 return llvm::all_of(PotentialCopies, [&](Value *V) { 4192 if (A.isAssumedDead(IRPosition::value(*V), this, nullptr, 4193 UsedAssumedInformation)) 4194 return true; 4195 if (auto *LI = dyn_cast<LoadInst>(V)) { 4196 if (llvm::all_of(LI->uses(), [&](const Use &U) { 4197 auto &UserI = cast<Instruction>(*U.getUser()); 4198 if (InfoCache.isOnlyUsedByAssume(UserI)) { 4199 if (AssumeOnlyInst) 4200 AssumeOnlyInst->insert(&UserI); 4201 return true; 4202 } 4203 return A.isAssumedDead(U, this, nullptr, UsedAssumedInformation); 4204 })) { 4205 return true; 4206 } 4207 } 4208 LLVM_DEBUG(dbgs() << "[AAIsDead] Potential copy " << *V 4209 << " is assumed live!\n"); 4210 return false; 4211 }); 4212 } 4213 4214 /// See AbstractAttribute::getAsStr(). 4215 const std::string getAsStr(Attributor *A) const override { 4216 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()); 4217 if (isa_and_nonnull<StoreInst>(I)) 4218 if (isValidState()) 4219 return "assumed-dead-store"; 4220 if (isa_and_nonnull<FenceInst>(I)) 4221 if (isValidState()) 4222 return "assumed-dead-fence"; 4223 return AAIsDeadValueImpl::getAsStr(A); 4224 } 4225 4226 /// See AbstractAttribute::updateImpl(...). 4227 ChangeStatus updateImpl(Attributor &A) override { 4228 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()); 4229 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) { 4230 if (!isDeadStore(A, *SI)) 4231 return indicatePessimisticFixpoint(); 4232 } else if (auto *FI = dyn_cast_or_null<FenceInst>(I)) { 4233 if (!isDeadFence(A, *FI)) 4234 return indicatePessimisticFixpoint(); 4235 } else { 4236 if (!isAssumedSideEffectFree(A, I)) 4237 return indicatePessimisticFixpoint(); 4238 if (!areAllUsesAssumedDead(A, getAssociatedValue())) 4239 return indicatePessimisticFixpoint(); 4240 } 4241 return ChangeStatus::UNCHANGED; 4242 } 4243 4244 bool isRemovableStore() const override { 4245 return isAssumed(IS_REMOVABLE) && isa<StoreInst>(&getAssociatedValue()); 4246 } 4247 4248 /// See AbstractAttribute::manifest(...). 4249 ChangeStatus manifest(Attributor &A) override { 4250 Value &V = getAssociatedValue(); 4251 if (auto *I = dyn_cast<Instruction>(&V)) { 4252 // If we get here we basically know the users are all dead. We check if 4253 // isAssumedSideEffectFree returns true here again because it might not be 4254 // the case and only the users are dead but the instruction (=call) is 4255 // still needed. 4256 if (auto *SI = dyn_cast<StoreInst>(I)) { 4257 SmallSetVector<Instruction *, 8> AssumeOnlyInst; 4258 bool IsDead = isDeadStore(A, *SI, &AssumeOnlyInst); 4259 (void)IsDead; 4260 assert(IsDead && "Store was assumed to be dead!"); 4261 A.deleteAfterManifest(*I); 4262 for (size_t i = 0; i < AssumeOnlyInst.size(); ++i) { 4263 Instruction *AOI = AssumeOnlyInst[i]; 4264 for (auto *Usr : AOI->users()) 4265 AssumeOnlyInst.insert(cast<Instruction>(Usr)); 4266 A.deleteAfterManifest(*AOI); 4267 } 4268 return ChangeStatus::CHANGED; 4269 } 4270 if (auto *FI = dyn_cast<FenceInst>(I)) { 4271 assert(isDeadFence(A, *FI)); 4272 A.deleteAfterManifest(*FI); 4273 return ChangeStatus::CHANGED; 4274 } 4275 if (isAssumedSideEffectFree(A, I) && !isa<InvokeInst>(I)) { 4276 A.deleteAfterManifest(*I); 4277 return ChangeStatus::CHANGED; 4278 } 4279 } 4280 return ChangeStatus::UNCHANGED; 4281 } 4282 4283 /// See AbstractAttribute::trackStatistics() 4284 void trackStatistics() const override { 4285 STATS_DECLTRACK_FLOATING_ATTR(IsDead) 4286 } 4287 4288 private: 4289 // The potential copies of a dead store, used for deletion during manifest. 4290 SmallSetVector<Value *, 4> PotentialCopies; 4291 }; 4292 4293 struct AAIsDeadArgument : public AAIsDeadFloating { 4294 AAIsDeadArgument(const IRPosition &IRP, Attributor &A) 4295 : AAIsDeadFloating(IRP, A) {} 4296 4297 /// See AbstractAttribute::manifest(...). 4298 ChangeStatus manifest(Attributor &A) override { 4299 Argument &Arg = *getAssociatedArgument(); 4300 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {})) 4301 if (A.registerFunctionSignatureRewrite( 4302 Arg, /* ReplacementTypes */ {}, 4303 Attributor::ArgumentReplacementInfo::CalleeRepairCBTy{}, 4304 Attributor::ArgumentReplacementInfo::ACSRepairCBTy{})) { 4305 return ChangeStatus::CHANGED; 4306 } 4307 return ChangeStatus::UNCHANGED; 4308 } 4309 4310 /// See AbstractAttribute::trackStatistics() 4311 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) } 4312 }; 4313 4314 struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl { 4315 AAIsDeadCallSiteArgument(const IRPosition &IRP, Attributor &A) 4316 : AAIsDeadValueImpl(IRP, A) {} 4317 4318 /// See AbstractAttribute::initialize(...). 4319 void initialize(Attributor &A) override { 4320 AAIsDeadValueImpl::initialize(A); 4321 if (isa<UndefValue>(getAssociatedValue())) 4322 indicatePessimisticFixpoint(); 4323 } 4324 4325 /// See AbstractAttribute::updateImpl(...). 4326 ChangeStatus updateImpl(Attributor &A) override { 4327 // TODO: Once we have call site specific value information we can provide 4328 // call site specific liveness information and then it makes 4329 // sense to specialize attributes for call sites arguments instead of 4330 // redirecting requests to the callee argument. 4331 Argument *Arg = getAssociatedArgument(); 4332 if (!Arg) 4333 return indicatePessimisticFixpoint(); 4334 const IRPosition &ArgPos = IRPosition::argument(*Arg); 4335 auto *ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos, DepClassTy::REQUIRED); 4336 if (!ArgAA) 4337 return indicatePessimisticFixpoint(); 4338 return clampStateAndIndicateChange(getState(), ArgAA->getState()); 4339 } 4340 4341 /// See AbstractAttribute::manifest(...). 4342 ChangeStatus manifest(Attributor &A) override { 4343 CallBase &CB = cast<CallBase>(getAnchorValue()); 4344 Use &U = CB.getArgOperandUse(getCallSiteArgNo()); 4345 assert(!isa<UndefValue>(U.get()) && 4346 "Expected undef values to be filtered out!"); 4347 UndefValue &UV = *UndefValue::get(U->getType()); 4348 if (A.changeUseAfterManifest(U, UV)) 4349 return ChangeStatus::CHANGED; 4350 return ChangeStatus::UNCHANGED; 4351 } 4352 4353 /// See AbstractAttribute::trackStatistics() 4354 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) } 4355 }; 4356 4357 struct AAIsDeadCallSiteReturned : public AAIsDeadFloating { 4358 AAIsDeadCallSiteReturned(const IRPosition &IRP, Attributor &A) 4359 : AAIsDeadFloating(IRP, A) {} 4360 4361 /// See AAIsDead::isAssumedDead(). 4362 bool isAssumedDead() const override { 4363 return AAIsDeadFloating::isAssumedDead() && IsAssumedSideEffectFree; 4364 } 4365 4366 /// See AbstractAttribute::initialize(...). 4367 void initialize(Attributor &A) override { 4368 AAIsDeadFloating::initialize(A); 4369 if (isa<UndefValue>(getAssociatedValue())) { 4370 indicatePessimisticFixpoint(); 4371 return; 4372 } 4373 4374 // We track this separately as a secondary state. 4375 IsAssumedSideEffectFree = isAssumedSideEffectFree(A, getCtxI()); 4376 } 4377 4378 /// See AbstractAttribute::updateImpl(...). 4379 ChangeStatus updateImpl(Attributor &A) override { 4380 ChangeStatus Changed = ChangeStatus::UNCHANGED; 4381 if (IsAssumedSideEffectFree && !isAssumedSideEffectFree(A, getCtxI())) { 4382 IsAssumedSideEffectFree = false; 4383 Changed = ChangeStatus::CHANGED; 4384 } 4385 if (!areAllUsesAssumedDead(A, getAssociatedValue())) 4386 return indicatePessimisticFixpoint(); 4387 return Changed; 4388 } 4389 4390 /// See AbstractAttribute::trackStatistics() 4391 void trackStatistics() const override { 4392 if (IsAssumedSideEffectFree) 4393 STATS_DECLTRACK_CSRET_ATTR(IsDead) 4394 else 4395 STATS_DECLTRACK_CSRET_ATTR(UnusedResult) 4396 } 4397 4398 /// See AbstractAttribute::getAsStr(). 4399 const std::string getAsStr(Attributor *A) const override { 4400 return isAssumedDead() 4401 ? "assumed-dead" 4402 : (getAssumed() ? "assumed-dead-users" : "assumed-live"); 4403 } 4404 4405 private: 4406 bool IsAssumedSideEffectFree = true; 4407 }; 4408 4409 struct AAIsDeadReturned : public AAIsDeadValueImpl { 4410 AAIsDeadReturned(const IRPosition &IRP, Attributor &A) 4411 : AAIsDeadValueImpl(IRP, A) {} 4412 4413 /// See AbstractAttribute::updateImpl(...). 4414 ChangeStatus updateImpl(Attributor &A) override { 4415 4416 bool UsedAssumedInformation = false; 4417 A.checkForAllInstructions([](Instruction &) { return true; }, *this, 4418 {Instruction::Ret}, UsedAssumedInformation); 4419 4420 auto PredForCallSite = [&](AbstractCallSite ACS) { 4421 if (ACS.isCallbackCall() || !ACS.getInstruction()) 4422 return false; 4423 return areAllUsesAssumedDead(A, *ACS.getInstruction()); 4424 }; 4425 4426 if (!A.checkForAllCallSites(PredForCallSite, *this, true, 4427 UsedAssumedInformation)) 4428 return indicatePessimisticFixpoint(); 4429 4430 return ChangeStatus::UNCHANGED; 4431 } 4432 4433 /// See AbstractAttribute::manifest(...). 4434 ChangeStatus manifest(Attributor &A) override { 4435 // TODO: Rewrite the signature to return void? 4436 bool AnyChange = false; 4437 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType()); 4438 auto RetInstPred = [&](Instruction &I) { 4439 ReturnInst &RI = cast<ReturnInst>(I); 4440 if (!isa<UndefValue>(RI.getReturnValue())) 4441 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV); 4442 return true; 4443 }; 4444 bool UsedAssumedInformation = false; 4445 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret}, 4446 UsedAssumedInformation); 4447 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 4448 } 4449 4450 /// See AbstractAttribute::trackStatistics() 4451 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) } 4452 }; 4453 4454 struct AAIsDeadFunction : public AAIsDead { 4455 AAIsDeadFunction(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {} 4456 4457 /// See AbstractAttribute::initialize(...). 4458 void initialize(Attributor &A) override { 4459 Function *F = getAnchorScope(); 4460 assert(F && "Did expect an anchor function"); 4461 if (!isAssumedDeadInternalFunction(A)) { 4462 ToBeExploredFrom.insert(&F->getEntryBlock().front()); 4463 assumeLive(A, F->getEntryBlock()); 4464 } 4465 } 4466 4467 bool isAssumedDeadInternalFunction(Attributor &A) { 4468 if (!getAnchorScope()->hasLocalLinkage()) 4469 return false; 4470 bool UsedAssumedInformation = false; 4471 return A.checkForAllCallSites([](AbstractCallSite) { return false; }, *this, 4472 true, UsedAssumedInformation); 4473 } 4474 4475 /// See AbstractAttribute::getAsStr(). 4476 const std::string getAsStr(Attributor *A) const override { 4477 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" + 4478 std::to_string(getAnchorScope()->size()) + "][#TBEP " + 4479 std::to_string(ToBeExploredFrom.size()) + "][#KDE " + 4480 std::to_string(KnownDeadEnds.size()) + "]"; 4481 } 4482 4483 /// See AbstractAttribute::manifest(...). 4484 ChangeStatus manifest(Attributor &A) override { 4485 assert(getState().isValidState() && 4486 "Attempted to manifest an invalid state!"); 4487 4488 ChangeStatus HasChanged = ChangeStatus::UNCHANGED; 4489 Function &F = *getAnchorScope(); 4490 4491 if (AssumedLiveBlocks.empty()) { 4492 A.deleteAfterManifest(F); 4493 return ChangeStatus::CHANGED; 4494 } 4495 4496 // Flag to determine if we can change an invoke to a call assuming the 4497 // callee is nounwind. This is not possible if the personality of the 4498 // function allows to catch asynchronous exceptions. 4499 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F); 4500 4501 KnownDeadEnds.set_union(ToBeExploredFrom); 4502 for (const Instruction *DeadEndI : KnownDeadEnds) { 4503 auto *CB = dyn_cast<CallBase>(DeadEndI); 4504 if (!CB) 4505 continue; 4506 bool IsKnownNoReturn; 4507 bool MayReturn = !AA::hasAssumedIRAttr<Attribute::NoReturn>( 4508 A, this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL, 4509 IsKnownNoReturn); 4510 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB))) 4511 continue; 4512 4513 if (auto *II = dyn_cast<InvokeInst>(DeadEndI)) 4514 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II)); 4515 else 4516 A.changeToUnreachableAfterManifest( 4517 const_cast<Instruction *>(DeadEndI->getNextNode())); 4518 HasChanged = ChangeStatus::CHANGED; 4519 } 4520 4521 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted."); 4522 for (BasicBlock &BB : F) 4523 if (!AssumedLiveBlocks.count(&BB)) { 4524 A.deleteAfterManifest(BB); 4525 ++BUILD_STAT_NAME(AAIsDead, BasicBlock); 4526 HasChanged = ChangeStatus::CHANGED; 4527 } 4528 4529 return HasChanged; 4530 } 4531 4532 /// See AbstractAttribute::updateImpl(...). 4533 ChangeStatus updateImpl(Attributor &A) override; 4534 4535 bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const override { 4536 assert(From->getParent() == getAnchorScope() && 4537 To->getParent() == getAnchorScope() && 4538 "Used AAIsDead of the wrong function"); 4539 return isValidState() && !AssumedLiveEdges.count(std::make_pair(From, To)); 4540 } 4541 4542 /// See AbstractAttribute::trackStatistics() 4543 void trackStatistics() const override {} 4544 4545 /// Returns true if the function is assumed dead. 4546 bool isAssumedDead() const override { return false; } 4547 4548 /// See AAIsDead::isKnownDead(). 4549 bool isKnownDead() const override { return false; } 4550 4551 /// See AAIsDead::isAssumedDead(BasicBlock *). 4552 bool isAssumedDead(const BasicBlock *BB) const override { 4553 assert(BB->getParent() == getAnchorScope() && 4554 "BB must be in the same anchor scope function."); 4555 4556 if (!getAssumed()) 4557 return false; 4558 return !AssumedLiveBlocks.count(BB); 4559 } 4560 4561 /// See AAIsDead::isKnownDead(BasicBlock *). 4562 bool isKnownDead(const BasicBlock *BB) const override { 4563 return getKnown() && isAssumedDead(BB); 4564 } 4565 4566 /// See AAIsDead::isAssumed(Instruction *I). 4567 bool isAssumedDead(const Instruction *I) const override { 4568 assert(I->getParent()->getParent() == getAnchorScope() && 4569 "Instruction must be in the same anchor scope function."); 4570 4571 if (!getAssumed()) 4572 return false; 4573 4574 // If it is not in AssumedLiveBlocks then it for sure dead. 4575 // Otherwise, it can still be after noreturn call in a live block. 4576 if (!AssumedLiveBlocks.count(I->getParent())) 4577 return true; 4578 4579 // If it is not after a liveness barrier it is live. 4580 const Instruction *PrevI = I->getPrevNode(); 4581 while (PrevI) { 4582 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI)) 4583 return true; 4584 PrevI = PrevI->getPrevNode(); 4585 } 4586 return false; 4587 } 4588 4589 /// See AAIsDead::isKnownDead(Instruction *I). 4590 bool isKnownDead(const Instruction *I) const override { 4591 return getKnown() && isAssumedDead(I); 4592 } 4593 4594 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A 4595 /// that internal function called from \p BB should now be looked at. 4596 bool assumeLive(Attributor &A, const BasicBlock &BB) { 4597 if (!AssumedLiveBlocks.insert(&BB).second) 4598 return false; 4599 4600 // We assume that all of BB is (probably) live now and if there are calls to 4601 // internal functions we will assume that those are now live as well. This 4602 // is a performance optimization for blocks with calls to a lot of internal 4603 // functions. It can however cause dead functions to be treated as live. 4604 for (const Instruction &I : BB) 4605 if (const auto *CB = dyn_cast<CallBase>(&I)) 4606 if (auto *F = dyn_cast_if_present<Function>(CB->getCalledOperand())) 4607 if (F->hasLocalLinkage()) 4608 A.markLiveInternalFunction(*F); 4609 return true; 4610 } 4611 4612 /// Collection of instructions that need to be explored again, e.g., we 4613 /// did assume they do not transfer control to (one of their) successors. 4614 SmallSetVector<const Instruction *, 8> ToBeExploredFrom; 4615 4616 /// Collection of instructions that are known to not transfer control. 4617 SmallSetVector<const Instruction *, 8> KnownDeadEnds; 4618 4619 /// Collection of all assumed live edges 4620 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> AssumedLiveEdges; 4621 4622 /// Collection of all assumed live BasicBlocks. 4623 DenseSet<const BasicBlock *> AssumedLiveBlocks; 4624 }; 4625 4626 static bool 4627 identifyAliveSuccessors(Attributor &A, const CallBase &CB, 4628 AbstractAttribute &AA, 4629 SmallVectorImpl<const Instruction *> &AliveSuccessors) { 4630 const IRPosition &IPos = IRPosition::callsite_function(CB); 4631 4632 bool IsKnownNoReturn; 4633 if (AA::hasAssumedIRAttr<Attribute::NoReturn>( 4634 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoReturn)) 4635 return !IsKnownNoReturn; 4636 if (CB.isTerminator()) 4637 AliveSuccessors.push_back(&CB.getSuccessor(0)->front()); 4638 else 4639 AliveSuccessors.push_back(CB.getNextNode()); 4640 return false; 4641 } 4642 4643 static bool 4644 identifyAliveSuccessors(Attributor &A, const InvokeInst &II, 4645 AbstractAttribute &AA, 4646 SmallVectorImpl<const Instruction *> &AliveSuccessors) { 4647 bool UsedAssumedInformation = 4648 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors); 4649 4650 // First, determine if we can change an invoke to a call assuming the 4651 // callee is nounwind. This is not possible if the personality of the 4652 // function allows to catch asynchronous exceptions. 4653 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) { 4654 AliveSuccessors.push_back(&II.getUnwindDest()->front()); 4655 } else { 4656 const IRPosition &IPos = IRPosition::callsite_function(II); 4657 4658 bool IsKnownNoUnwind; 4659 if (AA::hasAssumedIRAttr<Attribute::NoUnwind>( 4660 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) { 4661 UsedAssumedInformation |= !IsKnownNoUnwind; 4662 } else { 4663 AliveSuccessors.push_back(&II.getUnwindDest()->front()); 4664 } 4665 } 4666 return UsedAssumedInformation; 4667 } 4668 4669 static bool 4670 identifyAliveSuccessors(Attributor &A, const BranchInst &BI, 4671 AbstractAttribute &AA, 4672 SmallVectorImpl<const Instruction *> &AliveSuccessors) { 4673 bool UsedAssumedInformation = false; 4674 if (BI.getNumSuccessors() == 1) { 4675 AliveSuccessors.push_back(&BI.getSuccessor(0)->front()); 4676 } else { 4677 std::optional<Constant *> C = 4678 A.getAssumedConstant(*BI.getCondition(), AA, UsedAssumedInformation); 4679 if (!C || isa_and_nonnull<UndefValue>(*C)) { 4680 // No value yet, assume both edges are dead. 4681 } else if (isa_and_nonnull<ConstantInt>(*C)) { 4682 const BasicBlock *SuccBB = 4683 BI.getSuccessor(1 - cast<ConstantInt>(*C)->getValue().getZExtValue()); 4684 AliveSuccessors.push_back(&SuccBB->front()); 4685 } else { 4686 AliveSuccessors.push_back(&BI.getSuccessor(0)->front()); 4687 AliveSuccessors.push_back(&BI.getSuccessor(1)->front()); 4688 UsedAssumedInformation = false; 4689 } 4690 } 4691 return UsedAssumedInformation; 4692 } 4693 4694 static bool 4695 identifyAliveSuccessors(Attributor &A, const SwitchInst &SI, 4696 AbstractAttribute &AA, 4697 SmallVectorImpl<const Instruction *> &AliveSuccessors) { 4698 bool UsedAssumedInformation = false; 4699 std::optional<Constant *> C = 4700 A.getAssumedConstant(*SI.getCondition(), AA, UsedAssumedInformation); 4701 if (!C || isa_and_nonnull<UndefValue>(*C)) { 4702 // No value yet, assume all edges are dead. 4703 } else if (isa_and_nonnull<ConstantInt>(*C)) { 4704 for (const auto &CaseIt : SI.cases()) { 4705 if (CaseIt.getCaseValue() == *C) { 4706 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front()); 4707 return UsedAssumedInformation; 4708 } 4709 } 4710 AliveSuccessors.push_back(&SI.getDefaultDest()->front()); 4711 return UsedAssumedInformation; 4712 } else { 4713 for (const BasicBlock *SuccBB : successors(SI.getParent())) 4714 AliveSuccessors.push_back(&SuccBB->front()); 4715 } 4716 return UsedAssumedInformation; 4717 } 4718 4719 ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) { 4720 ChangeStatus Change = ChangeStatus::UNCHANGED; 4721 4722 if (AssumedLiveBlocks.empty()) { 4723 if (isAssumedDeadInternalFunction(A)) 4724 return ChangeStatus::UNCHANGED; 4725 4726 Function *F = getAnchorScope(); 4727 ToBeExploredFrom.insert(&F->getEntryBlock().front()); 4728 assumeLive(A, F->getEntryBlock()); 4729 Change = ChangeStatus::CHANGED; 4730 } 4731 4732 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/" 4733 << getAnchorScope()->size() << "] BBs and " 4734 << ToBeExploredFrom.size() << " exploration points and " 4735 << KnownDeadEnds.size() << " known dead ends\n"); 4736 4737 // Copy and clear the list of instructions we need to explore from. It is 4738 // refilled with instructions the next update has to look at. 4739 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(), 4740 ToBeExploredFrom.end()); 4741 decltype(ToBeExploredFrom) NewToBeExploredFrom; 4742 4743 SmallVector<const Instruction *, 8> AliveSuccessors; 4744 while (!Worklist.empty()) { 4745 const Instruction *I = Worklist.pop_back_val(); 4746 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n"); 4747 4748 // Fast forward for uninteresting instructions. We could look for UB here 4749 // though. 4750 while (!I->isTerminator() && !isa<CallBase>(I)) 4751 I = I->getNextNode(); 4752 4753 AliveSuccessors.clear(); 4754 4755 bool UsedAssumedInformation = false; 4756 switch (I->getOpcode()) { 4757 // TODO: look for (assumed) UB to backwards propagate "deadness". 4758 default: 4759 assert(I->isTerminator() && 4760 "Expected non-terminators to be handled already!"); 4761 for (const BasicBlock *SuccBB : successors(I->getParent())) 4762 AliveSuccessors.push_back(&SuccBB->front()); 4763 break; 4764 case Instruction::Call: 4765 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I), 4766 *this, AliveSuccessors); 4767 break; 4768 case Instruction::Invoke: 4769 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I), 4770 *this, AliveSuccessors); 4771 break; 4772 case Instruction::Br: 4773 UsedAssumedInformation = identifyAliveSuccessors(A, cast<BranchInst>(*I), 4774 *this, AliveSuccessors); 4775 break; 4776 case Instruction::Switch: 4777 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I), 4778 *this, AliveSuccessors); 4779 break; 4780 } 4781 4782 if (UsedAssumedInformation) { 4783 NewToBeExploredFrom.insert(I); 4784 } else if (AliveSuccessors.empty() || 4785 (I->isTerminator() && 4786 AliveSuccessors.size() < I->getNumSuccessors())) { 4787 if (KnownDeadEnds.insert(I)) 4788 Change = ChangeStatus::CHANGED; 4789 } 4790 4791 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: " 4792 << AliveSuccessors.size() << " UsedAssumedInformation: " 4793 << UsedAssumedInformation << "\n"); 4794 4795 for (const Instruction *AliveSuccessor : AliveSuccessors) { 4796 if (!I->isTerminator()) { 4797 assert(AliveSuccessors.size() == 1 && 4798 "Non-terminator expected to have a single successor!"); 4799 Worklist.push_back(AliveSuccessor); 4800 } else { 4801 // record the assumed live edge 4802 auto Edge = std::make_pair(I->getParent(), AliveSuccessor->getParent()); 4803 if (AssumedLiveEdges.insert(Edge).second) 4804 Change = ChangeStatus::CHANGED; 4805 if (assumeLive(A, *AliveSuccessor->getParent())) 4806 Worklist.push_back(AliveSuccessor); 4807 } 4808 } 4809 } 4810 4811 // Check if the content of ToBeExploredFrom changed, ignore the order. 4812 if (NewToBeExploredFrom.size() != ToBeExploredFrom.size() || 4813 llvm::any_of(NewToBeExploredFrom, [&](const Instruction *I) { 4814 return !ToBeExploredFrom.count(I); 4815 })) { 4816 Change = ChangeStatus::CHANGED; 4817 ToBeExploredFrom = std::move(NewToBeExploredFrom); 4818 } 4819 4820 // If we know everything is live there is no need to query for liveness. 4821 // Instead, indicating a pessimistic fixpoint will cause the state to be 4822 // "invalid" and all queries to be answered conservatively without lookups. 4823 // To be in this state we have to (1) finished the exploration and (3) not 4824 // discovered any non-trivial dead end and (2) not ruled unreachable code 4825 // dead. 4826 if (ToBeExploredFrom.empty() && 4827 getAnchorScope()->size() == AssumedLiveBlocks.size() && 4828 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) { 4829 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0; 4830 })) 4831 return indicatePessimisticFixpoint(); 4832 return Change; 4833 } 4834 4835 /// Liveness information for a call sites. 4836 struct AAIsDeadCallSite final : AAIsDeadFunction { 4837 AAIsDeadCallSite(const IRPosition &IRP, Attributor &A) 4838 : AAIsDeadFunction(IRP, A) {} 4839 4840 /// See AbstractAttribute::initialize(...). 4841 void initialize(Attributor &A) override { 4842 // TODO: Once we have call site specific value information we can provide 4843 // call site specific liveness information and then it makes 4844 // sense to specialize attributes for call sites instead of 4845 // redirecting requests to the callee. 4846 llvm_unreachable("Abstract attributes for liveness are not " 4847 "supported for call sites yet!"); 4848 } 4849 4850 /// See AbstractAttribute::updateImpl(...). 4851 ChangeStatus updateImpl(Attributor &A) override { 4852 return indicatePessimisticFixpoint(); 4853 } 4854 4855 /// See AbstractAttribute::trackStatistics() 4856 void trackStatistics() const override {} 4857 }; 4858 } // namespace 4859 4860 /// -------------------- Dereferenceable Argument Attribute -------------------- 4861 4862 namespace { 4863 struct AADereferenceableImpl : AADereferenceable { 4864 AADereferenceableImpl(const IRPosition &IRP, Attributor &A) 4865 : AADereferenceable(IRP, A) {} 4866 using StateType = DerefState; 4867 4868 /// See AbstractAttribute::initialize(...). 4869 void initialize(Attributor &A) override { 4870 Value &V = *getAssociatedValue().stripPointerCasts(); 4871 SmallVector<Attribute, 4> Attrs; 4872 A.getAttrs(getIRPosition(), 4873 {Attribute::Dereferenceable, Attribute::DereferenceableOrNull}, 4874 Attrs, /* IgnoreSubsumingPositions */ false); 4875 for (const Attribute &Attr : Attrs) 4876 takeKnownDerefBytesMaximum(Attr.getValueAsInt()); 4877 4878 // Ensure we initialize the non-null AA (if necessary). 4879 bool IsKnownNonNull; 4880 AA::hasAssumedIRAttr<Attribute::NonNull>( 4881 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNonNull); 4882 4883 bool CanBeNull, CanBeFreed; 4884 takeKnownDerefBytesMaximum(V.getPointerDereferenceableBytes( 4885 A.getDataLayout(), CanBeNull, CanBeFreed)); 4886 4887 if (Instruction *CtxI = getCtxI()) 4888 followUsesInMBEC(*this, A, getState(), *CtxI); 4889 } 4890 4891 /// See AbstractAttribute::getState() 4892 /// { 4893 StateType &getState() override { return *this; } 4894 const StateType &getState() const override { return *this; } 4895 /// } 4896 4897 /// Helper function for collecting accessed bytes in must-be-executed-context 4898 void addAccessedBytesForUse(Attributor &A, const Use *U, const Instruction *I, 4899 DerefState &State) { 4900 const Value *UseV = U->get(); 4901 if (!UseV->getType()->isPointerTy()) 4902 return; 4903 4904 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I); 4905 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile()) 4906 return; 4907 4908 int64_t Offset; 4909 const Value *Base = GetPointerBaseWithConstantOffset( 4910 Loc->Ptr, Offset, A.getDataLayout(), /*AllowNonInbounds*/ true); 4911 if (Base && Base == &getAssociatedValue()) 4912 State.addAccessedBytes(Offset, Loc->Size.getValue()); 4913 } 4914 4915 /// See followUsesInMBEC 4916 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I, 4917 AADereferenceable::StateType &State) { 4918 bool IsNonNull = false; 4919 bool TrackUse = false; 4920 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse( 4921 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse); 4922 LLVM_DEBUG(dbgs() << "[AADereferenceable] Deref bytes: " << DerefBytes 4923 << " for instruction " << *I << "\n"); 4924 4925 addAccessedBytesForUse(A, U, I, State); 4926 State.takeKnownDerefBytesMaximum(DerefBytes); 4927 return TrackUse; 4928 } 4929 4930 /// See AbstractAttribute::manifest(...). 4931 ChangeStatus manifest(Attributor &A) override { 4932 ChangeStatus Change = AADereferenceable::manifest(A); 4933 bool IsKnownNonNull; 4934 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>( 4935 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull); 4936 if (IsAssumedNonNull && 4937 A.hasAttr(getIRPosition(), Attribute::DereferenceableOrNull)) { 4938 A.removeAttrs(getIRPosition(), {Attribute::DereferenceableOrNull}); 4939 return ChangeStatus::CHANGED; 4940 } 4941 return Change; 4942 } 4943 4944 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, 4945 SmallVectorImpl<Attribute> &Attrs) const override { 4946 // TODO: Add *_globally support 4947 bool IsKnownNonNull; 4948 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>( 4949 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull); 4950 if (IsAssumedNonNull) 4951 Attrs.emplace_back(Attribute::getWithDereferenceableBytes( 4952 Ctx, getAssumedDereferenceableBytes())); 4953 else 4954 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes( 4955 Ctx, getAssumedDereferenceableBytes())); 4956 } 4957 4958 /// See AbstractAttribute::getAsStr(). 4959 const std::string getAsStr(Attributor *A) const override { 4960 if (!getAssumedDereferenceableBytes()) 4961 return "unknown-dereferenceable"; 4962 bool IsKnownNonNull; 4963 bool IsAssumedNonNull = false; 4964 if (A) 4965 IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>( 4966 *A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull); 4967 return std::string("dereferenceable") + 4968 (IsAssumedNonNull ? "" : "_or_null") + 4969 (isAssumedGlobal() ? "_globally" : "") + "<" + 4970 std::to_string(getKnownDereferenceableBytes()) + "-" + 4971 std::to_string(getAssumedDereferenceableBytes()) + ">" + 4972 (!A ? " [non-null is unknown]" : ""); 4973 } 4974 }; 4975 4976 /// Dereferenceable attribute for a floating value. 4977 struct AADereferenceableFloating : AADereferenceableImpl { 4978 AADereferenceableFloating(const IRPosition &IRP, Attributor &A) 4979 : AADereferenceableImpl(IRP, A) {} 4980 4981 /// See AbstractAttribute::updateImpl(...). 4982 ChangeStatus updateImpl(Attributor &A) override { 4983 bool Stripped; 4984 bool UsedAssumedInformation = false; 4985 SmallVector<AA::ValueAndContext> Values; 4986 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values, 4987 AA::AnyScope, UsedAssumedInformation)) { 4988 Values.push_back({getAssociatedValue(), getCtxI()}); 4989 Stripped = false; 4990 } else { 4991 Stripped = Values.size() != 1 || 4992 Values.front().getValue() != &getAssociatedValue(); 4993 } 4994 4995 const DataLayout &DL = A.getDataLayout(); 4996 DerefState T; 4997 4998 auto VisitValueCB = [&](const Value &V) -> bool { 4999 unsigned IdxWidth = 5000 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace()); 5001 APInt Offset(IdxWidth, 0); 5002 const Value *Base = stripAndAccumulateOffsets( 5003 A, *this, &V, DL, Offset, /* GetMinOffset */ false, 5004 /* AllowNonInbounds */ true); 5005 5006 const auto *AA = A.getAAFor<AADereferenceable>( 5007 *this, IRPosition::value(*Base), DepClassTy::REQUIRED); 5008 int64_t DerefBytes = 0; 5009 if (!AA || (!Stripped && this == AA)) { 5010 // Use IR information if we did not strip anything. 5011 // TODO: track globally. 5012 bool CanBeNull, CanBeFreed; 5013 DerefBytes = 5014 Base->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed); 5015 T.GlobalState.indicatePessimisticFixpoint(); 5016 } else { 5017 const DerefState &DS = AA->getState(); 5018 DerefBytes = DS.DerefBytesState.getAssumed(); 5019 T.GlobalState &= DS.GlobalState; 5020 } 5021 5022 // For now we do not try to "increase" dereferenceability due to negative 5023 // indices as we first have to come up with code to deal with loops and 5024 // for overflows of the dereferenceable bytes. 5025 int64_t OffsetSExt = Offset.getSExtValue(); 5026 if (OffsetSExt < 0) 5027 OffsetSExt = 0; 5028 5029 T.takeAssumedDerefBytesMinimum( 5030 std::max(int64_t(0), DerefBytes - OffsetSExt)); 5031 5032 if (this == AA) { 5033 if (!Stripped) { 5034 // If nothing was stripped IR information is all we got. 5035 T.takeKnownDerefBytesMaximum( 5036 std::max(int64_t(0), DerefBytes - OffsetSExt)); 5037 T.indicatePessimisticFixpoint(); 5038 } else if (OffsetSExt > 0) { 5039 // If something was stripped but there is circular reasoning we look 5040 // for the offset. If it is positive we basically decrease the 5041 // dereferenceable bytes in a circular loop now, which will simply 5042 // drive them down to the known value in a very slow way which we 5043 // can accelerate. 5044 T.indicatePessimisticFixpoint(); 5045 } 5046 } 5047 5048 return T.isValidState(); 5049 }; 5050 5051 for (const auto &VAC : Values) 5052 if (!VisitValueCB(*VAC.getValue())) 5053 return indicatePessimisticFixpoint(); 5054 5055 return clampStateAndIndicateChange(getState(), T); 5056 } 5057 5058 /// See AbstractAttribute::trackStatistics() 5059 void trackStatistics() const override { 5060 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable) 5061 } 5062 }; 5063 5064 /// Dereferenceable attribute for a return value. 5065 struct AADereferenceableReturned final 5066 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> { 5067 using Base = 5068 AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>; 5069 AADereferenceableReturned(const IRPosition &IRP, Attributor &A) 5070 : Base(IRP, A) {} 5071 5072 /// See AbstractAttribute::trackStatistics() 5073 void trackStatistics() const override { 5074 STATS_DECLTRACK_FNRET_ATTR(dereferenceable) 5075 } 5076 }; 5077 5078 /// Dereferenceable attribute for an argument 5079 struct AADereferenceableArgument final 5080 : AAArgumentFromCallSiteArguments<AADereferenceable, 5081 AADereferenceableImpl> { 5082 using Base = 5083 AAArgumentFromCallSiteArguments<AADereferenceable, AADereferenceableImpl>; 5084 AADereferenceableArgument(const IRPosition &IRP, Attributor &A) 5085 : Base(IRP, A) {} 5086 5087 /// See AbstractAttribute::trackStatistics() 5088 void trackStatistics() const override { 5089 STATS_DECLTRACK_ARG_ATTR(dereferenceable) 5090 } 5091 }; 5092 5093 /// Dereferenceable attribute for a call site argument. 5094 struct AADereferenceableCallSiteArgument final : AADereferenceableFloating { 5095 AADereferenceableCallSiteArgument(const IRPosition &IRP, Attributor &A) 5096 : AADereferenceableFloating(IRP, A) {} 5097 5098 /// See AbstractAttribute::trackStatistics() 5099 void trackStatistics() const override { 5100 STATS_DECLTRACK_CSARG_ATTR(dereferenceable) 5101 } 5102 }; 5103 5104 /// Dereferenceable attribute deduction for a call site return value. 5105 struct AADereferenceableCallSiteReturned final 5106 : AACallSiteReturnedFromReturned<AADereferenceable, AADereferenceableImpl> { 5107 using Base = 5108 AACallSiteReturnedFromReturned<AADereferenceable, AADereferenceableImpl>; 5109 AADereferenceableCallSiteReturned(const IRPosition &IRP, Attributor &A) 5110 : Base(IRP, A) {} 5111 5112 /// See AbstractAttribute::trackStatistics() 5113 void trackStatistics() const override { 5114 STATS_DECLTRACK_CS_ATTR(dereferenceable); 5115 } 5116 }; 5117 } // namespace 5118 5119 // ------------------------ Align Argument Attribute ------------------------ 5120 5121 namespace { 5122 static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA, 5123 Value &AssociatedValue, const Use *U, 5124 const Instruction *I, bool &TrackUse) { 5125 // We need to follow common pointer manipulation uses to the accesses they 5126 // feed into. 5127 if (isa<CastInst>(I)) { 5128 // Follow all but ptr2int casts. 5129 TrackUse = !isa<PtrToIntInst>(I); 5130 return 0; 5131 } 5132 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) { 5133 if (GEP->hasAllConstantIndices()) 5134 TrackUse = true; 5135 return 0; 5136 } 5137 5138 MaybeAlign MA; 5139 if (const auto *CB = dyn_cast<CallBase>(I)) { 5140 if (CB->isBundleOperand(U) || CB->isCallee(U)) 5141 return 0; 5142 5143 unsigned ArgNo = CB->getArgOperandNo(U); 5144 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo); 5145 // As long as we only use known information there is no need to track 5146 // dependences here. 5147 auto *AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP, DepClassTy::NONE); 5148 if (AlignAA) 5149 MA = MaybeAlign(AlignAA->getKnownAlign()); 5150 } 5151 5152 const DataLayout &DL = A.getDataLayout(); 5153 const Value *UseV = U->get(); 5154 if (auto *SI = dyn_cast<StoreInst>(I)) { 5155 if (SI->getPointerOperand() == UseV) 5156 MA = SI->getAlign(); 5157 } else if (auto *LI = dyn_cast<LoadInst>(I)) { 5158 if (LI->getPointerOperand() == UseV) 5159 MA = LI->getAlign(); 5160 } 5161 5162 if (!MA || *MA <= QueryingAA.getKnownAlign()) 5163 return 0; 5164 5165 unsigned Alignment = MA->value(); 5166 int64_t Offset; 5167 5168 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) { 5169 if (Base == &AssociatedValue) { 5170 // BasePointerAddr + Offset = Alignment * Q for some integer Q. 5171 // So we can say that the maximum power of two which is a divisor of 5172 // gcd(Offset, Alignment) is an alignment. 5173 5174 uint32_t gcd = std::gcd(uint32_t(abs((int32_t)Offset)), Alignment); 5175 Alignment = llvm::bit_floor(gcd); 5176 } 5177 } 5178 5179 return Alignment; 5180 } 5181 5182 struct AAAlignImpl : AAAlign { 5183 AAAlignImpl(const IRPosition &IRP, Attributor &A) : AAAlign(IRP, A) {} 5184 5185 /// See AbstractAttribute::initialize(...). 5186 void initialize(Attributor &A) override { 5187 SmallVector<Attribute, 4> Attrs; 5188 A.getAttrs(getIRPosition(), {Attribute::Alignment}, Attrs); 5189 for (const Attribute &Attr : Attrs) 5190 takeKnownMaximum(Attr.getValueAsInt()); 5191 5192 Value &V = *getAssociatedValue().stripPointerCasts(); 5193 takeKnownMaximum(V.getPointerAlignment(A.getDataLayout()).value()); 5194 5195 if (Instruction *CtxI = getCtxI()) 5196 followUsesInMBEC(*this, A, getState(), *CtxI); 5197 } 5198 5199 /// See AbstractAttribute::manifest(...). 5200 ChangeStatus manifest(Attributor &A) override { 5201 ChangeStatus LoadStoreChanged = ChangeStatus::UNCHANGED; 5202 5203 // Check for users that allow alignment annotations. 5204 Value &AssociatedValue = getAssociatedValue(); 5205 for (const Use &U : AssociatedValue.uses()) { 5206 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) { 5207 if (SI->getPointerOperand() == &AssociatedValue) 5208 if (SI->getAlign() < getAssumedAlign()) { 5209 STATS_DECLTRACK(AAAlign, Store, 5210 "Number of times alignment added to a store"); 5211 SI->setAlignment(getAssumedAlign()); 5212 LoadStoreChanged = ChangeStatus::CHANGED; 5213 } 5214 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) { 5215 if (LI->getPointerOperand() == &AssociatedValue) 5216 if (LI->getAlign() < getAssumedAlign()) { 5217 LI->setAlignment(getAssumedAlign()); 5218 STATS_DECLTRACK(AAAlign, Load, 5219 "Number of times alignment added to a load"); 5220 LoadStoreChanged = ChangeStatus::CHANGED; 5221 } 5222 } 5223 } 5224 5225 ChangeStatus Changed = AAAlign::manifest(A); 5226 5227 Align InheritAlign = 5228 getAssociatedValue().getPointerAlignment(A.getDataLayout()); 5229 if (InheritAlign >= getAssumedAlign()) 5230 return LoadStoreChanged; 5231 return Changed | LoadStoreChanged; 5232 } 5233 5234 // TODO: Provide a helper to determine the implied ABI alignment and check in 5235 // the existing manifest method and a new one for AAAlignImpl that value 5236 // to avoid making the alignment explicit if it did not improve. 5237 5238 /// See AbstractAttribute::getDeducedAttributes 5239 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, 5240 SmallVectorImpl<Attribute> &Attrs) const override { 5241 if (getAssumedAlign() > 1) 5242 Attrs.emplace_back( 5243 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign()))); 5244 } 5245 5246 /// See followUsesInMBEC 5247 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I, 5248 AAAlign::StateType &State) { 5249 bool TrackUse = false; 5250 5251 unsigned int KnownAlign = 5252 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse); 5253 State.takeKnownMaximum(KnownAlign); 5254 5255 return TrackUse; 5256 } 5257 5258 /// See AbstractAttribute::getAsStr(). 5259 const std::string getAsStr(Attributor *A) const override { 5260 return "align<" + std::to_string(getKnownAlign().value()) + "-" + 5261 std::to_string(getAssumedAlign().value()) + ">"; 5262 } 5263 }; 5264 5265 /// Align attribute for a floating value. 5266 struct AAAlignFloating : AAAlignImpl { 5267 AAAlignFloating(const IRPosition &IRP, Attributor &A) : AAAlignImpl(IRP, A) {} 5268 5269 /// See AbstractAttribute::updateImpl(...). 5270 ChangeStatus updateImpl(Attributor &A) override { 5271 const DataLayout &DL = A.getDataLayout(); 5272 5273 bool Stripped; 5274 bool UsedAssumedInformation = false; 5275 SmallVector<AA::ValueAndContext> Values; 5276 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values, 5277 AA::AnyScope, UsedAssumedInformation)) { 5278 Values.push_back({getAssociatedValue(), getCtxI()}); 5279 Stripped = false; 5280 } else { 5281 Stripped = Values.size() != 1 || 5282 Values.front().getValue() != &getAssociatedValue(); 5283 } 5284 5285 StateType T; 5286 auto VisitValueCB = [&](Value &V) -> bool { 5287 if (isa<UndefValue>(V) || isa<ConstantPointerNull>(V)) 5288 return true; 5289 const auto *AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V), 5290 DepClassTy::REQUIRED); 5291 if (!AA || (!Stripped && this == AA)) { 5292 int64_t Offset; 5293 unsigned Alignment = 1; 5294 if (const Value *Base = 5295 GetPointerBaseWithConstantOffset(&V, Offset, DL)) { 5296 // TODO: Use AAAlign for the base too. 5297 Align PA = Base->getPointerAlignment(DL); 5298 // BasePointerAddr + Offset = Alignment * Q for some integer Q. 5299 // So we can say that the maximum power of two which is a divisor of 5300 // gcd(Offset, Alignment) is an alignment. 5301 5302 uint32_t gcd = 5303 std::gcd(uint32_t(abs((int32_t)Offset)), uint32_t(PA.value())); 5304 Alignment = llvm::bit_floor(gcd); 5305 } else { 5306 Alignment = V.getPointerAlignment(DL).value(); 5307 } 5308 // Use only IR information if we did not strip anything. 5309 T.takeKnownMaximum(Alignment); 5310 T.indicatePessimisticFixpoint(); 5311 } else { 5312 // Use abstract attribute information. 5313 const AAAlign::StateType &DS = AA->getState(); 5314 T ^= DS; 5315 } 5316 return T.isValidState(); 5317 }; 5318 5319 for (const auto &VAC : Values) { 5320 if (!VisitValueCB(*VAC.getValue())) 5321 return indicatePessimisticFixpoint(); 5322 } 5323 5324 // TODO: If we know we visited all incoming values, thus no are assumed 5325 // dead, we can take the known information from the state T. 5326 return clampStateAndIndicateChange(getState(), T); 5327 } 5328 5329 /// See AbstractAttribute::trackStatistics() 5330 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) } 5331 }; 5332 5333 /// Align attribute for function return value. 5334 struct AAAlignReturned final 5335 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> { 5336 using Base = AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>; 5337 AAAlignReturned(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {} 5338 5339 /// See AbstractAttribute::trackStatistics() 5340 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) } 5341 }; 5342 5343 /// Align attribute for function argument. 5344 struct AAAlignArgument final 5345 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> { 5346 using Base = AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>; 5347 AAAlignArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {} 5348 5349 /// See AbstractAttribute::manifest(...). 5350 ChangeStatus manifest(Attributor &A) override { 5351 // If the associated argument is involved in a must-tail call we give up 5352 // because we would need to keep the argument alignments of caller and 5353 // callee in-sync. Just does not seem worth the trouble right now. 5354 if (A.getInfoCache().isInvolvedInMustTailCall(*getAssociatedArgument())) 5355 return ChangeStatus::UNCHANGED; 5356 return Base::manifest(A); 5357 } 5358 5359 /// See AbstractAttribute::trackStatistics() 5360 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) } 5361 }; 5362 5363 struct AAAlignCallSiteArgument final : AAAlignFloating { 5364 AAAlignCallSiteArgument(const IRPosition &IRP, Attributor &A) 5365 : AAAlignFloating(IRP, A) {} 5366 5367 /// See AbstractAttribute::manifest(...). 5368 ChangeStatus manifest(Attributor &A) override { 5369 // If the associated argument is involved in a must-tail call we give up 5370 // because we would need to keep the argument alignments of caller and 5371 // callee in-sync. Just does not seem worth the trouble right now. 5372 if (Argument *Arg = getAssociatedArgument()) 5373 if (A.getInfoCache().isInvolvedInMustTailCall(*Arg)) 5374 return ChangeStatus::UNCHANGED; 5375 ChangeStatus Changed = AAAlignImpl::manifest(A); 5376 Align InheritAlign = 5377 getAssociatedValue().getPointerAlignment(A.getDataLayout()); 5378 if (InheritAlign >= getAssumedAlign()) 5379 Changed = ChangeStatus::UNCHANGED; 5380 return Changed; 5381 } 5382 5383 /// See AbstractAttribute::updateImpl(Attributor &A). 5384 ChangeStatus updateImpl(Attributor &A) override { 5385 ChangeStatus Changed = AAAlignFloating::updateImpl(A); 5386 if (Argument *Arg = getAssociatedArgument()) { 5387 // We only take known information from the argument 5388 // so we do not need to track a dependence. 5389 const auto *ArgAlignAA = A.getAAFor<AAAlign>( 5390 *this, IRPosition::argument(*Arg), DepClassTy::NONE); 5391 if (ArgAlignAA) 5392 takeKnownMaximum(ArgAlignAA->getKnownAlign().value()); 5393 } 5394 return Changed; 5395 } 5396 5397 /// See AbstractAttribute::trackStatistics() 5398 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) } 5399 }; 5400 5401 /// Align attribute deduction for a call site return value. 5402 struct AAAlignCallSiteReturned final 5403 : AACallSiteReturnedFromReturned<AAAlign, AAAlignImpl> { 5404 using Base = AACallSiteReturnedFromReturned<AAAlign, AAAlignImpl>; 5405 AAAlignCallSiteReturned(const IRPosition &IRP, Attributor &A) 5406 : Base(IRP, A) {} 5407 5408 /// See AbstractAttribute::trackStatistics() 5409 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); } 5410 }; 5411 } // namespace 5412 5413 /// ------------------ Function No-Return Attribute ---------------------------- 5414 namespace { 5415 struct AANoReturnImpl : public AANoReturn { 5416 AANoReturnImpl(const IRPosition &IRP, Attributor &A) : AANoReturn(IRP, A) {} 5417 5418 /// See AbstractAttribute::initialize(...). 5419 void initialize(Attributor &A) override { 5420 bool IsKnown; 5421 assert(!AA::hasAssumedIRAttr<Attribute::NoReturn>( 5422 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown)); 5423 (void)IsKnown; 5424 } 5425 5426 /// See AbstractAttribute::getAsStr(). 5427 const std::string getAsStr(Attributor *A) const override { 5428 return getAssumed() ? "noreturn" : "may-return"; 5429 } 5430 5431 /// See AbstractAttribute::updateImpl(Attributor &A). 5432 ChangeStatus updateImpl(Attributor &A) override { 5433 auto CheckForNoReturn = [](Instruction &) { return false; }; 5434 bool UsedAssumedInformation = false; 5435 if (!A.checkForAllInstructions(CheckForNoReturn, *this, 5436 {(unsigned)Instruction::Ret}, 5437 UsedAssumedInformation)) 5438 return indicatePessimisticFixpoint(); 5439 return ChangeStatus::UNCHANGED; 5440 } 5441 }; 5442 5443 struct AANoReturnFunction final : AANoReturnImpl { 5444 AANoReturnFunction(const IRPosition &IRP, Attributor &A) 5445 : AANoReturnImpl(IRP, A) {} 5446 5447 /// See AbstractAttribute::trackStatistics() 5448 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) } 5449 }; 5450 5451 /// NoReturn attribute deduction for a call sites. 5452 struct AANoReturnCallSite final : AANoReturnImpl { 5453 AANoReturnCallSite(const IRPosition &IRP, Attributor &A) 5454 : AANoReturnImpl(IRP, A) {} 5455 5456 /// See AbstractAttribute::updateImpl(...). 5457 ChangeStatus updateImpl(Attributor &A) override { 5458 // TODO: Once we have call site specific value information we can provide 5459 // call site specific liveness information and then it makes 5460 // sense to specialize attributes for call sites arguments instead of 5461 // redirecting requests to the callee argument. 5462 Function *F = getAssociatedFunction(); 5463 const IRPosition &FnPos = IRPosition::function(*F); 5464 bool IsKnownNoReturn; 5465 if (!AA::hasAssumedIRAttr<Attribute::NoReturn>( 5466 A, this, FnPos, DepClassTy::REQUIRED, IsKnownNoReturn)) 5467 return indicatePessimisticFixpoint(); 5468 return ChangeStatus::UNCHANGED; 5469 } 5470 5471 /// See AbstractAttribute::trackStatistics() 5472 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); } 5473 }; 5474 } // namespace 5475 5476 /// ----------------------- Instance Info --------------------------------- 5477 5478 namespace { 5479 /// A class to hold the state of for no-capture attributes. 5480 struct AAInstanceInfoImpl : public AAInstanceInfo { 5481 AAInstanceInfoImpl(const IRPosition &IRP, Attributor &A) 5482 : AAInstanceInfo(IRP, A) {} 5483 5484 /// See AbstractAttribute::initialize(...). 5485 void initialize(Attributor &A) override { 5486 Value &V = getAssociatedValue(); 5487 if (auto *C = dyn_cast<Constant>(&V)) { 5488 if (C->isThreadDependent()) 5489 indicatePessimisticFixpoint(); 5490 else 5491 indicateOptimisticFixpoint(); 5492 return; 5493 } 5494 if (auto *CB = dyn_cast<CallBase>(&V)) 5495 if (CB->arg_size() == 0 && !CB->mayHaveSideEffects() && 5496 !CB->mayReadFromMemory()) { 5497 indicateOptimisticFixpoint(); 5498 return; 5499 } 5500 if (auto *I = dyn_cast<Instruction>(&V)) { 5501 const auto *CI = 5502 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>( 5503 *I->getFunction()); 5504 if (mayBeInCycle(CI, I, /* HeaderOnly */ false)) { 5505 indicatePessimisticFixpoint(); 5506 return; 5507 } 5508 } 5509 } 5510 5511 /// See AbstractAttribute::updateImpl(...). 5512 ChangeStatus updateImpl(Attributor &A) override { 5513 ChangeStatus Changed = ChangeStatus::UNCHANGED; 5514 5515 Value &V = getAssociatedValue(); 5516 const Function *Scope = nullptr; 5517 if (auto *I = dyn_cast<Instruction>(&V)) 5518 Scope = I->getFunction(); 5519 if (auto *A = dyn_cast<Argument>(&V)) { 5520 Scope = A->getParent(); 5521 if (!Scope->hasLocalLinkage()) 5522 return Changed; 5523 } 5524 if (!Scope) 5525 return indicateOptimisticFixpoint(); 5526 5527 bool IsKnownNoRecurse; 5528 if (AA::hasAssumedIRAttr<Attribute::NoRecurse>( 5529 A, this, IRPosition::function(*Scope), DepClassTy::OPTIONAL, 5530 IsKnownNoRecurse)) 5531 return Changed; 5532 5533 auto UsePred = [&](const Use &U, bool &Follow) { 5534 const Instruction *UserI = dyn_cast<Instruction>(U.getUser()); 5535 if (!UserI || isa<GetElementPtrInst>(UserI) || isa<CastInst>(UserI) || 5536 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) { 5537 Follow = true; 5538 return true; 5539 } 5540 if (isa<LoadInst>(UserI) || isa<CmpInst>(UserI) || 5541 (isa<StoreInst>(UserI) && 5542 cast<StoreInst>(UserI)->getValueOperand() != U.get())) 5543 return true; 5544 if (auto *CB = dyn_cast<CallBase>(UserI)) { 5545 // This check is not guaranteeing uniqueness but for now that we cannot 5546 // end up with two versions of \p U thinking it was one. 5547 auto *Callee = dyn_cast_if_present<Function>(CB->getCalledOperand()); 5548 if (!Callee || !Callee->hasLocalLinkage()) 5549 return true; 5550 if (!CB->isArgOperand(&U)) 5551 return false; 5552 const auto *ArgInstanceInfoAA = A.getAAFor<AAInstanceInfo>( 5553 *this, IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U)), 5554 DepClassTy::OPTIONAL); 5555 if (!ArgInstanceInfoAA || 5556 !ArgInstanceInfoAA->isAssumedUniqueForAnalysis()) 5557 return false; 5558 // If this call base might reach the scope again we might forward the 5559 // argument back here. This is very conservative. 5560 if (AA::isPotentiallyReachable( 5561 A, *CB, *Scope, *this, /* ExclusionSet */ nullptr, 5562 [Scope](const Function &Fn) { return &Fn != Scope; })) 5563 return false; 5564 return true; 5565 } 5566 return false; 5567 }; 5568 5569 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) { 5570 if (auto *SI = dyn_cast<StoreInst>(OldU.getUser())) { 5571 auto *Ptr = SI->getPointerOperand()->stripPointerCasts(); 5572 if ((isa<AllocaInst>(Ptr) || isNoAliasCall(Ptr)) && 5573 AA::isDynamicallyUnique(A, *this, *Ptr)) 5574 return true; 5575 } 5576 return false; 5577 }; 5578 5579 if (!A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ true, 5580 DepClassTy::OPTIONAL, 5581 /* IgnoreDroppableUses */ true, EquivalentUseCB)) 5582 return indicatePessimisticFixpoint(); 5583 5584 return Changed; 5585 } 5586 5587 /// See AbstractState::getAsStr(). 5588 const std::string getAsStr(Attributor *A) const override { 5589 return isAssumedUniqueForAnalysis() ? "<unique [fAa]>" : "<unknown>"; 5590 } 5591 5592 /// See AbstractAttribute::trackStatistics() 5593 void trackStatistics() const override {} 5594 }; 5595 5596 /// InstanceInfo attribute for floating values. 5597 struct AAInstanceInfoFloating : AAInstanceInfoImpl { 5598 AAInstanceInfoFloating(const IRPosition &IRP, Attributor &A) 5599 : AAInstanceInfoImpl(IRP, A) {} 5600 }; 5601 5602 /// NoCapture attribute for function arguments. 5603 struct AAInstanceInfoArgument final : AAInstanceInfoFloating { 5604 AAInstanceInfoArgument(const IRPosition &IRP, Attributor &A) 5605 : AAInstanceInfoFloating(IRP, A) {} 5606 }; 5607 5608 /// InstanceInfo attribute for call site arguments. 5609 struct AAInstanceInfoCallSiteArgument final : AAInstanceInfoImpl { 5610 AAInstanceInfoCallSiteArgument(const IRPosition &IRP, Attributor &A) 5611 : AAInstanceInfoImpl(IRP, A) {} 5612 5613 /// See AbstractAttribute::updateImpl(...). 5614 ChangeStatus updateImpl(Attributor &A) override { 5615 // TODO: Once we have call site specific value information we can provide 5616 // call site specific liveness information and then it makes 5617 // sense to specialize attributes for call sites arguments instead of 5618 // redirecting requests to the callee argument. 5619 Argument *Arg = getAssociatedArgument(); 5620 if (!Arg) 5621 return indicatePessimisticFixpoint(); 5622 const IRPosition &ArgPos = IRPosition::argument(*Arg); 5623 auto *ArgAA = 5624 A.getAAFor<AAInstanceInfo>(*this, ArgPos, DepClassTy::REQUIRED); 5625 if (!ArgAA) 5626 return indicatePessimisticFixpoint(); 5627 return clampStateAndIndicateChange(getState(), ArgAA->getState()); 5628 } 5629 }; 5630 5631 /// InstanceInfo attribute for function return value. 5632 struct AAInstanceInfoReturned final : AAInstanceInfoImpl { 5633 AAInstanceInfoReturned(const IRPosition &IRP, Attributor &A) 5634 : AAInstanceInfoImpl(IRP, A) { 5635 llvm_unreachable("InstanceInfo is not applicable to function returns!"); 5636 } 5637 5638 /// See AbstractAttribute::initialize(...). 5639 void initialize(Attributor &A) override { 5640 llvm_unreachable("InstanceInfo is not applicable to function returns!"); 5641 } 5642 5643 /// See AbstractAttribute::updateImpl(...). 5644 ChangeStatus updateImpl(Attributor &A) override { 5645 llvm_unreachable("InstanceInfo is not applicable to function returns!"); 5646 } 5647 }; 5648 5649 /// InstanceInfo attribute deduction for a call site return value. 5650 struct AAInstanceInfoCallSiteReturned final : AAInstanceInfoFloating { 5651 AAInstanceInfoCallSiteReturned(const IRPosition &IRP, Attributor &A) 5652 : AAInstanceInfoFloating(IRP, A) {} 5653 }; 5654 } // namespace 5655 5656 /// ----------------------- Variable Capturing --------------------------------- 5657 bool AANoCapture::isImpliedByIR(Attributor &A, const IRPosition &IRP, 5658 Attribute::AttrKind ImpliedAttributeKind, 5659 bool IgnoreSubsumingPositions) { 5660 assert(ImpliedAttributeKind == Attribute::NoCapture && 5661 "Unexpected attribute kind"); 5662 Value &V = IRP.getAssociatedValue(); 5663 if (!IRP.isArgumentPosition()) 5664 return V.use_empty(); 5665 5666 // You cannot "capture" null in the default address space. 5667 if (isa<UndefValue>(V) || (isa<ConstantPointerNull>(V) && 5668 V.getType()->getPointerAddressSpace() == 0)) { 5669 return true; 5670 } 5671 5672 if (A.hasAttr(IRP, {Attribute::NoCapture}, 5673 /* IgnoreSubsumingPositions */ true, Attribute::NoCapture)) 5674 return true; 5675 5676 if (IRP.getPositionKind() == IRP_CALL_SITE_ARGUMENT) 5677 if (Argument *Arg = IRP.getAssociatedArgument()) 5678 if (A.hasAttr(IRPosition::argument(*Arg), 5679 {Attribute::NoCapture, Attribute::ByVal}, 5680 /* IgnoreSubsumingPositions */ true)) { 5681 A.manifestAttrs(IRP, 5682 Attribute::get(V.getContext(), Attribute::NoCapture)); 5683 return true; 5684 } 5685 5686 if (const Function *F = IRP.getAssociatedFunction()) { 5687 // Check what state the associated function can actually capture. 5688 AANoCapture::StateType State; 5689 determineFunctionCaptureCapabilities(IRP, *F, State); 5690 if (State.isKnown(NO_CAPTURE)) { 5691 A.manifestAttrs(IRP, 5692 Attribute::get(V.getContext(), Attribute::NoCapture)); 5693 return true; 5694 } 5695 } 5696 5697 return false; 5698 } 5699 5700 /// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known 5701 /// depending on the ability of the function associated with \p IRP to capture 5702 /// state in memory and through "returning/throwing", respectively. 5703 void AANoCapture::determineFunctionCaptureCapabilities(const IRPosition &IRP, 5704 const Function &F, 5705 BitIntegerState &State) { 5706 // TODO: Once we have memory behavior attributes we should use them here. 5707 5708 // If we know we cannot communicate or write to memory, we do not care about 5709 // ptr2int anymore. 5710 bool ReadOnly = F.onlyReadsMemory(); 5711 bool NoThrow = F.doesNotThrow(); 5712 bool IsVoidReturn = F.getReturnType()->isVoidTy(); 5713 if (ReadOnly && NoThrow && IsVoidReturn) { 5714 State.addKnownBits(NO_CAPTURE); 5715 return; 5716 } 5717 5718 // A function cannot capture state in memory if it only reads memory, it can 5719 // however return/throw state and the state might be influenced by the 5720 // pointer value, e.g., loading from a returned pointer might reveal a bit. 5721 if (ReadOnly) 5722 State.addKnownBits(NOT_CAPTURED_IN_MEM); 5723 5724 // A function cannot communicate state back if it does not through 5725 // exceptions and doesn not return values. 5726 if (NoThrow && IsVoidReturn) 5727 State.addKnownBits(NOT_CAPTURED_IN_RET); 5728 5729 // Check existing "returned" attributes. 5730 int ArgNo = IRP.getCalleeArgNo(); 5731 if (!NoThrow || ArgNo < 0 || 5732 !F.getAttributes().hasAttrSomewhere(Attribute::Returned)) 5733 return; 5734 5735 for (unsigned U = 0, E = F.arg_size(); U < E; ++U) 5736 if (F.hasParamAttribute(U, Attribute::Returned)) { 5737 if (U == unsigned(ArgNo)) 5738 State.removeAssumedBits(NOT_CAPTURED_IN_RET); 5739 else if (ReadOnly) 5740 State.addKnownBits(NO_CAPTURE); 5741 else 5742 State.addKnownBits(NOT_CAPTURED_IN_RET); 5743 break; 5744 } 5745 } 5746 5747 namespace { 5748 /// A class to hold the state of for no-capture attributes. 5749 struct AANoCaptureImpl : public AANoCapture { 5750 AANoCaptureImpl(const IRPosition &IRP, Attributor &A) : AANoCapture(IRP, A) {} 5751 5752 /// See AbstractAttribute::initialize(...). 5753 void initialize(Attributor &A) override { 5754 bool IsKnown; 5755 assert(!AA::hasAssumedIRAttr<Attribute::NoCapture>( 5756 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown)); 5757 (void)IsKnown; 5758 } 5759 5760 /// See AbstractAttribute::updateImpl(...). 5761 ChangeStatus updateImpl(Attributor &A) override; 5762 5763 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...). 5764 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, 5765 SmallVectorImpl<Attribute> &Attrs) const override { 5766 if (!isAssumedNoCaptureMaybeReturned()) 5767 return; 5768 5769 if (isArgumentPosition()) { 5770 if (isAssumedNoCapture()) 5771 Attrs.emplace_back(Attribute::get(Ctx, Attribute::NoCapture)); 5772 else if (ManifestInternal) 5773 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned")); 5774 } 5775 } 5776 5777 /// See AbstractState::getAsStr(). 5778 const std::string getAsStr(Attributor *A) const override { 5779 if (isKnownNoCapture()) 5780 return "known not-captured"; 5781 if (isAssumedNoCapture()) 5782 return "assumed not-captured"; 5783 if (isKnownNoCaptureMaybeReturned()) 5784 return "known not-captured-maybe-returned"; 5785 if (isAssumedNoCaptureMaybeReturned()) 5786 return "assumed not-captured-maybe-returned"; 5787 return "assumed-captured"; 5788 } 5789 5790 /// Check the use \p U and update \p State accordingly. Return true if we 5791 /// should continue to update the state. 5792 bool checkUse(Attributor &A, AANoCapture::StateType &State, const Use &U, 5793 bool &Follow) { 5794 Instruction *UInst = cast<Instruction>(U.getUser()); 5795 LLVM_DEBUG(dbgs() << "[AANoCapture] Check use: " << *U.get() << " in " 5796 << *UInst << "\n"); 5797 5798 // Deal with ptr2int by following uses. 5799 if (isa<PtrToIntInst>(UInst)) { 5800 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n"); 5801 return isCapturedIn(State, /* Memory */ true, /* Integer */ true, 5802 /* Return */ true); 5803 } 5804 5805 // For stores we already checked if we can follow them, if they make it 5806 // here we give up. 5807 if (isa<StoreInst>(UInst)) 5808 return isCapturedIn(State, /* Memory */ true, /* Integer */ false, 5809 /* Return */ false); 5810 5811 // Explicitly catch return instructions. 5812 if (isa<ReturnInst>(UInst)) { 5813 if (UInst->getFunction() == getAnchorScope()) 5814 return isCapturedIn(State, /* Memory */ false, /* Integer */ false, 5815 /* Return */ true); 5816 return isCapturedIn(State, /* Memory */ true, /* Integer */ true, 5817 /* Return */ true); 5818 } 5819 5820 // For now we only use special logic for call sites. However, the tracker 5821 // itself knows about a lot of other non-capturing cases already. 5822 auto *CB = dyn_cast<CallBase>(UInst); 5823 if (!CB || !CB->isArgOperand(&U)) 5824 return isCapturedIn(State, /* Memory */ true, /* Integer */ true, 5825 /* Return */ true); 5826 5827 unsigned ArgNo = CB->getArgOperandNo(&U); 5828 const IRPosition &CSArgPos = IRPosition::callsite_argument(*CB, ArgNo); 5829 // If we have a abstract no-capture attribute for the argument we can use 5830 // it to justify a non-capture attribute here. This allows recursion! 5831 bool IsKnownNoCapture; 5832 const AANoCapture *ArgNoCaptureAA = nullptr; 5833 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>( 5834 A, this, CSArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false, 5835 &ArgNoCaptureAA); 5836 if (IsAssumedNoCapture) 5837 return isCapturedIn(State, /* Memory */ false, /* Integer */ false, 5838 /* Return */ false); 5839 if (ArgNoCaptureAA && ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned()) { 5840 Follow = true; 5841 return isCapturedIn(State, /* Memory */ false, /* Integer */ false, 5842 /* Return */ false); 5843 } 5844 5845 // Lastly, we could not find a reason no-capture can be assumed so we don't. 5846 return isCapturedIn(State, /* Memory */ true, /* Integer */ true, 5847 /* Return */ true); 5848 } 5849 5850 /// Update \p State according to \p CapturedInMem, \p CapturedInInt, and 5851 /// \p CapturedInRet, then return true if we should continue updating the 5852 /// state. 5853 static bool isCapturedIn(AANoCapture::StateType &State, bool CapturedInMem, 5854 bool CapturedInInt, bool CapturedInRet) { 5855 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int " 5856 << CapturedInInt << "|Ret " << CapturedInRet << "]\n"); 5857 if (CapturedInMem) 5858 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM); 5859 if (CapturedInInt) 5860 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT); 5861 if (CapturedInRet) 5862 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET); 5863 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED); 5864 } 5865 }; 5866 5867 ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) { 5868 const IRPosition &IRP = getIRPosition(); 5869 Value *V = isArgumentPosition() ? IRP.getAssociatedArgument() 5870 : &IRP.getAssociatedValue(); 5871 if (!V) 5872 return indicatePessimisticFixpoint(); 5873 5874 const Function *F = 5875 isArgumentPosition() ? IRP.getAssociatedFunction() : IRP.getAnchorScope(); 5876 assert(F && "Expected a function!"); 5877 const IRPosition &FnPos = IRPosition::function(*F); 5878 5879 AANoCapture::StateType T; 5880 5881 // Readonly means we cannot capture through memory. 5882 bool IsKnown; 5883 if (AA::isAssumedReadOnly(A, FnPos, *this, IsKnown)) { 5884 T.addKnownBits(NOT_CAPTURED_IN_MEM); 5885 if (IsKnown) 5886 addKnownBits(NOT_CAPTURED_IN_MEM); 5887 } 5888 5889 // Make sure all returned values are different than the underlying value. 5890 // TODO: we could do this in a more sophisticated way inside 5891 // AAReturnedValues, e.g., track all values that escape through returns 5892 // directly somehow. 5893 auto CheckReturnedArgs = [&](bool &UsedAssumedInformation) { 5894 SmallVector<AA::ValueAndContext> Values; 5895 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*F), this, Values, 5896 AA::ValueScope::Intraprocedural, 5897 UsedAssumedInformation)) 5898 return false; 5899 bool SeenConstant = false; 5900 for (const AA::ValueAndContext &VAC : Values) { 5901 if (isa<Constant>(VAC.getValue())) { 5902 if (SeenConstant) 5903 return false; 5904 SeenConstant = true; 5905 } else if (!isa<Argument>(VAC.getValue()) || 5906 VAC.getValue() == getAssociatedArgument()) 5907 return false; 5908 } 5909 return true; 5910 }; 5911 5912 bool IsKnownNoUnwind; 5913 if (AA::hasAssumedIRAttr<Attribute::NoUnwind>( 5914 A, this, FnPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) { 5915 bool IsVoidTy = F->getReturnType()->isVoidTy(); 5916 bool UsedAssumedInformation = false; 5917 if (IsVoidTy || CheckReturnedArgs(UsedAssumedInformation)) { 5918 T.addKnownBits(NOT_CAPTURED_IN_RET); 5919 if (T.isKnown(NOT_CAPTURED_IN_MEM)) 5920 return ChangeStatus::UNCHANGED; 5921 if (IsKnownNoUnwind && (IsVoidTy || !UsedAssumedInformation)) { 5922 addKnownBits(NOT_CAPTURED_IN_RET); 5923 if (isKnown(NOT_CAPTURED_IN_MEM)) 5924 return indicateOptimisticFixpoint(); 5925 } 5926 } 5927 } 5928 5929 auto IsDereferenceableOrNull = [&](Value *O, const DataLayout &DL) { 5930 const auto *DerefAA = A.getAAFor<AADereferenceable>( 5931 *this, IRPosition::value(*O), DepClassTy::OPTIONAL); 5932 return DerefAA && DerefAA->getAssumedDereferenceableBytes(); 5933 }; 5934 5935 auto UseCheck = [&](const Use &U, bool &Follow) -> bool { 5936 switch (DetermineUseCaptureKind(U, IsDereferenceableOrNull)) { 5937 case UseCaptureKind::NO_CAPTURE: 5938 return true; 5939 case UseCaptureKind::MAY_CAPTURE: 5940 return checkUse(A, T, U, Follow); 5941 case UseCaptureKind::PASSTHROUGH: 5942 Follow = true; 5943 return true; 5944 } 5945 llvm_unreachable("Unexpected use capture kind!"); 5946 }; 5947 5948 if (!A.checkForAllUses(UseCheck, *this, *V)) 5949 return indicatePessimisticFixpoint(); 5950 5951 AANoCapture::StateType &S = getState(); 5952 auto Assumed = S.getAssumed(); 5953 S.intersectAssumedBits(T.getAssumed()); 5954 if (!isAssumedNoCaptureMaybeReturned()) 5955 return indicatePessimisticFixpoint(); 5956 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED 5957 : ChangeStatus::CHANGED; 5958 } 5959 5960 /// NoCapture attribute for function arguments. 5961 struct AANoCaptureArgument final : AANoCaptureImpl { 5962 AANoCaptureArgument(const IRPosition &IRP, Attributor &A) 5963 : AANoCaptureImpl(IRP, A) {} 5964 5965 /// See AbstractAttribute::trackStatistics() 5966 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) } 5967 }; 5968 5969 /// NoCapture attribute for call site arguments. 5970 struct AANoCaptureCallSiteArgument final : AANoCaptureImpl { 5971 AANoCaptureCallSiteArgument(const IRPosition &IRP, Attributor &A) 5972 : AANoCaptureImpl(IRP, A) {} 5973 5974 /// See AbstractAttribute::updateImpl(...). 5975 ChangeStatus updateImpl(Attributor &A) override { 5976 // TODO: Once we have call site specific value information we can provide 5977 // call site specific liveness information and then it makes 5978 // sense to specialize attributes for call sites arguments instead of 5979 // redirecting requests to the callee argument. 5980 Argument *Arg = getAssociatedArgument(); 5981 if (!Arg) 5982 return indicatePessimisticFixpoint(); 5983 const IRPosition &ArgPos = IRPosition::argument(*Arg); 5984 bool IsKnownNoCapture; 5985 const AANoCapture *ArgAA = nullptr; 5986 if (AA::hasAssumedIRAttr<Attribute::NoCapture>( 5987 A, this, ArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false, 5988 &ArgAA)) 5989 return ChangeStatus::UNCHANGED; 5990 if (!ArgAA || !ArgAA->isAssumedNoCaptureMaybeReturned()) 5991 return indicatePessimisticFixpoint(); 5992 return clampStateAndIndicateChange(getState(), ArgAA->getState()); 5993 } 5994 5995 /// See AbstractAttribute::trackStatistics() 5996 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nocapture)}; 5997 }; 5998 5999 /// NoCapture attribute for floating values. 6000 struct AANoCaptureFloating final : AANoCaptureImpl { 6001 AANoCaptureFloating(const IRPosition &IRP, Attributor &A) 6002 : AANoCaptureImpl(IRP, A) {} 6003 6004 /// See AbstractAttribute::trackStatistics() 6005 void trackStatistics() const override { 6006 STATS_DECLTRACK_FLOATING_ATTR(nocapture) 6007 } 6008 }; 6009 6010 /// NoCapture attribute for function return value. 6011 struct AANoCaptureReturned final : AANoCaptureImpl { 6012 AANoCaptureReturned(const IRPosition &IRP, Attributor &A) 6013 : AANoCaptureImpl(IRP, A) { 6014 llvm_unreachable("NoCapture is not applicable to function returns!"); 6015 } 6016 6017 /// See AbstractAttribute::initialize(...). 6018 void initialize(Attributor &A) override { 6019 llvm_unreachable("NoCapture is not applicable to function returns!"); 6020 } 6021 6022 /// See AbstractAttribute::updateImpl(...). 6023 ChangeStatus updateImpl(Attributor &A) override { 6024 llvm_unreachable("NoCapture is not applicable to function returns!"); 6025 } 6026 6027 /// See AbstractAttribute::trackStatistics() 6028 void trackStatistics() const override {} 6029 }; 6030 6031 /// NoCapture attribute deduction for a call site return value. 6032 struct AANoCaptureCallSiteReturned final : AANoCaptureImpl { 6033 AANoCaptureCallSiteReturned(const IRPosition &IRP, Attributor &A) 6034 : AANoCaptureImpl(IRP, A) {} 6035 6036 /// See AbstractAttribute::initialize(...). 6037 void initialize(Attributor &A) override { 6038 const Function *F = getAnchorScope(); 6039 // Check what state the associated function can actually capture. 6040 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this); 6041 } 6042 6043 /// See AbstractAttribute::trackStatistics() 6044 void trackStatistics() const override { 6045 STATS_DECLTRACK_CSRET_ATTR(nocapture) 6046 } 6047 }; 6048 } // namespace 6049 6050 /// ------------------ Value Simplify Attribute ---------------------------- 6051 6052 bool ValueSimplifyStateType::unionAssumed(std::optional<Value *> Other) { 6053 // FIXME: Add a typecast support. 6054 SimplifiedAssociatedValue = AA::combineOptionalValuesInAAValueLatice( 6055 SimplifiedAssociatedValue, Other, Ty); 6056 if (SimplifiedAssociatedValue == std::optional<Value *>(nullptr)) 6057 return false; 6058 6059 LLVM_DEBUG({ 6060 if (SimplifiedAssociatedValue) 6061 dbgs() << "[ValueSimplify] is assumed to be " 6062 << **SimplifiedAssociatedValue << "\n"; 6063 else 6064 dbgs() << "[ValueSimplify] is assumed to be <none>\n"; 6065 }); 6066 return true; 6067 } 6068 6069 namespace { 6070 struct AAValueSimplifyImpl : AAValueSimplify { 6071 AAValueSimplifyImpl(const IRPosition &IRP, Attributor &A) 6072 : AAValueSimplify(IRP, A) {} 6073 6074 /// See AbstractAttribute::initialize(...). 6075 void initialize(Attributor &A) override { 6076 if (getAssociatedValue().getType()->isVoidTy()) 6077 indicatePessimisticFixpoint(); 6078 if (A.hasSimplificationCallback(getIRPosition())) 6079 indicatePessimisticFixpoint(); 6080 } 6081 6082 /// See AbstractAttribute::getAsStr(). 6083 const std::string getAsStr(Attributor *A) const override { 6084 LLVM_DEBUG({ 6085 dbgs() << "SAV: " << (bool)SimplifiedAssociatedValue << " "; 6086 if (SimplifiedAssociatedValue && *SimplifiedAssociatedValue) 6087 dbgs() << "SAV: " << **SimplifiedAssociatedValue << " "; 6088 }); 6089 return isValidState() ? (isAtFixpoint() ? "simplified" : "maybe-simple") 6090 : "not-simple"; 6091 } 6092 6093 /// See AbstractAttribute::trackStatistics() 6094 void trackStatistics() const override {} 6095 6096 /// See AAValueSimplify::getAssumedSimplifiedValue() 6097 std::optional<Value *> 6098 getAssumedSimplifiedValue(Attributor &A) const override { 6099 return SimplifiedAssociatedValue; 6100 } 6101 6102 /// Ensure the return value is \p V with type \p Ty, if not possible return 6103 /// nullptr. If \p Check is true we will only verify such an operation would 6104 /// suceed and return a non-nullptr value if that is the case. No IR is 6105 /// generated or modified. 6106 static Value *ensureType(Attributor &A, Value &V, Type &Ty, Instruction *CtxI, 6107 bool Check) { 6108 if (auto *TypedV = AA::getWithType(V, Ty)) 6109 return TypedV; 6110 if (CtxI && V.getType()->canLosslesslyBitCastTo(&Ty)) 6111 return Check ? &V 6112 : BitCastInst::CreatePointerBitCastOrAddrSpaceCast(&V, &Ty, 6113 "", CtxI); 6114 return nullptr; 6115 } 6116 6117 /// Reproduce \p I with type \p Ty or return nullptr if that is not posisble. 6118 /// If \p Check is true we will only verify such an operation would suceed and 6119 /// return a non-nullptr value if that is the case. No IR is generated or 6120 /// modified. 6121 static Value *reproduceInst(Attributor &A, 6122 const AbstractAttribute &QueryingAA, 6123 Instruction &I, Type &Ty, Instruction *CtxI, 6124 bool Check, ValueToValueMapTy &VMap) { 6125 assert(CtxI && "Cannot reproduce an instruction without context!"); 6126 if (Check && (I.mayReadFromMemory() || 6127 !isSafeToSpeculativelyExecute(&I, CtxI, /* DT */ nullptr, 6128 /* TLI */ nullptr))) 6129 return nullptr; 6130 for (Value *Op : I.operands()) { 6131 Value *NewOp = reproduceValue(A, QueryingAA, *Op, Ty, CtxI, Check, VMap); 6132 if (!NewOp) { 6133 assert(Check && "Manifest of new value unexpectedly failed!"); 6134 return nullptr; 6135 } 6136 if (!Check) 6137 VMap[Op] = NewOp; 6138 } 6139 if (Check) 6140 return &I; 6141 6142 Instruction *CloneI = I.clone(); 6143 // TODO: Try to salvage debug information here. 6144 CloneI->setDebugLoc(DebugLoc()); 6145 VMap[&I] = CloneI; 6146 CloneI->insertBefore(CtxI); 6147 RemapInstruction(CloneI, VMap); 6148 return CloneI; 6149 } 6150 6151 /// Reproduce \p V with type \p Ty or return nullptr if that is not posisble. 6152 /// If \p Check is true we will only verify such an operation would suceed and 6153 /// return a non-nullptr value if that is the case. No IR is generated or 6154 /// modified. 6155 static Value *reproduceValue(Attributor &A, 6156 const AbstractAttribute &QueryingAA, Value &V, 6157 Type &Ty, Instruction *CtxI, bool Check, 6158 ValueToValueMapTy &VMap) { 6159 if (const auto &NewV = VMap.lookup(&V)) 6160 return NewV; 6161 bool UsedAssumedInformation = false; 6162 std::optional<Value *> SimpleV = A.getAssumedSimplified( 6163 V, QueryingAA, UsedAssumedInformation, AA::Interprocedural); 6164 if (!SimpleV.has_value()) 6165 return PoisonValue::get(&Ty); 6166 Value *EffectiveV = &V; 6167 if (*SimpleV) 6168 EffectiveV = *SimpleV; 6169 if (auto *C = dyn_cast<Constant>(EffectiveV)) 6170 return C; 6171 if (CtxI && AA::isValidAtPosition(AA::ValueAndContext(*EffectiveV, *CtxI), 6172 A.getInfoCache())) 6173 return ensureType(A, *EffectiveV, Ty, CtxI, Check); 6174 if (auto *I = dyn_cast<Instruction>(EffectiveV)) 6175 if (Value *NewV = reproduceInst(A, QueryingAA, *I, Ty, CtxI, Check, VMap)) 6176 return ensureType(A, *NewV, Ty, CtxI, Check); 6177 return nullptr; 6178 } 6179 6180 /// Return a value we can use as replacement for the associated one, or 6181 /// nullptr if we don't have one that makes sense. 6182 Value *manifestReplacementValue(Attributor &A, Instruction *CtxI) const { 6183 Value *NewV = SimplifiedAssociatedValue 6184 ? *SimplifiedAssociatedValue 6185 : UndefValue::get(getAssociatedType()); 6186 if (NewV && NewV != &getAssociatedValue()) { 6187 ValueToValueMapTy VMap; 6188 // First verify we can reprduce the value with the required type at the 6189 // context location before we actually start modifying the IR. 6190 if (reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI, 6191 /* CheckOnly */ true, VMap)) 6192 return reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI, 6193 /* CheckOnly */ false, VMap); 6194 } 6195 return nullptr; 6196 } 6197 6198 /// Helper function for querying AAValueSimplify and updating candidate. 6199 /// \param IRP The value position we are trying to unify with SimplifiedValue 6200 bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA, 6201 const IRPosition &IRP, bool Simplify = true) { 6202 bool UsedAssumedInformation = false; 6203 std::optional<Value *> QueryingValueSimplified = &IRP.getAssociatedValue(); 6204 if (Simplify) 6205 QueryingValueSimplified = A.getAssumedSimplified( 6206 IRP, QueryingAA, UsedAssumedInformation, AA::Interprocedural); 6207 return unionAssumed(QueryingValueSimplified); 6208 } 6209 6210 /// Returns a candidate is found or not 6211 template <typename AAType> bool askSimplifiedValueFor(Attributor &A) { 6212 if (!getAssociatedValue().getType()->isIntegerTy()) 6213 return false; 6214 6215 // This will also pass the call base context. 6216 const auto *AA = 6217 A.getAAFor<AAType>(*this, getIRPosition(), DepClassTy::NONE); 6218 if (!AA) 6219 return false; 6220 6221 std::optional<Constant *> COpt = AA->getAssumedConstant(A); 6222 6223 if (!COpt) { 6224 SimplifiedAssociatedValue = std::nullopt; 6225 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL); 6226 return true; 6227 } 6228 if (auto *C = *COpt) { 6229 SimplifiedAssociatedValue = C; 6230 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL); 6231 return true; 6232 } 6233 return false; 6234 } 6235 6236 bool askSimplifiedValueForOtherAAs(Attributor &A) { 6237 if (askSimplifiedValueFor<AAValueConstantRange>(A)) 6238 return true; 6239 if (askSimplifiedValueFor<AAPotentialConstantValues>(A)) 6240 return true; 6241 return false; 6242 } 6243 6244 /// See AbstractAttribute::manifest(...). 6245 ChangeStatus manifest(Attributor &A) override { 6246 ChangeStatus Changed = ChangeStatus::UNCHANGED; 6247 for (auto &U : getAssociatedValue().uses()) { 6248 // Check if we need to adjust the insertion point to make sure the IR is 6249 // valid. 6250 Instruction *IP = dyn_cast<Instruction>(U.getUser()); 6251 if (auto *PHI = dyn_cast_or_null<PHINode>(IP)) 6252 IP = PHI->getIncomingBlock(U)->getTerminator(); 6253 if (auto *NewV = manifestReplacementValue(A, IP)) { 6254 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << getAssociatedValue() 6255 << " -> " << *NewV << " :: " << *this << "\n"); 6256 if (A.changeUseAfterManifest(U, *NewV)) 6257 Changed = ChangeStatus::CHANGED; 6258 } 6259 } 6260 6261 return Changed | AAValueSimplify::manifest(A); 6262 } 6263 6264 /// See AbstractState::indicatePessimisticFixpoint(...). 6265 ChangeStatus indicatePessimisticFixpoint() override { 6266 SimplifiedAssociatedValue = &getAssociatedValue(); 6267 return AAValueSimplify::indicatePessimisticFixpoint(); 6268 } 6269 }; 6270 6271 struct AAValueSimplifyArgument final : AAValueSimplifyImpl { 6272 AAValueSimplifyArgument(const IRPosition &IRP, Attributor &A) 6273 : AAValueSimplifyImpl(IRP, A) {} 6274 6275 void initialize(Attributor &A) override { 6276 AAValueSimplifyImpl::initialize(A); 6277 if (A.hasAttr(getIRPosition(), 6278 {Attribute::InAlloca, Attribute::Preallocated, 6279 Attribute::StructRet, Attribute::Nest, Attribute::ByVal}, 6280 /* IgnoreSubsumingPositions */ true)) 6281 indicatePessimisticFixpoint(); 6282 } 6283 6284 /// See AbstractAttribute::updateImpl(...). 6285 ChangeStatus updateImpl(Attributor &A) override { 6286 // Byval is only replacable if it is readonly otherwise we would write into 6287 // the replaced value and not the copy that byval creates implicitly. 6288 Argument *Arg = getAssociatedArgument(); 6289 if (Arg->hasByValAttr()) { 6290 // TODO: We probably need to verify synchronization is not an issue, e.g., 6291 // there is no race by not copying a constant byval. 6292 bool IsKnown; 6293 if (!AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown)) 6294 return indicatePessimisticFixpoint(); 6295 } 6296 6297 auto Before = SimplifiedAssociatedValue; 6298 6299 auto PredForCallSite = [&](AbstractCallSite ACS) { 6300 const IRPosition &ACSArgPos = 6301 IRPosition::callsite_argument(ACS, getCallSiteArgNo()); 6302 // Check if a coresponding argument was found or if it is on not 6303 // associated (which can happen for callback calls). 6304 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID) 6305 return false; 6306 6307 // Simplify the argument operand explicitly and check if the result is 6308 // valid in the current scope. This avoids refering to simplified values 6309 // in other functions, e.g., we don't want to say a an argument in a 6310 // static function is actually an argument in a different function. 6311 bool UsedAssumedInformation = false; 6312 std::optional<Constant *> SimpleArgOp = 6313 A.getAssumedConstant(ACSArgPos, *this, UsedAssumedInformation); 6314 if (!SimpleArgOp) 6315 return true; 6316 if (!*SimpleArgOp) 6317 return false; 6318 if (!AA::isDynamicallyUnique(A, *this, **SimpleArgOp)) 6319 return false; 6320 return unionAssumed(*SimpleArgOp); 6321 }; 6322 6323 // Generate a answer specific to a call site context. 6324 bool Success; 6325 bool UsedAssumedInformation = false; 6326 if (hasCallBaseContext() && 6327 getCallBaseContext()->getCalledOperand() == Arg->getParent()) 6328 Success = PredForCallSite( 6329 AbstractCallSite(&getCallBaseContext()->getCalledOperandUse())); 6330 else 6331 Success = A.checkForAllCallSites(PredForCallSite, *this, true, 6332 UsedAssumedInformation); 6333 6334 if (!Success) 6335 if (!askSimplifiedValueForOtherAAs(A)) 6336 return indicatePessimisticFixpoint(); 6337 6338 // If a candidate was found in this update, return CHANGED. 6339 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED 6340 : ChangeStatus ::CHANGED; 6341 } 6342 6343 /// See AbstractAttribute::trackStatistics() 6344 void trackStatistics() const override { 6345 STATS_DECLTRACK_ARG_ATTR(value_simplify) 6346 } 6347 }; 6348 6349 struct AAValueSimplifyReturned : AAValueSimplifyImpl { 6350 AAValueSimplifyReturned(const IRPosition &IRP, Attributor &A) 6351 : AAValueSimplifyImpl(IRP, A) {} 6352 6353 /// See AAValueSimplify::getAssumedSimplifiedValue() 6354 std::optional<Value *> 6355 getAssumedSimplifiedValue(Attributor &A) const override { 6356 if (!isValidState()) 6357 return nullptr; 6358 return SimplifiedAssociatedValue; 6359 } 6360 6361 /// See AbstractAttribute::updateImpl(...). 6362 ChangeStatus updateImpl(Attributor &A) override { 6363 auto Before = SimplifiedAssociatedValue; 6364 6365 auto ReturnInstCB = [&](Instruction &I) { 6366 auto &RI = cast<ReturnInst>(I); 6367 return checkAndUpdate( 6368 A, *this, 6369 IRPosition::value(*RI.getReturnValue(), getCallBaseContext())); 6370 }; 6371 6372 bool UsedAssumedInformation = false; 6373 if (!A.checkForAllInstructions(ReturnInstCB, *this, {Instruction::Ret}, 6374 UsedAssumedInformation)) 6375 if (!askSimplifiedValueForOtherAAs(A)) 6376 return indicatePessimisticFixpoint(); 6377 6378 // If a candidate was found in this update, return CHANGED. 6379 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED 6380 : ChangeStatus ::CHANGED; 6381 } 6382 6383 ChangeStatus manifest(Attributor &A) override { 6384 // We queried AAValueSimplify for the returned values so they will be 6385 // replaced if a simplified form was found. Nothing to do here. 6386 return ChangeStatus::UNCHANGED; 6387 } 6388 6389 /// See AbstractAttribute::trackStatistics() 6390 void trackStatistics() const override { 6391 STATS_DECLTRACK_FNRET_ATTR(value_simplify) 6392 } 6393 }; 6394 6395 struct AAValueSimplifyFloating : AAValueSimplifyImpl { 6396 AAValueSimplifyFloating(const IRPosition &IRP, Attributor &A) 6397 : AAValueSimplifyImpl(IRP, A) {} 6398 6399 /// See AbstractAttribute::initialize(...). 6400 void initialize(Attributor &A) override { 6401 AAValueSimplifyImpl::initialize(A); 6402 Value &V = getAnchorValue(); 6403 6404 // TODO: add other stuffs 6405 if (isa<Constant>(V)) 6406 indicatePessimisticFixpoint(); 6407 } 6408 6409 /// See AbstractAttribute::updateImpl(...). 6410 ChangeStatus updateImpl(Attributor &A) override { 6411 auto Before = SimplifiedAssociatedValue; 6412 if (!askSimplifiedValueForOtherAAs(A)) 6413 return indicatePessimisticFixpoint(); 6414 6415 // If a candidate was found in this update, return CHANGED. 6416 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED 6417 : ChangeStatus ::CHANGED; 6418 } 6419 6420 /// See AbstractAttribute::trackStatistics() 6421 void trackStatistics() const override { 6422 STATS_DECLTRACK_FLOATING_ATTR(value_simplify) 6423 } 6424 }; 6425 6426 struct AAValueSimplifyFunction : AAValueSimplifyImpl { 6427 AAValueSimplifyFunction(const IRPosition &IRP, Attributor &A) 6428 : AAValueSimplifyImpl(IRP, A) {} 6429 6430 /// See AbstractAttribute::initialize(...). 6431 void initialize(Attributor &A) override { 6432 SimplifiedAssociatedValue = nullptr; 6433 indicateOptimisticFixpoint(); 6434 } 6435 /// See AbstractAttribute::initialize(...). 6436 ChangeStatus updateImpl(Attributor &A) override { 6437 llvm_unreachable( 6438 "AAValueSimplify(Function|CallSite)::updateImpl will not be called"); 6439 } 6440 /// See AbstractAttribute::trackStatistics() 6441 void trackStatistics() const override { 6442 STATS_DECLTRACK_FN_ATTR(value_simplify) 6443 } 6444 }; 6445 6446 struct AAValueSimplifyCallSite : AAValueSimplifyFunction { 6447 AAValueSimplifyCallSite(const IRPosition &IRP, Attributor &A) 6448 : AAValueSimplifyFunction(IRP, A) {} 6449 /// See AbstractAttribute::trackStatistics() 6450 void trackStatistics() const override { 6451 STATS_DECLTRACK_CS_ATTR(value_simplify) 6452 } 6453 }; 6454 6455 struct AAValueSimplifyCallSiteReturned : AAValueSimplifyImpl { 6456 AAValueSimplifyCallSiteReturned(const IRPosition &IRP, Attributor &A) 6457 : AAValueSimplifyImpl(IRP, A) {} 6458 6459 void initialize(Attributor &A) override { 6460 AAValueSimplifyImpl::initialize(A); 6461 Function *Fn = getAssociatedFunction(); 6462 assert(Fn && "Did expect an associted function"); 6463 for (Argument &Arg : Fn->args()) { 6464 if (Arg.hasReturnedAttr()) { 6465 auto IRP = IRPosition::callsite_argument(*cast<CallBase>(getCtxI()), 6466 Arg.getArgNo()); 6467 if (IRP.getPositionKind() == IRPosition::IRP_CALL_SITE_ARGUMENT && 6468 checkAndUpdate(A, *this, IRP)) 6469 indicateOptimisticFixpoint(); 6470 else 6471 indicatePessimisticFixpoint(); 6472 return; 6473 } 6474 } 6475 } 6476 6477 /// See AbstractAttribute::updateImpl(...). 6478 ChangeStatus updateImpl(Attributor &A) override { 6479 return indicatePessimisticFixpoint(); 6480 } 6481 6482 void trackStatistics() const override { 6483 STATS_DECLTRACK_CSRET_ATTR(value_simplify) 6484 } 6485 }; 6486 6487 struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating { 6488 AAValueSimplifyCallSiteArgument(const IRPosition &IRP, Attributor &A) 6489 : AAValueSimplifyFloating(IRP, A) {} 6490 6491 /// See AbstractAttribute::manifest(...). 6492 ChangeStatus manifest(Attributor &A) override { 6493 ChangeStatus Changed = ChangeStatus::UNCHANGED; 6494 // TODO: We should avoid simplification duplication to begin with. 6495 auto *FloatAA = A.lookupAAFor<AAValueSimplify>( 6496 IRPosition::value(getAssociatedValue()), this, DepClassTy::NONE); 6497 if (FloatAA && FloatAA->getState().isValidState()) 6498 return Changed; 6499 6500 if (auto *NewV = manifestReplacementValue(A, getCtxI())) { 6501 Use &U = cast<CallBase>(&getAnchorValue()) 6502 ->getArgOperandUse(getCallSiteArgNo()); 6503 if (A.changeUseAfterManifest(U, *NewV)) 6504 Changed = ChangeStatus::CHANGED; 6505 } 6506 6507 return Changed | AAValueSimplify::manifest(A); 6508 } 6509 6510 void trackStatistics() const override { 6511 STATS_DECLTRACK_CSARG_ATTR(value_simplify) 6512 } 6513 }; 6514 } // namespace 6515 6516 /// ----------------------- Heap-To-Stack Conversion --------------------------- 6517 namespace { 6518 struct AAHeapToStackFunction final : public AAHeapToStack { 6519 6520 struct AllocationInfo { 6521 /// The call that allocates the memory. 6522 CallBase *const CB; 6523 6524 /// The library function id for the allocation. 6525 LibFunc LibraryFunctionId = NotLibFunc; 6526 6527 /// The status wrt. a rewrite. 6528 enum { 6529 STACK_DUE_TO_USE, 6530 STACK_DUE_TO_FREE, 6531 INVALID, 6532 } Status = STACK_DUE_TO_USE; 6533 6534 /// Flag to indicate if we encountered a use that might free this allocation 6535 /// but which is not in the deallocation infos. 6536 bool HasPotentiallyFreeingUnknownUses = false; 6537 6538 /// Flag to indicate that we should place the new alloca in the function 6539 /// entry block rather than where the call site (CB) is. 6540 bool MoveAllocaIntoEntry = true; 6541 6542 /// The set of free calls that use this allocation. 6543 SmallSetVector<CallBase *, 1> PotentialFreeCalls{}; 6544 }; 6545 6546 struct DeallocationInfo { 6547 /// The call that deallocates the memory. 6548 CallBase *const CB; 6549 /// The value freed by the call. 6550 Value *FreedOp; 6551 6552 /// Flag to indicate if we don't know all objects this deallocation might 6553 /// free. 6554 bool MightFreeUnknownObjects = false; 6555 6556 /// The set of allocation calls that are potentially freed. 6557 SmallSetVector<CallBase *, 1> PotentialAllocationCalls{}; 6558 }; 6559 6560 AAHeapToStackFunction(const IRPosition &IRP, Attributor &A) 6561 : AAHeapToStack(IRP, A) {} 6562 6563 ~AAHeapToStackFunction() { 6564 // Ensure we call the destructor so we release any memory allocated in the 6565 // sets. 6566 for (auto &It : AllocationInfos) 6567 It.second->~AllocationInfo(); 6568 for (auto &It : DeallocationInfos) 6569 It.second->~DeallocationInfo(); 6570 } 6571 6572 void initialize(Attributor &A) override { 6573 AAHeapToStack::initialize(A); 6574 6575 const Function *F = getAnchorScope(); 6576 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F); 6577 6578 auto AllocationIdentifierCB = [&](Instruction &I) { 6579 CallBase *CB = dyn_cast<CallBase>(&I); 6580 if (!CB) 6581 return true; 6582 if (Value *FreedOp = getFreedOperand(CB, TLI)) { 6583 DeallocationInfos[CB] = new (A.Allocator) DeallocationInfo{CB, FreedOp}; 6584 return true; 6585 } 6586 // To do heap to stack, we need to know that the allocation itself is 6587 // removable once uses are rewritten, and that we can initialize the 6588 // alloca to the same pattern as the original allocation result. 6589 if (isRemovableAlloc(CB, TLI)) { 6590 auto *I8Ty = Type::getInt8Ty(CB->getParent()->getContext()); 6591 if (nullptr != getInitialValueOfAllocation(CB, TLI, I8Ty)) { 6592 AllocationInfo *AI = new (A.Allocator) AllocationInfo{CB}; 6593 AllocationInfos[CB] = AI; 6594 if (TLI) 6595 TLI->getLibFunc(*CB, AI->LibraryFunctionId); 6596 } 6597 } 6598 return true; 6599 }; 6600 6601 bool UsedAssumedInformation = false; 6602 bool Success = A.checkForAllCallLikeInstructions( 6603 AllocationIdentifierCB, *this, UsedAssumedInformation, 6604 /* CheckBBLivenessOnly */ false, 6605 /* CheckPotentiallyDead */ true); 6606 (void)Success; 6607 assert(Success && "Did not expect the call base visit callback to fail!"); 6608 6609 Attributor::SimplifictionCallbackTy SCB = 6610 [](const IRPosition &, const AbstractAttribute *, 6611 bool &) -> std::optional<Value *> { return nullptr; }; 6612 for (const auto &It : AllocationInfos) 6613 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first), 6614 SCB); 6615 for (const auto &It : DeallocationInfos) 6616 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first), 6617 SCB); 6618 } 6619 6620 const std::string getAsStr(Attributor *A) const override { 6621 unsigned NumH2SMallocs = 0, NumInvalidMallocs = 0; 6622 for (const auto &It : AllocationInfos) { 6623 if (It.second->Status == AllocationInfo::INVALID) 6624 ++NumInvalidMallocs; 6625 else 6626 ++NumH2SMallocs; 6627 } 6628 return "[H2S] Mallocs Good/Bad: " + std::to_string(NumH2SMallocs) + "/" + 6629 std::to_string(NumInvalidMallocs); 6630 } 6631 6632 /// See AbstractAttribute::trackStatistics(). 6633 void trackStatistics() const override { 6634 STATS_DECL( 6635 MallocCalls, Function, 6636 "Number of malloc/calloc/aligned_alloc calls converted to allocas"); 6637 for (const auto &It : AllocationInfos) 6638 if (It.second->Status != AllocationInfo::INVALID) 6639 ++BUILD_STAT_NAME(MallocCalls, Function); 6640 } 6641 6642 bool isAssumedHeapToStack(const CallBase &CB) const override { 6643 if (isValidState()) 6644 if (AllocationInfo *AI = 6645 AllocationInfos.lookup(const_cast<CallBase *>(&CB))) 6646 return AI->Status != AllocationInfo::INVALID; 6647 return false; 6648 } 6649 6650 bool isAssumedHeapToStackRemovedFree(CallBase &CB) const override { 6651 if (!isValidState()) 6652 return false; 6653 6654 for (const auto &It : AllocationInfos) { 6655 AllocationInfo &AI = *It.second; 6656 if (AI.Status == AllocationInfo::INVALID) 6657 continue; 6658 6659 if (AI.PotentialFreeCalls.count(&CB)) 6660 return true; 6661 } 6662 6663 return false; 6664 } 6665 6666 ChangeStatus manifest(Attributor &A) override { 6667 assert(getState().isValidState() && 6668 "Attempted to manifest an invalid state!"); 6669 6670 ChangeStatus HasChanged = ChangeStatus::UNCHANGED; 6671 Function *F = getAnchorScope(); 6672 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F); 6673 6674 for (auto &It : AllocationInfos) { 6675 AllocationInfo &AI = *It.second; 6676 if (AI.Status == AllocationInfo::INVALID) 6677 continue; 6678 6679 for (CallBase *FreeCall : AI.PotentialFreeCalls) { 6680 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n"); 6681 A.deleteAfterManifest(*FreeCall); 6682 HasChanged = ChangeStatus::CHANGED; 6683 } 6684 6685 LLVM_DEBUG(dbgs() << "H2S: Removing malloc-like call: " << *AI.CB 6686 << "\n"); 6687 6688 auto Remark = [&](OptimizationRemark OR) { 6689 LibFunc IsAllocShared; 6690 if (TLI->getLibFunc(*AI.CB, IsAllocShared)) 6691 if (IsAllocShared == LibFunc___kmpc_alloc_shared) 6692 return OR << "Moving globalized variable to the stack."; 6693 return OR << "Moving memory allocation from the heap to the stack."; 6694 }; 6695 if (AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared) 6696 A.emitRemark<OptimizationRemark>(AI.CB, "OMP110", Remark); 6697 else 6698 A.emitRemark<OptimizationRemark>(AI.CB, "HeapToStack", Remark); 6699 6700 const DataLayout &DL = A.getInfoCache().getDL(); 6701 Value *Size; 6702 std::optional<APInt> SizeAPI = getSize(A, *this, AI); 6703 if (SizeAPI) { 6704 Size = ConstantInt::get(AI.CB->getContext(), *SizeAPI); 6705 } else { 6706 LLVMContext &Ctx = AI.CB->getContext(); 6707 ObjectSizeOpts Opts; 6708 ObjectSizeOffsetEvaluator Eval(DL, TLI, Ctx, Opts); 6709 SizeOffsetEvalType SizeOffsetPair = Eval.compute(AI.CB); 6710 assert(SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown() && 6711 cast<ConstantInt>(SizeOffsetPair.second)->isZero()); 6712 Size = SizeOffsetPair.first; 6713 } 6714 6715 Instruction *IP = 6716 AI.MoveAllocaIntoEntry ? &F->getEntryBlock().front() : AI.CB; 6717 6718 Align Alignment(1); 6719 if (MaybeAlign RetAlign = AI.CB->getRetAlign()) 6720 Alignment = std::max(Alignment, *RetAlign); 6721 if (Value *Align = getAllocAlignment(AI.CB, TLI)) { 6722 std::optional<APInt> AlignmentAPI = getAPInt(A, *this, *Align); 6723 assert(AlignmentAPI && AlignmentAPI->getZExtValue() > 0 && 6724 "Expected an alignment during manifest!"); 6725 Alignment = 6726 std::max(Alignment, assumeAligned(AlignmentAPI->getZExtValue())); 6727 } 6728 6729 // TODO: Hoist the alloca towards the function entry. 6730 unsigned AS = DL.getAllocaAddrSpace(); 6731 Instruction *Alloca = 6732 new AllocaInst(Type::getInt8Ty(F->getContext()), AS, Size, Alignment, 6733 AI.CB->getName() + ".h2s", IP); 6734 6735 if (Alloca->getType() != AI.CB->getType()) 6736 Alloca = BitCastInst::CreatePointerBitCastOrAddrSpaceCast( 6737 Alloca, AI.CB->getType(), "malloc_cast", AI.CB); 6738 6739 auto *I8Ty = Type::getInt8Ty(F->getContext()); 6740 auto *InitVal = getInitialValueOfAllocation(AI.CB, TLI, I8Ty); 6741 assert(InitVal && 6742 "Must be able to materialize initial memory state of allocation"); 6743 6744 A.changeAfterManifest(IRPosition::inst(*AI.CB), *Alloca); 6745 6746 if (auto *II = dyn_cast<InvokeInst>(AI.CB)) { 6747 auto *NBB = II->getNormalDest(); 6748 BranchInst::Create(NBB, AI.CB->getParent()); 6749 A.deleteAfterManifest(*AI.CB); 6750 } else { 6751 A.deleteAfterManifest(*AI.CB); 6752 } 6753 6754 // Initialize the alloca with the same value as used by the allocation 6755 // function. We can skip undef as the initial value of an alloc is 6756 // undef, and the memset would simply end up being DSEd. 6757 if (!isa<UndefValue>(InitVal)) { 6758 IRBuilder<> Builder(Alloca->getNextNode()); 6759 // TODO: Use alignment above if align!=1 6760 Builder.CreateMemSet(Alloca, InitVal, Size, std::nullopt); 6761 } 6762 HasChanged = ChangeStatus::CHANGED; 6763 } 6764 6765 return HasChanged; 6766 } 6767 6768 std::optional<APInt> getAPInt(Attributor &A, const AbstractAttribute &AA, 6769 Value &V) { 6770 bool UsedAssumedInformation = false; 6771 std::optional<Constant *> SimpleV = 6772 A.getAssumedConstant(V, AA, UsedAssumedInformation); 6773 if (!SimpleV) 6774 return APInt(64, 0); 6775 if (auto *CI = dyn_cast_or_null<ConstantInt>(*SimpleV)) 6776 return CI->getValue(); 6777 return std::nullopt; 6778 } 6779 6780 std::optional<APInt> getSize(Attributor &A, const AbstractAttribute &AA, 6781 AllocationInfo &AI) { 6782 auto Mapper = [&](const Value *V) -> const Value * { 6783 bool UsedAssumedInformation = false; 6784 if (std::optional<Constant *> SimpleV = 6785 A.getAssumedConstant(*V, AA, UsedAssumedInformation)) 6786 if (*SimpleV) 6787 return *SimpleV; 6788 return V; 6789 }; 6790 6791 const Function *F = getAnchorScope(); 6792 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F); 6793 return getAllocSize(AI.CB, TLI, Mapper); 6794 } 6795 6796 /// Collection of all malloc-like calls in a function with associated 6797 /// information. 6798 MapVector<CallBase *, AllocationInfo *> AllocationInfos; 6799 6800 /// Collection of all free-like calls in a function with associated 6801 /// information. 6802 MapVector<CallBase *, DeallocationInfo *> DeallocationInfos; 6803 6804 ChangeStatus updateImpl(Attributor &A) override; 6805 }; 6806 6807 ChangeStatus AAHeapToStackFunction::updateImpl(Attributor &A) { 6808 ChangeStatus Changed = ChangeStatus::UNCHANGED; 6809 const Function *F = getAnchorScope(); 6810 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F); 6811 6812 const auto *LivenessAA = 6813 A.getAAFor<AAIsDead>(*this, IRPosition::function(*F), DepClassTy::NONE); 6814 6815 MustBeExecutedContextExplorer *Explorer = 6816 A.getInfoCache().getMustBeExecutedContextExplorer(); 6817 6818 bool StackIsAccessibleByOtherThreads = 6819 A.getInfoCache().stackIsAccessibleByOtherThreads(); 6820 6821 LoopInfo *LI = 6822 A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(*F); 6823 std::optional<bool> MayContainIrreducibleControl; 6824 auto IsInLoop = [&](BasicBlock &BB) { 6825 if (&F->getEntryBlock() == &BB) 6826 return false; 6827 if (!MayContainIrreducibleControl.has_value()) 6828 MayContainIrreducibleControl = mayContainIrreducibleControl(*F, LI); 6829 if (*MayContainIrreducibleControl) 6830 return true; 6831 if (!LI) 6832 return true; 6833 return LI->getLoopFor(&BB) != nullptr; 6834 }; 6835 6836 // Flag to ensure we update our deallocation information at most once per 6837 // updateImpl call and only if we use the free check reasoning. 6838 bool HasUpdatedFrees = false; 6839 6840 auto UpdateFrees = [&]() { 6841 HasUpdatedFrees = true; 6842 6843 for (auto &It : DeallocationInfos) { 6844 DeallocationInfo &DI = *It.second; 6845 // For now we cannot use deallocations that have unknown inputs, skip 6846 // them. 6847 if (DI.MightFreeUnknownObjects) 6848 continue; 6849 6850 // No need to analyze dead calls, ignore them instead. 6851 bool UsedAssumedInformation = false; 6852 if (A.isAssumedDead(*DI.CB, this, LivenessAA, UsedAssumedInformation, 6853 /* CheckBBLivenessOnly */ true)) 6854 continue; 6855 6856 // Use the non-optimistic version to get the freed object. 6857 Value *Obj = getUnderlyingObject(DI.FreedOp); 6858 if (!Obj) { 6859 LLVM_DEBUG(dbgs() << "[H2S] Unknown underlying object for free!\n"); 6860 DI.MightFreeUnknownObjects = true; 6861 continue; 6862 } 6863 6864 // Free of null and undef can be ignored as no-ops (or UB in the latter 6865 // case). 6866 if (isa<ConstantPointerNull>(Obj) || isa<UndefValue>(Obj)) 6867 continue; 6868 6869 CallBase *ObjCB = dyn_cast<CallBase>(Obj); 6870 if (!ObjCB) { 6871 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-call object: " << *Obj 6872 << "\n"); 6873 DI.MightFreeUnknownObjects = true; 6874 continue; 6875 } 6876 6877 AllocationInfo *AI = AllocationInfos.lookup(ObjCB); 6878 if (!AI) { 6879 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-allocation object: " << *Obj 6880 << "\n"); 6881 DI.MightFreeUnknownObjects = true; 6882 continue; 6883 } 6884 6885 DI.PotentialAllocationCalls.insert(ObjCB); 6886 } 6887 }; 6888 6889 auto FreeCheck = [&](AllocationInfo &AI) { 6890 // If the stack is not accessible by other threads, the "must-free" logic 6891 // doesn't apply as the pointer could be shared and needs to be places in 6892 // "shareable" memory. 6893 if (!StackIsAccessibleByOtherThreads) { 6894 bool IsKnownNoSycn; 6895 if (!AA::hasAssumedIRAttr<Attribute::NoSync>( 6896 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoSycn)) { 6897 LLVM_DEBUG( 6898 dbgs() << "[H2S] found an escaping use, stack is not accessible by " 6899 "other threads and function is not nosync:\n"); 6900 return false; 6901 } 6902 } 6903 if (!HasUpdatedFrees) 6904 UpdateFrees(); 6905 6906 // TODO: Allow multi exit functions that have different free calls. 6907 if (AI.PotentialFreeCalls.size() != 1) { 6908 LLVM_DEBUG(dbgs() << "[H2S] did not find one free call but " 6909 << AI.PotentialFreeCalls.size() << "\n"); 6910 return false; 6911 } 6912 CallBase *UniqueFree = *AI.PotentialFreeCalls.begin(); 6913 DeallocationInfo *DI = DeallocationInfos.lookup(UniqueFree); 6914 if (!DI) { 6915 LLVM_DEBUG( 6916 dbgs() << "[H2S] unique free call was not known as deallocation call " 6917 << *UniqueFree << "\n"); 6918 return false; 6919 } 6920 if (DI->MightFreeUnknownObjects) { 6921 LLVM_DEBUG( 6922 dbgs() << "[H2S] unique free call might free unknown allocations\n"); 6923 return false; 6924 } 6925 if (DI->PotentialAllocationCalls.empty()) 6926 return true; 6927 if (DI->PotentialAllocationCalls.size() > 1) { 6928 LLVM_DEBUG(dbgs() << "[H2S] unique free call might free " 6929 << DI->PotentialAllocationCalls.size() 6930 << " different allocations\n"); 6931 return false; 6932 } 6933 if (*DI->PotentialAllocationCalls.begin() != AI.CB) { 6934 LLVM_DEBUG( 6935 dbgs() 6936 << "[H2S] unique free call not known to free this allocation but " 6937 << **DI->PotentialAllocationCalls.begin() << "\n"); 6938 return false; 6939 } 6940 Instruction *CtxI = isa<InvokeInst>(AI.CB) ? AI.CB : AI.CB->getNextNode(); 6941 if (!Explorer || !Explorer->findInContextOf(UniqueFree, CtxI)) { 6942 LLVM_DEBUG( 6943 dbgs() 6944 << "[H2S] unique free call might not be executed with the allocation " 6945 << *UniqueFree << "\n"); 6946 return false; 6947 } 6948 return true; 6949 }; 6950 6951 auto UsesCheck = [&](AllocationInfo &AI) { 6952 bool ValidUsesOnly = true; 6953 6954 auto Pred = [&](const Use &U, bool &Follow) -> bool { 6955 Instruction *UserI = cast<Instruction>(U.getUser()); 6956 if (isa<LoadInst>(UserI)) 6957 return true; 6958 if (auto *SI = dyn_cast<StoreInst>(UserI)) { 6959 if (SI->getValueOperand() == U.get()) { 6960 LLVM_DEBUG(dbgs() 6961 << "[H2S] escaping store to memory: " << *UserI << "\n"); 6962 ValidUsesOnly = false; 6963 } else { 6964 // A store into the malloc'ed memory is fine. 6965 } 6966 return true; 6967 } 6968 if (auto *CB = dyn_cast<CallBase>(UserI)) { 6969 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd()) 6970 return true; 6971 if (DeallocationInfos.count(CB)) { 6972 AI.PotentialFreeCalls.insert(CB); 6973 return true; 6974 } 6975 6976 unsigned ArgNo = CB->getArgOperandNo(&U); 6977 auto CBIRP = IRPosition::callsite_argument(*CB, ArgNo); 6978 6979 bool IsKnownNoCapture; 6980 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>( 6981 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoCapture); 6982 6983 // If a call site argument use is nofree, we are fine. 6984 bool IsKnownNoFree; 6985 bool IsAssumedNoFree = AA::hasAssumedIRAttr<Attribute::NoFree>( 6986 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoFree); 6987 6988 if (!IsAssumedNoCapture || 6989 (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared && 6990 !IsAssumedNoFree)) { 6991 AI.HasPotentiallyFreeingUnknownUses |= !IsAssumedNoFree; 6992 6993 // Emit a missed remark if this is missed OpenMP globalization. 6994 auto Remark = [&](OptimizationRemarkMissed ORM) { 6995 return ORM 6996 << "Could not move globalized variable to the stack. " 6997 "Variable is potentially captured in call. Mark " 6998 "parameter as `__attribute__((noescape))` to override."; 6999 }; 7000 7001 if (ValidUsesOnly && 7002 AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared) 7003 A.emitRemark<OptimizationRemarkMissed>(CB, "OMP113", Remark); 7004 7005 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n"); 7006 ValidUsesOnly = false; 7007 } 7008 return true; 7009 } 7010 7011 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) || 7012 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) { 7013 Follow = true; 7014 return true; 7015 } 7016 // Unknown user for which we can not track uses further (in a way that 7017 // makes sense). 7018 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n"); 7019 ValidUsesOnly = false; 7020 return true; 7021 }; 7022 if (!A.checkForAllUses(Pred, *this, *AI.CB, /* CheckBBLivenessOnly */ false, 7023 DepClassTy::OPTIONAL, /* IgnoreDroppableUses */ true, 7024 [&](const Use &OldU, const Use &NewU) { 7025 auto *SI = dyn_cast<StoreInst>(OldU.getUser()); 7026 return !SI || StackIsAccessibleByOtherThreads || 7027 AA::isAssumedThreadLocalObject( 7028 A, *SI->getPointerOperand(), *this); 7029 })) 7030 return false; 7031 return ValidUsesOnly; 7032 }; 7033 7034 // The actual update starts here. We look at all allocations and depending on 7035 // their status perform the appropriate check(s). 7036 for (auto &It : AllocationInfos) { 7037 AllocationInfo &AI = *It.second; 7038 if (AI.Status == AllocationInfo::INVALID) 7039 continue; 7040 7041 if (Value *Align = getAllocAlignment(AI.CB, TLI)) { 7042 std::optional<APInt> APAlign = getAPInt(A, *this, *Align); 7043 if (!APAlign) { 7044 // Can't generate an alloca which respects the required alignment 7045 // on the allocation. 7046 LLVM_DEBUG(dbgs() << "[H2S] Unknown allocation alignment: " << *AI.CB 7047 << "\n"); 7048 AI.Status = AllocationInfo::INVALID; 7049 Changed = ChangeStatus::CHANGED; 7050 continue; 7051 } 7052 if (APAlign->ugt(llvm::Value::MaximumAlignment) || 7053 !APAlign->isPowerOf2()) { 7054 LLVM_DEBUG(dbgs() << "[H2S] Invalid allocation alignment: " << APAlign 7055 << "\n"); 7056 AI.Status = AllocationInfo::INVALID; 7057 Changed = ChangeStatus::CHANGED; 7058 continue; 7059 } 7060 } 7061 7062 std::optional<APInt> Size = getSize(A, *this, AI); 7063 if (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared && 7064 MaxHeapToStackSize != -1) { 7065 if (!Size || Size->ugt(MaxHeapToStackSize)) { 7066 LLVM_DEBUG({ 7067 if (!Size) 7068 dbgs() << "[H2S] Unknown allocation size: " << *AI.CB << "\n"; 7069 else 7070 dbgs() << "[H2S] Allocation size too large: " << *AI.CB << " vs. " 7071 << MaxHeapToStackSize << "\n"; 7072 }); 7073 7074 AI.Status = AllocationInfo::INVALID; 7075 Changed = ChangeStatus::CHANGED; 7076 continue; 7077 } 7078 } 7079 7080 switch (AI.Status) { 7081 case AllocationInfo::STACK_DUE_TO_USE: 7082 if (UsesCheck(AI)) 7083 break; 7084 AI.Status = AllocationInfo::STACK_DUE_TO_FREE; 7085 [[fallthrough]]; 7086 case AllocationInfo::STACK_DUE_TO_FREE: 7087 if (FreeCheck(AI)) 7088 break; 7089 AI.Status = AllocationInfo::INVALID; 7090 Changed = ChangeStatus::CHANGED; 7091 break; 7092 case AllocationInfo::INVALID: 7093 llvm_unreachable("Invalid allocations should never reach this point!"); 7094 }; 7095 7096 // Check if we still think we can move it into the entry block. If the 7097 // alloca comes from a converted __kmpc_alloc_shared then we can usually 7098 // ignore the potential compilations associated with loops. 7099 bool IsGlobalizedLocal = 7100 AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared; 7101 if (AI.MoveAllocaIntoEntry && 7102 (!Size.has_value() || 7103 (!IsGlobalizedLocal && IsInLoop(*AI.CB->getParent())))) 7104 AI.MoveAllocaIntoEntry = false; 7105 } 7106 7107 return Changed; 7108 } 7109 } // namespace 7110 7111 /// ----------------------- Privatizable Pointers ------------------------------ 7112 namespace { 7113 struct AAPrivatizablePtrImpl : public AAPrivatizablePtr { 7114 AAPrivatizablePtrImpl(const IRPosition &IRP, Attributor &A) 7115 : AAPrivatizablePtr(IRP, A), PrivatizableType(std::nullopt) {} 7116 7117 ChangeStatus indicatePessimisticFixpoint() override { 7118 AAPrivatizablePtr::indicatePessimisticFixpoint(); 7119 PrivatizableType = nullptr; 7120 return ChangeStatus::CHANGED; 7121 } 7122 7123 /// Identify the type we can chose for a private copy of the underlying 7124 /// argument. std::nullopt means it is not clear yet, nullptr means there is 7125 /// none. 7126 virtual std::optional<Type *> identifyPrivatizableType(Attributor &A) = 0; 7127 7128 /// Return a privatizable type that encloses both T0 and T1. 7129 /// TODO: This is merely a stub for now as we should manage a mapping as well. 7130 std::optional<Type *> combineTypes(std::optional<Type *> T0, 7131 std::optional<Type *> T1) { 7132 if (!T0) 7133 return T1; 7134 if (!T1) 7135 return T0; 7136 if (T0 == T1) 7137 return T0; 7138 return nullptr; 7139 } 7140 7141 std::optional<Type *> getPrivatizableType() const override { 7142 return PrivatizableType; 7143 } 7144 7145 const std::string getAsStr(Attributor *A) const override { 7146 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]"; 7147 } 7148 7149 protected: 7150 std::optional<Type *> PrivatizableType; 7151 }; 7152 7153 // TODO: Do this for call site arguments (probably also other values) as well. 7154 7155 struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl { 7156 AAPrivatizablePtrArgument(const IRPosition &IRP, Attributor &A) 7157 : AAPrivatizablePtrImpl(IRP, A) {} 7158 7159 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...) 7160 std::optional<Type *> identifyPrivatizableType(Attributor &A) override { 7161 // If this is a byval argument and we know all the call sites (so we can 7162 // rewrite them), there is no need to check them explicitly. 7163 bool UsedAssumedInformation = false; 7164 SmallVector<Attribute, 1> Attrs; 7165 A.getAttrs(getIRPosition(), {Attribute::ByVal}, Attrs, 7166 /* IgnoreSubsumingPositions */ true); 7167 if (!Attrs.empty() && 7168 A.checkForAllCallSites([](AbstractCallSite ACS) { return true; }, *this, 7169 true, UsedAssumedInformation)) 7170 return Attrs[0].getValueAsType(); 7171 7172 std::optional<Type *> Ty; 7173 unsigned ArgNo = getIRPosition().getCallSiteArgNo(); 7174 7175 // Make sure the associated call site argument has the same type at all call 7176 // sites and it is an allocation we know is safe to privatize, for now that 7177 // means we only allow alloca instructions. 7178 // TODO: We can additionally analyze the accesses in the callee to create 7179 // the type from that information instead. That is a little more 7180 // involved and will be done in a follow up patch. 7181 auto CallSiteCheck = [&](AbstractCallSite ACS) { 7182 IRPosition ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo); 7183 // Check if a coresponding argument was found or if it is one not 7184 // associated (which can happen for callback calls). 7185 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID) 7186 return false; 7187 7188 // Check that all call sites agree on a type. 7189 auto *PrivCSArgAA = 7190 A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos, DepClassTy::REQUIRED); 7191 if (!PrivCSArgAA) 7192 return false; 7193 std::optional<Type *> CSTy = PrivCSArgAA->getPrivatizableType(); 7194 7195 LLVM_DEBUG({ 7196 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: "; 7197 if (CSTy && *CSTy) 7198 (*CSTy)->print(dbgs()); 7199 else if (CSTy) 7200 dbgs() << "<nullptr>"; 7201 else 7202 dbgs() << "<none>"; 7203 }); 7204 7205 Ty = combineTypes(Ty, CSTy); 7206 7207 LLVM_DEBUG({ 7208 dbgs() << " : New Type: "; 7209 if (Ty && *Ty) 7210 (*Ty)->print(dbgs()); 7211 else if (Ty) 7212 dbgs() << "<nullptr>"; 7213 else 7214 dbgs() << "<none>"; 7215 dbgs() << "\n"; 7216 }); 7217 7218 return !Ty || *Ty; 7219 }; 7220 7221 if (!A.checkForAllCallSites(CallSiteCheck, *this, true, 7222 UsedAssumedInformation)) 7223 return nullptr; 7224 return Ty; 7225 } 7226 7227 /// See AbstractAttribute::updateImpl(...). 7228 ChangeStatus updateImpl(Attributor &A) override { 7229 PrivatizableType = identifyPrivatizableType(A); 7230 if (!PrivatizableType) 7231 return ChangeStatus::UNCHANGED; 7232 if (!*PrivatizableType) 7233 return indicatePessimisticFixpoint(); 7234 7235 // The dependence is optional so we don't give up once we give up on the 7236 // alignment. 7237 A.getAAFor<AAAlign>(*this, IRPosition::value(getAssociatedValue()), 7238 DepClassTy::OPTIONAL); 7239 7240 // Avoid arguments with padding for now. 7241 if (!A.hasAttr(getIRPosition(), Attribute::ByVal) && 7242 !isDenselyPacked(*PrivatizableType, A.getInfoCache().getDL())) { 7243 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n"); 7244 return indicatePessimisticFixpoint(); 7245 } 7246 7247 // Collect the types that will replace the privatizable type in the function 7248 // signature. 7249 SmallVector<Type *, 16> ReplacementTypes; 7250 identifyReplacementTypes(*PrivatizableType, ReplacementTypes); 7251 7252 // Verify callee and caller agree on how the promoted argument would be 7253 // passed. 7254 Function &Fn = *getIRPosition().getAnchorScope(); 7255 const auto *TTI = 7256 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn); 7257 if (!TTI) { 7258 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Missing TTI for function " 7259 << Fn.getName() << "\n"); 7260 return indicatePessimisticFixpoint(); 7261 } 7262 7263 auto CallSiteCheck = [&](AbstractCallSite ACS) { 7264 CallBase *CB = ACS.getInstruction(); 7265 return TTI->areTypesABICompatible( 7266 CB->getCaller(), 7267 dyn_cast_if_present<Function>(CB->getCalledOperand()), 7268 ReplacementTypes); 7269 }; 7270 bool UsedAssumedInformation = false; 7271 if (!A.checkForAllCallSites(CallSiteCheck, *this, true, 7272 UsedAssumedInformation)) { 7273 LLVM_DEBUG( 7274 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for " 7275 << Fn.getName() << "\n"); 7276 return indicatePessimisticFixpoint(); 7277 } 7278 7279 // Register a rewrite of the argument. 7280 Argument *Arg = getAssociatedArgument(); 7281 if (!A.isValidFunctionSignatureRewrite(*Arg, ReplacementTypes)) { 7282 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n"); 7283 return indicatePessimisticFixpoint(); 7284 } 7285 7286 unsigned ArgNo = Arg->getArgNo(); 7287 7288 // Helper to check if for the given call site the associated argument is 7289 // passed to a callback where the privatization would be different. 7290 auto IsCompatiblePrivArgOfCallback = [&](CallBase &CB) { 7291 SmallVector<const Use *, 4> CallbackUses; 7292 AbstractCallSite::getCallbackUses(CB, CallbackUses); 7293 for (const Use *U : CallbackUses) { 7294 AbstractCallSite CBACS(U); 7295 assert(CBACS && CBACS.isCallbackCall()); 7296 for (Argument &CBArg : CBACS.getCalledFunction()->args()) { 7297 int CBArgNo = CBACS.getCallArgOperandNo(CBArg); 7298 7299 LLVM_DEBUG({ 7300 dbgs() 7301 << "[AAPrivatizablePtr] Argument " << *Arg 7302 << "check if can be privatized in the context of its parent (" 7303 << Arg->getParent()->getName() 7304 << ")\n[AAPrivatizablePtr] because it is an argument in a " 7305 "callback (" 7306 << CBArgNo << "@" << CBACS.getCalledFunction()->getName() 7307 << ")\n[AAPrivatizablePtr] " << CBArg << " : " 7308 << CBACS.getCallArgOperand(CBArg) << " vs " 7309 << CB.getArgOperand(ArgNo) << "\n" 7310 << "[AAPrivatizablePtr] " << CBArg << " : " 7311 << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n"; 7312 }); 7313 7314 if (CBArgNo != int(ArgNo)) 7315 continue; 7316 const auto *CBArgPrivAA = A.getAAFor<AAPrivatizablePtr>( 7317 *this, IRPosition::argument(CBArg), DepClassTy::REQUIRED); 7318 if (CBArgPrivAA && CBArgPrivAA->isValidState()) { 7319 auto CBArgPrivTy = CBArgPrivAA->getPrivatizableType(); 7320 if (!CBArgPrivTy) 7321 continue; 7322 if (*CBArgPrivTy == PrivatizableType) 7323 continue; 7324 } 7325 7326 LLVM_DEBUG({ 7327 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg 7328 << " cannot be privatized in the context of its parent (" 7329 << Arg->getParent()->getName() 7330 << ")\n[AAPrivatizablePtr] because it is an argument in a " 7331 "callback (" 7332 << CBArgNo << "@" << CBACS.getCalledFunction()->getName() 7333 << ").\n[AAPrivatizablePtr] for which the argument " 7334 "privatization is not compatible.\n"; 7335 }); 7336 return false; 7337 } 7338 } 7339 return true; 7340 }; 7341 7342 // Helper to check if for the given call site the associated argument is 7343 // passed to a direct call where the privatization would be different. 7344 auto IsCompatiblePrivArgOfDirectCS = [&](AbstractCallSite ACS) { 7345 CallBase *DC = cast<CallBase>(ACS.getInstruction()); 7346 int DCArgNo = ACS.getCallArgOperandNo(ArgNo); 7347 assert(DCArgNo >= 0 && unsigned(DCArgNo) < DC->arg_size() && 7348 "Expected a direct call operand for callback call operand"); 7349 7350 Function *DCCallee = 7351 dyn_cast_if_present<Function>(DC->getCalledOperand()); 7352 LLVM_DEBUG({ 7353 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg 7354 << " check if be privatized in the context of its parent (" 7355 << Arg->getParent()->getName() 7356 << ")\n[AAPrivatizablePtr] because it is an argument in a " 7357 "direct call of (" 7358 << DCArgNo << "@" << DCCallee->getName() << ").\n"; 7359 }); 7360 7361 if (unsigned(DCArgNo) < DCCallee->arg_size()) { 7362 const auto *DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>( 7363 *this, IRPosition::argument(*DCCallee->getArg(DCArgNo)), 7364 DepClassTy::REQUIRED); 7365 if (DCArgPrivAA && DCArgPrivAA->isValidState()) { 7366 auto DCArgPrivTy = DCArgPrivAA->getPrivatizableType(); 7367 if (!DCArgPrivTy) 7368 return true; 7369 if (*DCArgPrivTy == PrivatizableType) 7370 return true; 7371 } 7372 } 7373 7374 LLVM_DEBUG({ 7375 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg 7376 << " cannot be privatized in the context of its parent (" 7377 << Arg->getParent()->getName() 7378 << ")\n[AAPrivatizablePtr] because it is an argument in a " 7379 "direct call of (" 7380 << ACS.getInstruction()->getCalledOperand()->getName() 7381 << ").\n[AAPrivatizablePtr] for which the argument " 7382 "privatization is not compatible.\n"; 7383 }); 7384 return false; 7385 }; 7386 7387 // Helper to check if the associated argument is used at the given abstract 7388 // call site in a way that is incompatible with the privatization assumed 7389 // here. 7390 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) { 7391 if (ACS.isDirectCall()) 7392 return IsCompatiblePrivArgOfCallback(*ACS.getInstruction()); 7393 if (ACS.isCallbackCall()) 7394 return IsCompatiblePrivArgOfDirectCS(ACS); 7395 return false; 7396 }; 7397 7398 if (!A.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite, *this, true, 7399 UsedAssumedInformation)) 7400 return indicatePessimisticFixpoint(); 7401 7402 return ChangeStatus::UNCHANGED; 7403 } 7404 7405 /// Given a type to private \p PrivType, collect the constituates (which are 7406 /// used) in \p ReplacementTypes. 7407 static void 7408 identifyReplacementTypes(Type *PrivType, 7409 SmallVectorImpl<Type *> &ReplacementTypes) { 7410 // TODO: For now we expand the privatization type to the fullest which can 7411 // lead to dead arguments that need to be removed later. 7412 assert(PrivType && "Expected privatizable type!"); 7413 7414 // Traverse the type, extract constituate types on the outermost level. 7415 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) { 7416 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) 7417 ReplacementTypes.push_back(PrivStructType->getElementType(u)); 7418 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) { 7419 ReplacementTypes.append(PrivArrayType->getNumElements(), 7420 PrivArrayType->getElementType()); 7421 } else { 7422 ReplacementTypes.push_back(PrivType); 7423 } 7424 } 7425 7426 /// Initialize \p Base according to the type \p PrivType at position \p IP. 7427 /// The values needed are taken from the arguments of \p F starting at 7428 /// position \p ArgNo. 7429 static void createInitialization(Type *PrivType, Value &Base, Function &F, 7430 unsigned ArgNo, Instruction &IP) { 7431 assert(PrivType && "Expected privatizable type!"); 7432 7433 IRBuilder<NoFolder> IRB(&IP); 7434 const DataLayout &DL = F.getParent()->getDataLayout(); 7435 7436 // Traverse the type, build GEPs and stores. 7437 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) { 7438 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType); 7439 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) { 7440 Type *PointeeTy = PrivStructType->getElementType(u)->getPointerTo(); 7441 Value *Ptr = 7442 constructPointer(PointeeTy, PrivType, &Base, 7443 PrivStructLayout->getElementOffset(u), IRB, DL); 7444 new StoreInst(F.getArg(ArgNo + u), Ptr, &IP); 7445 } 7446 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) { 7447 Type *PointeeTy = PrivArrayType->getElementType(); 7448 Type *PointeePtrTy = PointeeTy->getPointerTo(); 7449 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy); 7450 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) { 7451 Value *Ptr = constructPointer(PointeePtrTy, PrivType, &Base, 7452 u * PointeeTySize, IRB, DL); 7453 new StoreInst(F.getArg(ArgNo + u), Ptr, &IP); 7454 } 7455 } else { 7456 new StoreInst(F.getArg(ArgNo), &Base, &IP); 7457 } 7458 } 7459 7460 /// Extract values from \p Base according to the type \p PrivType at the 7461 /// call position \p ACS. The values are appended to \p ReplacementValues. 7462 void createReplacementValues(Align Alignment, Type *PrivType, 7463 AbstractCallSite ACS, Value *Base, 7464 SmallVectorImpl<Value *> &ReplacementValues) { 7465 assert(Base && "Expected base value!"); 7466 assert(PrivType && "Expected privatizable type!"); 7467 Instruction *IP = ACS.getInstruction(); 7468 7469 IRBuilder<NoFolder> IRB(IP); 7470 const DataLayout &DL = IP->getModule()->getDataLayout(); 7471 7472 Type *PrivPtrType = PrivType->getPointerTo(); 7473 if (Base->getType() != PrivPtrType) 7474 Base = BitCastInst::CreatePointerBitCastOrAddrSpaceCast( 7475 Base, PrivPtrType, "", ACS.getInstruction()); 7476 7477 // Traverse the type, build GEPs and loads. 7478 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) { 7479 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType); 7480 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) { 7481 Type *PointeeTy = PrivStructType->getElementType(u); 7482 Value *Ptr = 7483 constructPointer(PointeeTy->getPointerTo(), PrivType, Base, 7484 PrivStructLayout->getElementOffset(u), IRB, DL); 7485 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP); 7486 L->setAlignment(Alignment); 7487 ReplacementValues.push_back(L); 7488 } 7489 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) { 7490 Type *PointeeTy = PrivArrayType->getElementType(); 7491 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy); 7492 Type *PointeePtrTy = PointeeTy->getPointerTo(); 7493 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) { 7494 Value *Ptr = constructPointer(PointeePtrTy, PrivType, Base, 7495 u * PointeeTySize, IRB, DL); 7496 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP); 7497 L->setAlignment(Alignment); 7498 ReplacementValues.push_back(L); 7499 } 7500 } else { 7501 LoadInst *L = new LoadInst(PrivType, Base, "", IP); 7502 L->setAlignment(Alignment); 7503 ReplacementValues.push_back(L); 7504 } 7505 } 7506 7507 /// See AbstractAttribute::manifest(...) 7508 ChangeStatus manifest(Attributor &A) override { 7509 if (!PrivatizableType) 7510 return ChangeStatus::UNCHANGED; 7511 assert(*PrivatizableType && "Expected privatizable type!"); 7512 7513 // Collect all tail calls in the function as we cannot allow new allocas to 7514 // escape into tail recursion. 7515 // TODO: Be smarter about new allocas escaping into tail calls. 7516 SmallVector<CallInst *, 16> TailCalls; 7517 bool UsedAssumedInformation = false; 7518 if (!A.checkForAllInstructions( 7519 [&](Instruction &I) { 7520 CallInst &CI = cast<CallInst>(I); 7521 if (CI.isTailCall()) 7522 TailCalls.push_back(&CI); 7523 return true; 7524 }, 7525 *this, {Instruction::Call}, UsedAssumedInformation)) 7526 return ChangeStatus::UNCHANGED; 7527 7528 Argument *Arg = getAssociatedArgument(); 7529 // Query AAAlign attribute for alignment of associated argument to 7530 // determine the best alignment of loads. 7531 const auto *AlignAA = 7532 A.getAAFor<AAAlign>(*this, IRPosition::value(*Arg), DepClassTy::NONE); 7533 7534 // Callback to repair the associated function. A new alloca is placed at the 7535 // beginning and initialized with the values passed through arguments. The 7536 // new alloca replaces the use of the old pointer argument. 7537 Attributor::ArgumentReplacementInfo::CalleeRepairCBTy FnRepairCB = 7538 [=](const Attributor::ArgumentReplacementInfo &ARI, 7539 Function &ReplacementFn, Function::arg_iterator ArgIt) { 7540 BasicBlock &EntryBB = ReplacementFn.getEntryBlock(); 7541 Instruction *IP = &*EntryBB.getFirstInsertionPt(); 7542 const DataLayout &DL = IP->getModule()->getDataLayout(); 7543 unsigned AS = DL.getAllocaAddrSpace(); 7544 Instruction *AI = new AllocaInst(*PrivatizableType, AS, 7545 Arg->getName() + ".priv", IP); 7546 createInitialization(*PrivatizableType, *AI, ReplacementFn, 7547 ArgIt->getArgNo(), *IP); 7548 7549 if (AI->getType() != Arg->getType()) 7550 AI = BitCastInst::CreatePointerBitCastOrAddrSpaceCast( 7551 AI, Arg->getType(), "", IP); 7552 Arg->replaceAllUsesWith(AI); 7553 7554 for (CallInst *CI : TailCalls) 7555 CI->setTailCall(false); 7556 }; 7557 7558 // Callback to repair a call site of the associated function. The elements 7559 // of the privatizable type are loaded prior to the call and passed to the 7560 // new function version. 7561 Attributor::ArgumentReplacementInfo::ACSRepairCBTy ACSRepairCB = 7562 [=](const Attributor::ArgumentReplacementInfo &ARI, 7563 AbstractCallSite ACS, SmallVectorImpl<Value *> &NewArgOperands) { 7564 // When no alignment is specified for the load instruction, 7565 // natural alignment is assumed. 7566 createReplacementValues( 7567 AlignAA ? AlignAA->getAssumedAlign() : Align(0), 7568 *PrivatizableType, ACS, 7569 ACS.getCallArgOperand(ARI.getReplacedArg().getArgNo()), 7570 NewArgOperands); 7571 }; 7572 7573 // Collect the types that will replace the privatizable type in the function 7574 // signature. 7575 SmallVector<Type *, 16> ReplacementTypes; 7576 identifyReplacementTypes(*PrivatizableType, ReplacementTypes); 7577 7578 // Register a rewrite of the argument. 7579 if (A.registerFunctionSignatureRewrite(*Arg, ReplacementTypes, 7580 std::move(FnRepairCB), 7581 std::move(ACSRepairCB))) 7582 return ChangeStatus::CHANGED; 7583 return ChangeStatus::UNCHANGED; 7584 } 7585 7586 /// See AbstractAttribute::trackStatistics() 7587 void trackStatistics() const override { 7588 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr); 7589 } 7590 }; 7591 7592 struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl { 7593 AAPrivatizablePtrFloating(const IRPosition &IRP, Attributor &A) 7594 : AAPrivatizablePtrImpl(IRP, A) {} 7595 7596 /// See AbstractAttribute::initialize(...). 7597 void initialize(Attributor &A) override { 7598 // TODO: We can privatize more than arguments. 7599 indicatePessimisticFixpoint(); 7600 } 7601 7602 ChangeStatus updateImpl(Attributor &A) override { 7603 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::" 7604 "updateImpl will not be called"); 7605 } 7606 7607 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...) 7608 std::optional<Type *> identifyPrivatizableType(Attributor &A) override { 7609 Value *Obj = getUnderlyingObject(&getAssociatedValue()); 7610 if (!Obj) { 7611 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n"); 7612 return nullptr; 7613 } 7614 7615 if (auto *AI = dyn_cast<AllocaInst>(Obj)) 7616 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize())) 7617 if (CI->isOne()) 7618 return AI->getAllocatedType(); 7619 if (auto *Arg = dyn_cast<Argument>(Obj)) { 7620 auto *PrivArgAA = A.getAAFor<AAPrivatizablePtr>( 7621 *this, IRPosition::argument(*Arg), DepClassTy::REQUIRED); 7622 if (PrivArgAA && PrivArgAA->isAssumedPrivatizablePtr()) 7623 return PrivArgAA->getPrivatizableType(); 7624 } 7625 7626 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid " 7627 "alloca nor privatizable argument: " 7628 << *Obj << "!\n"); 7629 return nullptr; 7630 } 7631 7632 /// See AbstractAttribute::trackStatistics() 7633 void trackStatistics() const override { 7634 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr); 7635 } 7636 }; 7637 7638 struct AAPrivatizablePtrCallSiteArgument final 7639 : public AAPrivatizablePtrFloating { 7640 AAPrivatizablePtrCallSiteArgument(const IRPosition &IRP, Attributor &A) 7641 : AAPrivatizablePtrFloating(IRP, A) {} 7642 7643 /// See AbstractAttribute::initialize(...). 7644 void initialize(Attributor &A) override { 7645 if (A.hasAttr(getIRPosition(), Attribute::ByVal)) 7646 indicateOptimisticFixpoint(); 7647 } 7648 7649 /// See AbstractAttribute::updateImpl(...). 7650 ChangeStatus updateImpl(Attributor &A) override { 7651 PrivatizableType = identifyPrivatizableType(A); 7652 if (!PrivatizableType) 7653 return ChangeStatus::UNCHANGED; 7654 if (!*PrivatizableType) 7655 return indicatePessimisticFixpoint(); 7656 7657 const IRPosition &IRP = getIRPosition(); 7658 bool IsKnownNoCapture; 7659 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>( 7660 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoCapture); 7661 if (!IsAssumedNoCapture) { 7662 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n"); 7663 return indicatePessimisticFixpoint(); 7664 } 7665 7666 bool IsKnownNoAlias; 7667 if (!AA::hasAssumedIRAttr<Attribute::NoAlias>( 7668 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoAlias)) { 7669 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n"); 7670 return indicatePessimisticFixpoint(); 7671 } 7672 7673 bool IsKnown; 7674 if (!AA::isAssumedReadOnly(A, IRP, *this, IsKnown)) { 7675 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n"); 7676 return indicatePessimisticFixpoint(); 7677 } 7678 7679 return ChangeStatus::UNCHANGED; 7680 } 7681 7682 /// See AbstractAttribute::trackStatistics() 7683 void trackStatistics() const override { 7684 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr); 7685 } 7686 }; 7687 7688 struct AAPrivatizablePtrCallSiteReturned final 7689 : public AAPrivatizablePtrFloating { 7690 AAPrivatizablePtrCallSiteReturned(const IRPosition &IRP, Attributor &A) 7691 : AAPrivatizablePtrFloating(IRP, A) {} 7692 7693 /// See AbstractAttribute::initialize(...). 7694 void initialize(Attributor &A) override { 7695 // TODO: We can privatize more than arguments. 7696 indicatePessimisticFixpoint(); 7697 } 7698 7699 /// See AbstractAttribute::trackStatistics() 7700 void trackStatistics() const override { 7701 STATS_DECLTRACK_CSRET_ATTR(privatizable_ptr); 7702 } 7703 }; 7704 7705 struct AAPrivatizablePtrReturned final : public AAPrivatizablePtrFloating { 7706 AAPrivatizablePtrReturned(const IRPosition &IRP, Attributor &A) 7707 : AAPrivatizablePtrFloating(IRP, A) {} 7708 7709 /// See AbstractAttribute::initialize(...). 7710 void initialize(Attributor &A) override { 7711 // TODO: We can privatize more than arguments. 7712 indicatePessimisticFixpoint(); 7713 } 7714 7715 /// See AbstractAttribute::trackStatistics() 7716 void trackStatistics() const override { 7717 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr); 7718 } 7719 }; 7720 } // namespace 7721 7722 /// -------------------- Memory Behavior Attributes ---------------------------- 7723 /// Includes read-none, read-only, and write-only. 7724 /// ---------------------------------------------------------------------------- 7725 namespace { 7726 struct AAMemoryBehaviorImpl : public AAMemoryBehavior { 7727 AAMemoryBehaviorImpl(const IRPosition &IRP, Attributor &A) 7728 : AAMemoryBehavior(IRP, A) {} 7729 7730 /// See AbstractAttribute::initialize(...). 7731 void initialize(Attributor &A) override { 7732 intersectAssumedBits(BEST_STATE); 7733 getKnownStateFromValue(A, getIRPosition(), getState()); 7734 AAMemoryBehavior::initialize(A); 7735 } 7736 7737 /// Return the memory behavior information encoded in the IR for \p IRP. 7738 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP, 7739 BitIntegerState &State, 7740 bool IgnoreSubsumingPositions = false) { 7741 SmallVector<Attribute, 2> Attrs; 7742 A.getAttrs(IRP, AttrKinds, Attrs, IgnoreSubsumingPositions); 7743 for (const Attribute &Attr : Attrs) { 7744 switch (Attr.getKindAsEnum()) { 7745 case Attribute::ReadNone: 7746 State.addKnownBits(NO_ACCESSES); 7747 break; 7748 case Attribute::ReadOnly: 7749 State.addKnownBits(NO_WRITES); 7750 break; 7751 case Attribute::WriteOnly: 7752 State.addKnownBits(NO_READS); 7753 break; 7754 default: 7755 llvm_unreachable("Unexpected attribute!"); 7756 } 7757 } 7758 7759 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) { 7760 if (!I->mayReadFromMemory()) 7761 State.addKnownBits(NO_READS); 7762 if (!I->mayWriteToMemory()) 7763 State.addKnownBits(NO_WRITES); 7764 } 7765 } 7766 7767 /// See AbstractAttribute::getDeducedAttributes(...). 7768 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, 7769 SmallVectorImpl<Attribute> &Attrs) const override { 7770 assert(Attrs.size() == 0); 7771 if (isAssumedReadNone()) 7772 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone)); 7773 else if (isAssumedReadOnly()) 7774 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly)); 7775 else if (isAssumedWriteOnly()) 7776 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly)); 7777 assert(Attrs.size() <= 1); 7778 } 7779 7780 /// See AbstractAttribute::manifest(...). 7781 ChangeStatus manifest(Attributor &A) override { 7782 const IRPosition &IRP = getIRPosition(); 7783 7784 if (A.hasAttr(IRP, Attribute::ReadNone, 7785 /* IgnoreSubsumingPositions */ true)) 7786 return ChangeStatus::UNCHANGED; 7787 7788 // Check if we would improve the existing attributes first. 7789 SmallVector<Attribute, 4> DeducedAttrs; 7790 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs); 7791 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) { 7792 return A.hasAttr(IRP, Attr.getKindAsEnum(), 7793 /* IgnoreSubsumingPositions */ true); 7794 })) 7795 return ChangeStatus::UNCHANGED; 7796 7797 // Clear existing attributes. 7798 A.removeAttrs(IRP, AttrKinds); 7799 7800 // Use the generic manifest method. 7801 return IRAttribute::manifest(A); 7802 } 7803 7804 /// See AbstractState::getAsStr(). 7805 const std::string getAsStr(Attributor *A) const override { 7806 if (isAssumedReadNone()) 7807 return "readnone"; 7808 if (isAssumedReadOnly()) 7809 return "readonly"; 7810 if (isAssumedWriteOnly()) 7811 return "writeonly"; 7812 return "may-read/write"; 7813 } 7814 7815 /// The set of IR attributes AAMemoryBehavior deals with. 7816 static const Attribute::AttrKind AttrKinds[3]; 7817 }; 7818 7819 const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = { 7820 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly}; 7821 7822 /// Memory behavior attribute for a floating value. 7823 struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl { 7824 AAMemoryBehaviorFloating(const IRPosition &IRP, Attributor &A) 7825 : AAMemoryBehaviorImpl(IRP, A) {} 7826 7827 /// See AbstractAttribute::updateImpl(...). 7828 ChangeStatus updateImpl(Attributor &A) override; 7829 7830 /// See AbstractAttribute::trackStatistics() 7831 void trackStatistics() const override { 7832 if (isAssumedReadNone()) 7833 STATS_DECLTRACK_FLOATING_ATTR(readnone) 7834 else if (isAssumedReadOnly()) 7835 STATS_DECLTRACK_FLOATING_ATTR(readonly) 7836 else if (isAssumedWriteOnly()) 7837 STATS_DECLTRACK_FLOATING_ATTR(writeonly) 7838 } 7839 7840 private: 7841 /// Return true if users of \p UserI might access the underlying 7842 /// variable/location described by \p U and should therefore be analyzed. 7843 bool followUsersOfUseIn(Attributor &A, const Use &U, 7844 const Instruction *UserI); 7845 7846 /// Update the state according to the effect of use \p U in \p UserI. 7847 void analyzeUseIn(Attributor &A, const Use &U, const Instruction *UserI); 7848 }; 7849 7850 /// Memory behavior attribute for function argument. 7851 struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating { 7852 AAMemoryBehaviorArgument(const IRPosition &IRP, Attributor &A) 7853 : AAMemoryBehaviorFloating(IRP, A) {} 7854 7855 /// See AbstractAttribute::initialize(...). 7856 void initialize(Attributor &A) override { 7857 intersectAssumedBits(BEST_STATE); 7858 const IRPosition &IRP = getIRPosition(); 7859 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we 7860 // can query it when we use has/getAttr. That would allow us to reuse the 7861 // initialize of the base class here. 7862 bool HasByVal = A.hasAttr(IRP, {Attribute::ByVal}, 7863 /* IgnoreSubsumingPositions */ true); 7864 getKnownStateFromValue(A, IRP, getState(), 7865 /* IgnoreSubsumingPositions */ HasByVal); 7866 } 7867 7868 ChangeStatus manifest(Attributor &A) override { 7869 // TODO: Pointer arguments are not supported on vectors of pointers yet. 7870 if (!getAssociatedValue().getType()->isPointerTy()) 7871 return ChangeStatus::UNCHANGED; 7872 7873 // TODO: From readattrs.ll: "inalloca parameters are always 7874 // considered written" 7875 if (A.hasAttr(getIRPosition(), 7876 {Attribute::InAlloca, Attribute::Preallocated})) { 7877 removeKnownBits(NO_WRITES); 7878 removeAssumedBits(NO_WRITES); 7879 } 7880 A.removeAttrs(getIRPosition(), AttrKinds); 7881 return AAMemoryBehaviorFloating::manifest(A); 7882 } 7883 7884 /// See AbstractAttribute::trackStatistics() 7885 void trackStatistics() const override { 7886 if (isAssumedReadNone()) 7887 STATS_DECLTRACK_ARG_ATTR(readnone) 7888 else if (isAssumedReadOnly()) 7889 STATS_DECLTRACK_ARG_ATTR(readonly) 7890 else if (isAssumedWriteOnly()) 7891 STATS_DECLTRACK_ARG_ATTR(writeonly) 7892 } 7893 }; 7894 7895 struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument { 7896 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP, Attributor &A) 7897 : AAMemoryBehaviorArgument(IRP, A) {} 7898 7899 /// See AbstractAttribute::initialize(...). 7900 void initialize(Attributor &A) override { 7901 // If we don't have an associated attribute this is either a variadic call 7902 // or an indirect call, either way, nothing to do here. 7903 Argument *Arg = getAssociatedArgument(); 7904 if (!Arg) { 7905 indicatePessimisticFixpoint(); 7906 return; 7907 } 7908 if (Arg->hasByValAttr()) { 7909 addKnownBits(NO_WRITES); 7910 removeKnownBits(NO_READS); 7911 removeAssumedBits(NO_READS); 7912 } 7913 AAMemoryBehaviorArgument::initialize(A); 7914 if (getAssociatedFunction()->isDeclaration()) 7915 indicatePessimisticFixpoint(); 7916 } 7917 7918 /// See AbstractAttribute::updateImpl(...). 7919 ChangeStatus updateImpl(Attributor &A) override { 7920 // TODO: Once we have call site specific value information we can provide 7921 // call site specific liveness liveness information and then it makes 7922 // sense to specialize attributes for call sites arguments instead of 7923 // redirecting requests to the callee argument. 7924 Argument *Arg = getAssociatedArgument(); 7925 const IRPosition &ArgPos = IRPosition::argument(*Arg); 7926 auto *ArgAA = 7927 A.getAAFor<AAMemoryBehavior>(*this, ArgPos, DepClassTy::REQUIRED); 7928 if (!ArgAA) 7929 return indicatePessimisticFixpoint(); 7930 return clampStateAndIndicateChange(getState(), ArgAA->getState()); 7931 } 7932 7933 /// See AbstractAttribute::trackStatistics() 7934 void trackStatistics() const override { 7935 if (isAssumedReadNone()) 7936 STATS_DECLTRACK_CSARG_ATTR(readnone) 7937 else if (isAssumedReadOnly()) 7938 STATS_DECLTRACK_CSARG_ATTR(readonly) 7939 else if (isAssumedWriteOnly()) 7940 STATS_DECLTRACK_CSARG_ATTR(writeonly) 7941 } 7942 }; 7943 7944 /// Memory behavior attribute for a call site return position. 7945 struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating { 7946 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP, Attributor &A) 7947 : AAMemoryBehaviorFloating(IRP, A) {} 7948 7949 /// See AbstractAttribute::initialize(...). 7950 void initialize(Attributor &A) override { 7951 AAMemoryBehaviorImpl::initialize(A); 7952 } 7953 /// See AbstractAttribute::manifest(...). 7954 ChangeStatus manifest(Attributor &A) override { 7955 // We do not annotate returned values. 7956 return ChangeStatus::UNCHANGED; 7957 } 7958 7959 /// See AbstractAttribute::trackStatistics() 7960 void trackStatistics() const override {} 7961 }; 7962 7963 /// An AA to represent the memory behavior function attributes. 7964 struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl { 7965 AAMemoryBehaviorFunction(const IRPosition &IRP, Attributor &A) 7966 : AAMemoryBehaviorImpl(IRP, A) {} 7967 7968 /// See AbstractAttribute::updateImpl(Attributor &A). 7969 ChangeStatus updateImpl(Attributor &A) override; 7970 7971 /// See AbstractAttribute::manifest(...). 7972 ChangeStatus manifest(Attributor &A) override { 7973 // TODO: It would be better to merge this with AAMemoryLocation, so that 7974 // we could determine read/write per location. This would also have the 7975 // benefit of only one place trying to manifest the memory attribute. 7976 Function &F = cast<Function>(getAnchorValue()); 7977 MemoryEffects ME = MemoryEffects::unknown(); 7978 if (isAssumedReadNone()) 7979 ME = MemoryEffects::none(); 7980 else if (isAssumedReadOnly()) 7981 ME = MemoryEffects::readOnly(); 7982 else if (isAssumedWriteOnly()) 7983 ME = MemoryEffects::writeOnly(); 7984 7985 A.removeAttrs(getIRPosition(), AttrKinds); 7986 return A.manifestAttrs(getIRPosition(), 7987 Attribute::getWithMemoryEffects(F.getContext(), ME)); 7988 } 7989 7990 /// See AbstractAttribute::trackStatistics() 7991 void trackStatistics() const override { 7992 if (isAssumedReadNone()) 7993 STATS_DECLTRACK_FN_ATTR(readnone) 7994 else if (isAssumedReadOnly()) 7995 STATS_DECLTRACK_FN_ATTR(readonly) 7996 else if (isAssumedWriteOnly()) 7997 STATS_DECLTRACK_FN_ATTR(writeonly) 7998 } 7999 }; 8000 8001 /// AAMemoryBehavior attribute for call sites. 8002 struct AAMemoryBehaviorCallSite final : AAMemoryBehaviorImpl { 8003 AAMemoryBehaviorCallSite(const IRPosition &IRP, Attributor &A) 8004 : AAMemoryBehaviorImpl(IRP, A) {} 8005 8006 /// See AbstractAttribute::updateImpl(...). 8007 ChangeStatus updateImpl(Attributor &A) override { 8008 // TODO: Once we have call site specific value information we can provide 8009 // call site specific liveness liveness information and then it makes 8010 // sense to specialize attributes for call sites arguments instead of 8011 // redirecting requests to the callee argument. 8012 Function *F = getAssociatedFunction(); 8013 const IRPosition &FnPos = IRPosition::function(*F); 8014 auto *FnAA = 8015 A.getAAFor<AAMemoryBehavior>(*this, FnPos, DepClassTy::REQUIRED); 8016 if (!FnAA) 8017 return indicatePessimisticFixpoint(); 8018 return clampStateAndIndicateChange(getState(), FnAA->getState()); 8019 } 8020 8021 /// See AbstractAttribute::manifest(...). 8022 ChangeStatus manifest(Attributor &A) override { 8023 // TODO: Deduplicate this with AAMemoryBehaviorFunction. 8024 CallBase &CB = cast<CallBase>(getAnchorValue()); 8025 MemoryEffects ME = MemoryEffects::unknown(); 8026 if (isAssumedReadNone()) 8027 ME = MemoryEffects::none(); 8028 else if (isAssumedReadOnly()) 8029 ME = MemoryEffects::readOnly(); 8030 else if (isAssumedWriteOnly()) 8031 ME = MemoryEffects::writeOnly(); 8032 8033 A.removeAttrs(getIRPosition(), AttrKinds); 8034 return A.manifestAttrs( 8035 getIRPosition(), Attribute::getWithMemoryEffects(CB.getContext(), ME)); 8036 } 8037 8038 /// See AbstractAttribute::trackStatistics() 8039 void trackStatistics() const override { 8040 if (isAssumedReadNone()) 8041 STATS_DECLTRACK_CS_ATTR(readnone) 8042 else if (isAssumedReadOnly()) 8043 STATS_DECLTRACK_CS_ATTR(readonly) 8044 else if (isAssumedWriteOnly()) 8045 STATS_DECLTRACK_CS_ATTR(writeonly) 8046 } 8047 }; 8048 8049 ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) { 8050 8051 // The current assumed state used to determine a change. 8052 auto AssumedState = getAssumed(); 8053 8054 auto CheckRWInst = [&](Instruction &I) { 8055 // If the instruction has an own memory behavior state, use it to restrict 8056 // the local state. No further analysis is required as the other memory 8057 // state is as optimistic as it gets. 8058 if (const auto *CB = dyn_cast<CallBase>(&I)) { 8059 const auto *MemBehaviorAA = A.getAAFor<AAMemoryBehavior>( 8060 *this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED); 8061 if (MemBehaviorAA) { 8062 intersectAssumedBits(MemBehaviorAA->getAssumed()); 8063 return !isAtFixpoint(); 8064 } 8065 } 8066 8067 // Remove access kind modifiers if necessary. 8068 if (I.mayReadFromMemory()) 8069 removeAssumedBits(NO_READS); 8070 if (I.mayWriteToMemory()) 8071 removeAssumedBits(NO_WRITES); 8072 return !isAtFixpoint(); 8073 }; 8074 8075 bool UsedAssumedInformation = false; 8076 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this, 8077 UsedAssumedInformation)) 8078 return indicatePessimisticFixpoint(); 8079 8080 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED 8081 : ChangeStatus::UNCHANGED; 8082 } 8083 8084 ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) { 8085 8086 const IRPosition &IRP = getIRPosition(); 8087 const IRPosition &FnPos = IRPosition::function_scope(IRP); 8088 AAMemoryBehavior::StateType &S = getState(); 8089 8090 // First, check the function scope. We take the known information and we avoid 8091 // work if the assumed information implies the current assumed information for 8092 // this attribute. This is a valid for all but byval arguments. 8093 Argument *Arg = IRP.getAssociatedArgument(); 8094 AAMemoryBehavior::base_t FnMemAssumedState = 8095 AAMemoryBehavior::StateType::getWorstState(); 8096 if (!Arg || !Arg->hasByValAttr()) { 8097 const auto *FnMemAA = 8098 A.getAAFor<AAMemoryBehavior>(*this, FnPos, DepClassTy::OPTIONAL); 8099 if (FnMemAA) { 8100 FnMemAssumedState = FnMemAA->getAssumed(); 8101 S.addKnownBits(FnMemAA->getKnown()); 8102 if ((S.getAssumed() & FnMemAA->getAssumed()) == S.getAssumed()) 8103 return ChangeStatus::UNCHANGED; 8104 } 8105 } 8106 8107 // The current assumed state used to determine a change. 8108 auto AssumedState = S.getAssumed(); 8109 8110 // Make sure the value is not captured (except through "return"), if 8111 // it is, any information derived would be irrelevant anyway as we cannot 8112 // check the potential aliases introduced by the capture. However, no need 8113 // to fall back to anythign less optimistic than the function state. 8114 bool IsKnownNoCapture; 8115 const AANoCapture *ArgNoCaptureAA = nullptr; 8116 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>( 8117 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture, false, 8118 &ArgNoCaptureAA); 8119 8120 if (!IsAssumedNoCapture && 8121 (!ArgNoCaptureAA || !ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned())) { 8122 S.intersectAssumedBits(FnMemAssumedState); 8123 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED 8124 : ChangeStatus::UNCHANGED; 8125 } 8126 8127 // Visit and expand uses until all are analyzed or a fixpoint is reached. 8128 auto UsePred = [&](const Use &U, bool &Follow) -> bool { 8129 Instruction *UserI = cast<Instruction>(U.getUser()); 8130 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << *U << " in " << *UserI 8131 << " \n"); 8132 8133 // Droppable users, e.g., llvm::assume does not actually perform any action. 8134 if (UserI->isDroppable()) 8135 return true; 8136 8137 // Check if the users of UserI should also be visited. 8138 Follow = followUsersOfUseIn(A, U, UserI); 8139 8140 // If UserI might touch memory we analyze the use in detail. 8141 if (UserI->mayReadOrWriteMemory()) 8142 analyzeUseIn(A, U, UserI); 8143 8144 return !isAtFixpoint(); 8145 }; 8146 8147 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) 8148 return indicatePessimisticFixpoint(); 8149 8150 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED 8151 : ChangeStatus::UNCHANGED; 8152 } 8153 8154 bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use &U, 8155 const Instruction *UserI) { 8156 // The loaded value is unrelated to the pointer argument, no need to 8157 // follow the users of the load. 8158 if (isa<LoadInst>(UserI) || isa<ReturnInst>(UserI)) 8159 return false; 8160 8161 // By default we follow all uses assuming UserI might leak information on U, 8162 // we have special handling for call sites operands though. 8163 const auto *CB = dyn_cast<CallBase>(UserI); 8164 if (!CB || !CB->isArgOperand(&U)) 8165 return true; 8166 8167 // If the use is a call argument known not to be captured, the users of 8168 // the call do not need to be visited because they have to be unrelated to 8169 // the input. Note that this check is not trivial even though we disallow 8170 // general capturing of the underlying argument. The reason is that the 8171 // call might the argument "through return", which we allow and for which we 8172 // need to check call users. 8173 if (U.get()->getType()->isPointerTy()) { 8174 unsigned ArgNo = CB->getArgOperandNo(&U); 8175 bool IsKnownNoCapture; 8176 return !AA::hasAssumedIRAttr<Attribute::NoCapture>( 8177 A, this, IRPosition::callsite_argument(*CB, ArgNo), 8178 DepClassTy::OPTIONAL, IsKnownNoCapture); 8179 } 8180 8181 return true; 8182 } 8183 8184 void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use &U, 8185 const Instruction *UserI) { 8186 assert(UserI->mayReadOrWriteMemory()); 8187 8188 switch (UserI->getOpcode()) { 8189 default: 8190 // TODO: Handle all atomics and other side-effect operations we know of. 8191 break; 8192 case Instruction::Load: 8193 // Loads cause the NO_READS property to disappear. 8194 removeAssumedBits(NO_READS); 8195 return; 8196 8197 case Instruction::Store: 8198 // Stores cause the NO_WRITES property to disappear if the use is the 8199 // pointer operand. Note that while capturing was taken care of somewhere 8200 // else we need to deal with stores of the value that is not looked through. 8201 if (cast<StoreInst>(UserI)->getPointerOperand() == U.get()) 8202 removeAssumedBits(NO_WRITES); 8203 else 8204 indicatePessimisticFixpoint(); 8205 return; 8206 8207 case Instruction::Call: 8208 case Instruction::CallBr: 8209 case Instruction::Invoke: { 8210 // For call sites we look at the argument memory behavior attribute (this 8211 // could be recursive!) in order to restrict our own state. 8212 const auto *CB = cast<CallBase>(UserI); 8213 8214 // Give up on operand bundles. 8215 if (CB->isBundleOperand(&U)) { 8216 indicatePessimisticFixpoint(); 8217 return; 8218 } 8219 8220 // Calling a function does read the function pointer, maybe write it if the 8221 // function is self-modifying. 8222 if (CB->isCallee(&U)) { 8223 removeAssumedBits(NO_READS); 8224 break; 8225 } 8226 8227 // Adjust the possible access behavior based on the information on the 8228 // argument. 8229 IRPosition Pos; 8230 if (U.get()->getType()->isPointerTy()) 8231 Pos = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U)); 8232 else 8233 Pos = IRPosition::callsite_function(*CB); 8234 const auto *MemBehaviorAA = 8235 A.getAAFor<AAMemoryBehavior>(*this, Pos, DepClassTy::OPTIONAL); 8236 if (!MemBehaviorAA) 8237 break; 8238 // "assumed" has at most the same bits as the MemBehaviorAA assumed 8239 // and at least "known". 8240 intersectAssumedBits(MemBehaviorAA->getAssumed()); 8241 return; 8242 } 8243 }; 8244 8245 // Generally, look at the "may-properties" and adjust the assumed state if we 8246 // did not trigger special handling before. 8247 if (UserI->mayReadFromMemory()) 8248 removeAssumedBits(NO_READS); 8249 if (UserI->mayWriteToMemory()) 8250 removeAssumedBits(NO_WRITES); 8251 } 8252 } // namespace 8253 8254 /// -------------------- Memory Locations Attributes --------------------------- 8255 /// Includes read-none, argmemonly, inaccessiblememonly, 8256 /// inaccessiblememorargmemonly 8257 /// ---------------------------------------------------------------------------- 8258 8259 std::string AAMemoryLocation::getMemoryLocationsAsStr( 8260 AAMemoryLocation::MemoryLocationsKind MLK) { 8261 if (0 == (MLK & AAMemoryLocation::NO_LOCATIONS)) 8262 return "all memory"; 8263 if (MLK == AAMemoryLocation::NO_LOCATIONS) 8264 return "no memory"; 8265 std::string S = "memory:"; 8266 if (0 == (MLK & AAMemoryLocation::NO_LOCAL_MEM)) 8267 S += "stack,"; 8268 if (0 == (MLK & AAMemoryLocation::NO_CONST_MEM)) 8269 S += "constant,"; 8270 if (0 == (MLK & AAMemoryLocation::NO_GLOBAL_INTERNAL_MEM)) 8271 S += "internal global,"; 8272 if (0 == (MLK & AAMemoryLocation::NO_GLOBAL_EXTERNAL_MEM)) 8273 S += "external global,"; 8274 if (0 == (MLK & AAMemoryLocation::NO_ARGUMENT_MEM)) 8275 S += "argument,"; 8276 if (0 == (MLK & AAMemoryLocation::NO_INACCESSIBLE_MEM)) 8277 S += "inaccessible,"; 8278 if (0 == (MLK & AAMemoryLocation::NO_MALLOCED_MEM)) 8279 S += "malloced,"; 8280 if (0 == (MLK & AAMemoryLocation::NO_UNKOWN_MEM)) 8281 S += "unknown,"; 8282 S.pop_back(); 8283 return S; 8284 } 8285 8286 namespace { 8287 struct AAMemoryLocationImpl : public AAMemoryLocation { 8288 8289 AAMemoryLocationImpl(const IRPosition &IRP, Attributor &A) 8290 : AAMemoryLocation(IRP, A), Allocator(A.Allocator) { 8291 AccessKind2Accesses.fill(nullptr); 8292 } 8293 8294 ~AAMemoryLocationImpl() { 8295 // The AccessSets are allocated via a BumpPtrAllocator, we call 8296 // the destructor manually. 8297 for (AccessSet *AS : AccessKind2Accesses) 8298 if (AS) 8299 AS->~AccessSet(); 8300 } 8301 8302 /// See AbstractAttribute::initialize(...). 8303 void initialize(Attributor &A) override { 8304 intersectAssumedBits(BEST_STATE); 8305 getKnownStateFromValue(A, getIRPosition(), getState()); 8306 AAMemoryLocation::initialize(A); 8307 } 8308 8309 /// Return the memory behavior information encoded in the IR for \p IRP. 8310 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP, 8311 BitIntegerState &State, 8312 bool IgnoreSubsumingPositions = false) { 8313 // For internal functions we ignore `argmemonly` and 8314 // `inaccessiblememorargmemonly` as we might break it via interprocedural 8315 // constant propagation. It is unclear if this is the best way but it is 8316 // unlikely this will cause real performance problems. If we are deriving 8317 // attributes for the anchor function we even remove the attribute in 8318 // addition to ignoring it. 8319 // TODO: A better way to handle this would be to add ~NO_GLOBAL_MEM / 8320 // MemoryEffects::Other as a possible location. 8321 bool UseArgMemOnly = true; 8322 Function *AnchorFn = IRP.getAnchorScope(); 8323 if (AnchorFn && A.isRunOn(*AnchorFn)) 8324 UseArgMemOnly = !AnchorFn->hasLocalLinkage(); 8325 8326 SmallVector<Attribute, 2> Attrs; 8327 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions); 8328 for (const Attribute &Attr : Attrs) { 8329 // TODO: We can map MemoryEffects to Attributor locations more precisely. 8330 MemoryEffects ME = Attr.getMemoryEffects(); 8331 if (ME.doesNotAccessMemory()) { 8332 State.addKnownBits(NO_LOCAL_MEM | NO_CONST_MEM); 8333 continue; 8334 } 8335 if (ME.onlyAccessesInaccessibleMem()) { 8336 State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true)); 8337 continue; 8338 } 8339 if (ME.onlyAccessesArgPointees()) { 8340 if (UseArgMemOnly) 8341 State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true)); 8342 else { 8343 // Remove location information, only keep read/write info. 8344 ME = MemoryEffects(ME.getModRef()); 8345 A.manifestAttrs(IRP, 8346 Attribute::getWithMemoryEffects( 8347 IRP.getAnchorValue().getContext(), ME), 8348 /*ForceReplace*/ true); 8349 } 8350 continue; 8351 } 8352 if (ME.onlyAccessesInaccessibleOrArgMem()) { 8353 if (UseArgMemOnly) 8354 State.addKnownBits(inverseLocation( 8355 NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true)); 8356 else { 8357 // Remove location information, only keep read/write info. 8358 ME = MemoryEffects(ME.getModRef()); 8359 A.manifestAttrs(IRP, 8360 Attribute::getWithMemoryEffects( 8361 IRP.getAnchorValue().getContext(), ME), 8362 /*ForceReplace*/ true); 8363 } 8364 continue; 8365 } 8366 } 8367 } 8368 8369 /// See AbstractAttribute::getDeducedAttributes(...). 8370 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, 8371 SmallVectorImpl<Attribute> &Attrs) const override { 8372 // TODO: We can map Attributor locations to MemoryEffects more precisely. 8373 assert(Attrs.size() == 0); 8374 if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION) { 8375 if (isAssumedReadNone()) 8376 Attrs.push_back( 8377 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::none())); 8378 else if (isAssumedInaccessibleMemOnly()) 8379 Attrs.push_back(Attribute::getWithMemoryEffects( 8380 Ctx, MemoryEffects::inaccessibleMemOnly())); 8381 else if (isAssumedArgMemOnly()) 8382 Attrs.push_back( 8383 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::argMemOnly())); 8384 else if (isAssumedInaccessibleOrArgMemOnly()) 8385 Attrs.push_back(Attribute::getWithMemoryEffects( 8386 Ctx, MemoryEffects::inaccessibleOrArgMemOnly())); 8387 } 8388 assert(Attrs.size() <= 1); 8389 } 8390 8391 /// See AbstractAttribute::manifest(...). 8392 ChangeStatus manifest(Attributor &A) override { 8393 // TODO: If AAMemoryLocation and AAMemoryBehavior are merged, we could 8394 // provide per-location modref information here. 8395 const IRPosition &IRP = getIRPosition(); 8396 8397 SmallVector<Attribute, 1> DeducedAttrs; 8398 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs); 8399 if (DeducedAttrs.size() != 1) 8400 return ChangeStatus::UNCHANGED; 8401 MemoryEffects ME = DeducedAttrs[0].getMemoryEffects(); 8402 8403 return A.manifestAttrs(IRP, Attribute::getWithMemoryEffects( 8404 IRP.getAnchorValue().getContext(), ME)); 8405 } 8406 8407 /// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...). 8408 bool checkForAllAccessesToMemoryKind( 8409 function_ref<bool(const Instruction *, const Value *, AccessKind, 8410 MemoryLocationsKind)> 8411 Pred, 8412 MemoryLocationsKind RequestedMLK) const override { 8413 if (!isValidState()) 8414 return false; 8415 8416 MemoryLocationsKind AssumedMLK = getAssumedNotAccessedLocation(); 8417 if (AssumedMLK == NO_LOCATIONS) 8418 return true; 8419 8420 unsigned Idx = 0; 8421 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; 8422 CurMLK *= 2, ++Idx) { 8423 if (CurMLK & RequestedMLK) 8424 continue; 8425 8426 if (const AccessSet *Accesses = AccessKind2Accesses[Idx]) 8427 for (const AccessInfo &AI : *Accesses) 8428 if (!Pred(AI.I, AI.Ptr, AI.Kind, CurMLK)) 8429 return false; 8430 } 8431 8432 return true; 8433 } 8434 8435 ChangeStatus indicatePessimisticFixpoint() override { 8436 // If we give up and indicate a pessimistic fixpoint this instruction will 8437 // become an access for all potential access kinds: 8438 // TODO: Add pointers for argmemonly and globals to improve the results of 8439 // checkForAllAccessesToMemoryKind. 8440 bool Changed = false; 8441 MemoryLocationsKind KnownMLK = getKnown(); 8442 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()); 8443 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) 8444 if (!(CurMLK & KnownMLK)) 8445 updateStateAndAccessesMap(getState(), CurMLK, I, nullptr, Changed, 8446 getAccessKindFromInst(I)); 8447 return AAMemoryLocation::indicatePessimisticFixpoint(); 8448 } 8449 8450 protected: 8451 /// Helper struct to tie together an instruction that has a read or write 8452 /// effect with the pointer it accesses (if any). 8453 struct AccessInfo { 8454 8455 /// The instruction that caused the access. 8456 const Instruction *I; 8457 8458 /// The base pointer that is accessed, or null if unknown. 8459 const Value *Ptr; 8460 8461 /// The kind of access (read/write/read+write). 8462 AccessKind Kind; 8463 8464 bool operator==(const AccessInfo &RHS) const { 8465 return I == RHS.I && Ptr == RHS.Ptr && Kind == RHS.Kind; 8466 } 8467 bool operator()(const AccessInfo &LHS, const AccessInfo &RHS) const { 8468 if (LHS.I != RHS.I) 8469 return LHS.I < RHS.I; 8470 if (LHS.Ptr != RHS.Ptr) 8471 return LHS.Ptr < RHS.Ptr; 8472 if (LHS.Kind != RHS.Kind) 8473 return LHS.Kind < RHS.Kind; 8474 return false; 8475 } 8476 }; 8477 8478 /// Mapping from *single* memory location kinds, e.g., LOCAL_MEM with the 8479 /// value of NO_LOCAL_MEM, to the accesses encountered for this memory kind. 8480 using AccessSet = SmallSet<AccessInfo, 2, AccessInfo>; 8481 std::array<AccessSet *, llvm::CTLog2<VALID_STATE>()> AccessKind2Accesses; 8482 8483 /// Categorize the pointer arguments of CB that might access memory in 8484 /// AccessedLoc and update the state and access map accordingly. 8485 void 8486 categorizeArgumentPointerLocations(Attributor &A, CallBase &CB, 8487 AAMemoryLocation::StateType &AccessedLocs, 8488 bool &Changed); 8489 8490 /// Return the kind(s) of location that may be accessed by \p V. 8491 AAMemoryLocation::MemoryLocationsKind 8492 categorizeAccessedLocations(Attributor &A, Instruction &I, bool &Changed); 8493 8494 /// Return the access kind as determined by \p I. 8495 AccessKind getAccessKindFromInst(const Instruction *I) { 8496 AccessKind AK = READ_WRITE; 8497 if (I) { 8498 AK = I->mayReadFromMemory() ? READ : NONE; 8499 AK = AccessKind(AK | (I->mayWriteToMemory() ? WRITE : NONE)); 8500 } 8501 return AK; 8502 } 8503 8504 /// Update the state \p State and the AccessKind2Accesses given that \p I is 8505 /// an access of kind \p AK to a \p MLK memory location with the access 8506 /// pointer \p Ptr. 8507 void updateStateAndAccessesMap(AAMemoryLocation::StateType &State, 8508 MemoryLocationsKind MLK, const Instruction *I, 8509 const Value *Ptr, bool &Changed, 8510 AccessKind AK = READ_WRITE) { 8511 8512 assert(isPowerOf2_32(MLK) && "Expected a single location set!"); 8513 auto *&Accesses = AccessKind2Accesses[llvm::Log2_32(MLK)]; 8514 if (!Accesses) 8515 Accesses = new (Allocator) AccessSet(); 8516 Changed |= Accesses->insert(AccessInfo{I, Ptr, AK}).second; 8517 if (MLK == NO_UNKOWN_MEM) 8518 MLK = NO_LOCATIONS; 8519 State.removeAssumedBits(MLK); 8520 } 8521 8522 /// Determine the underlying locations kinds for \p Ptr, e.g., globals or 8523 /// arguments, and update the state and access map accordingly. 8524 void categorizePtrValue(Attributor &A, const Instruction &I, const Value &Ptr, 8525 AAMemoryLocation::StateType &State, bool &Changed, 8526 unsigned AccessAS = 0); 8527 8528 /// Used to allocate access sets. 8529 BumpPtrAllocator &Allocator; 8530 }; 8531 8532 void AAMemoryLocationImpl::categorizePtrValue( 8533 Attributor &A, const Instruction &I, const Value &Ptr, 8534 AAMemoryLocation::StateType &State, bool &Changed, unsigned AccessAS) { 8535 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize pointer locations for " 8536 << Ptr << " [" 8537 << getMemoryLocationsAsStr(State.getAssumed()) << "]\n"); 8538 8539 auto Pred = [&](Value &Obj) { 8540 unsigned ObjectAS = Obj.getType()->getPointerAddressSpace(); 8541 // TODO: recognize the TBAA used for constant accesses. 8542 MemoryLocationsKind MLK = NO_LOCATIONS; 8543 8544 // Filter accesses to constant (GPU) memory if we have an AS at the access 8545 // site or the object is known to actually have the associated AS. 8546 if ((AccessAS == (unsigned)AA::GPUAddressSpace::Constant || 8547 (ObjectAS == (unsigned)AA::GPUAddressSpace::Constant && 8548 isIdentifiedObject(&Obj))) && 8549 AA::isGPU(*I.getModule())) 8550 return true; 8551 8552 if (isa<UndefValue>(&Obj)) 8553 return true; 8554 if (isa<Argument>(&Obj)) { 8555 // TODO: For now we do not treat byval arguments as local copies performed 8556 // on the call edge, though, we should. To make that happen we need to 8557 // teach various passes, e.g., DSE, about the copy effect of a byval. That 8558 // would also allow us to mark functions only accessing byval arguments as 8559 // readnone again, arguably their accesses have no effect outside of the 8560 // function, like accesses to allocas. 8561 MLK = NO_ARGUMENT_MEM; 8562 } else if (auto *GV = dyn_cast<GlobalValue>(&Obj)) { 8563 // Reading constant memory is not treated as a read "effect" by the 8564 // function attr pass so we won't neither. Constants defined by TBAA are 8565 // similar. (We know we do not write it because it is constant.) 8566 if (auto *GVar = dyn_cast<GlobalVariable>(GV)) 8567 if (GVar->isConstant()) 8568 return true; 8569 8570 if (GV->hasLocalLinkage()) 8571 MLK = NO_GLOBAL_INTERNAL_MEM; 8572 else 8573 MLK = NO_GLOBAL_EXTERNAL_MEM; 8574 } else if (isa<ConstantPointerNull>(&Obj) && 8575 (!NullPointerIsDefined(getAssociatedFunction(), AccessAS) || 8576 !NullPointerIsDefined(getAssociatedFunction(), ObjectAS))) { 8577 return true; 8578 } else if (isa<AllocaInst>(&Obj)) { 8579 MLK = NO_LOCAL_MEM; 8580 } else if (const auto *CB = dyn_cast<CallBase>(&Obj)) { 8581 bool IsKnownNoAlias; 8582 if (AA::hasAssumedIRAttr<Attribute::NoAlias>( 8583 A, this, IRPosition::callsite_returned(*CB), DepClassTy::OPTIONAL, 8584 IsKnownNoAlias)) 8585 MLK = NO_MALLOCED_MEM; 8586 else 8587 MLK = NO_UNKOWN_MEM; 8588 } else { 8589 MLK = NO_UNKOWN_MEM; 8590 } 8591 8592 assert(MLK != NO_LOCATIONS && "No location specified!"); 8593 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Ptr value can be categorized: " 8594 << Obj << " -> " << getMemoryLocationsAsStr(MLK) << "\n"); 8595 updateStateAndAccessesMap(State, MLK, &I, &Obj, Changed, 8596 getAccessKindFromInst(&I)); 8597 8598 return true; 8599 }; 8600 8601 const auto *AA = A.getAAFor<AAUnderlyingObjects>( 8602 *this, IRPosition::value(Ptr), DepClassTy::OPTIONAL); 8603 if (!AA || !AA->forallUnderlyingObjects(Pred, AA::Intraprocedural)) { 8604 LLVM_DEBUG( 8605 dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n"); 8606 updateStateAndAccessesMap(State, NO_UNKOWN_MEM, &I, nullptr, Changed, 8607 getAccessKindFromInst(&I)); 8608 return; 8609 } 8610 8611 LLVM_DEBUG( 8612 dbgs() << "[AAMemoryLocation] Accessed locations with pointer locations: " 8613 << getMemoryLocationsAsStr(State.getAssumed()) << "\n"); 8614 } 8615 8616 void AAMemoryLocationImpl::categorizeArgumentPointerLocations( 8617 Attributor &A, CallBase &CB, AAMemoryLocation::StateType &AccessedLocs, 8618 bool &Changed) { 8619 for (unsigned ArgNo = 0, E = CB.arg_size(); ArgNo < E; ++ArgNo) { 8620 8621 // Skip non-pointer arguments. 8622 const Value *ArgOp = CB.getArgOperand(ArgNo); 8623 if (!ArgOp->getType()->isPtrOrPtrVectorTy()) 8624 continue; 8625 8626 // Skip readnone arguments. 8627 const IRPosition &ArgOpIRP = IRPosition::callsite_argument(CB, ArgNo); 8628 const auto *ArgOpMemLocationAA = 8629 A.getAAFor<AAMemoryBehavior>(*this, ArgOpIRP, DepClassTy::OPTIONAL); 8630 8631 if (ArgOpMemLocationAA && ArgOpMemLocationAA->isAssumedReadNone()) 8632 continue; 8633 8634 // Categorize potentially accessed pointer arguments as if there was an 8635 // access instruction with them as pointer. 8636 categorizePtrValue(A, CB, *ArgOp, AccessedLocs, Changed); 8637 } 8638 } 8639 8640 AAMemoryLocation::MemoryLocationsKind 8641 AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I, 8642 bool &Changed) { 8643 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize accessed locations for " 8644 << I << "\n"); 8645 8646 AAMemoryLocation::StateType AccessedLocs; 8647 AccessedLocs.intersectAssumedBits(NO_LOCATIONS); 8648 8649 if (auto *CB = dyn_cast<CallBase>(&I)) { 8650 8651 // First check if we assume any memory is access is visible. 8652 const auto *CBMemLocationAA = A.getAAFor<AAMemoryLocation>( 8653 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL); 8654 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I 8655 << " [" << CBMemLocationAA << "]\n"); 8656 if (!CBMemLocationAA) { 8657 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr, 8658 Changed, getAccessKindFromInst(&I)); 8659 return NO_UNKOWN_MEM; 8660 } 8661 8662 if (CBMemLocationAA->isAssumedReadNone()) 8663 return NO_LOCATIONS; 8664 8665 if (CBMemLocationAA->isAssumedInaccessibleMemOnly()) { 8666 updateStateAndAccessesMap(AccessedLocs, NO_INACCESSIBLE_MEM, &I, nullptr, 8667 Changed, getAccessKindFromInst(&I)); 8668 return AccessedLocs.getAssumed(); 8669 } 8670 8671 uint32_t CBAssumedNotAccessedLocs = 8672 CBMemLocationAA->getAssumedNotAccessedLocation(); 8673 8674 // Set the argmemonly and global bit as we handle them separately below. 8675 uint32_t CBAssumedNotAccessedLocsNoArgMem = 8676 CBAssumedNotAccessedLocs | NO_ARGUMENT_MEM | NO_GLOBAL_MEM; 8677 8678 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) { 8679 if (CBAssumedNotAccessedLocsNoArgMem & CurMLK) 8680 continue; 8681 updateStateAndAccessesMap(AccessedLocs, CurMLK, &I, nullptr, Changed, 8682 getAccessKindFromInst(&I)); 8683 } 8684 8685 // Now handle global memory if it might be accessed. This is slightly tricky 8686 // as NO_GLOBAL_MEM has multiple bits set. 8687 bool HasGlobalAccesses = ((~CBAssumedNotAccessedLocs) & NO_GLOBAL_MEM); 8688 if (HasGlobalAccesses) { 8689 auto AccessPred = [&](const Instruction *, const Value *Ptr, 8690 AccessKind Kind, MemoryLocationsKind MLK) { 8691 updateStateAndAccessesMap(AccessedLocs, MLK, &I, Ptr, Changed, 8692 getAccessKindFromInst(&I)); 8693 return true; 8694 }; 8695 if (!CBMemLocationAA->checkForAllAccessesToMemoryKind( 8696 AccessPred, inverseLocation(NO_GLOBAL_MEM, false, false))) 8697 return AccessedLocs.getWorstState(); 8698 } 8699 8700 LLVM_DEBUG( 8701 dbgs() << "[AAMemoryLocation] Accessed state before argument handling: " 8702 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n"); 8703 8704 // Now handle argument memory if it might be accessed. 8705 bool HasArgAccesses = ((~CBAssumedNotAccessedLocs) & NO_ARGUMENT_MEM); 8706 if (HasArgAccesses) 8707 categorizeArgumentPointerLocations(A, *CB, AccessedLocs, Changed); 8708 8709 LLVM_DEBUG( 8710 dbgs() << "[AAMemoryLocation] Accessed state after argument handling: " 8711 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n"); 8712 8713 return AccessedLocs.getAssumed(); 8714 } 8715 8716 if (const Value *Ptr = getPointerOperand(&I, /* AllowVolatile */ true)) { 8717 LLVM_DEBUG( 8718 dbgs() << "[AAMemoryLocation] Categorize memory access with pointer: " 8719 << I << " [" << *Ptr << "]\n"); 8720 categorizePtrValue(A, I, *Ptr, AccessedLocs, Changed, 8721 Ptr->getType()->getPointerAddressSpace()); 8722 return AccessedLocs.getAssumed(); 8723 } 8724 8725 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Failed to categorize instruction: " 8726 << I << "\n"); 8727 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr, Changed, 8728 getAccessKindFromInst(&I)); 8729 return AccessedLocs.getAssumed(); 8730 } 8731 8732 /// An AA to represent the memory behavior function attributes. 8733 struct AAMemoryLocationFunction final : public AAMemoryLocationImpl { 8734 AAMemoryLocationFunction(const IRPosition &IRP, Attributor &A) 8735 : AAMemoryLocationImpl(IRP, A) {} 8736 8737 /// See AbstractAttribute::updateImpl(Attributor &A). 8738 ChangeStatus updateImpl(Attributor &A) override { 8739 8740 const auto *MemBehaviorAA = 8741 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE); 8742 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) { 8743 if (MemBehaviorAA->isKnownReadNone()) 8744 return indicateOptimisticFixpoint(); 8745 assert(isAssumedReadNone() && 8746 "AAMemoryLocation was not read-none but AAMemoryBehavior was!"); 8747 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL); 8748 return ChangeStatus::UNCHANGED; 8749 } 8750 8751 // The current assumed state used to determine a change. 8752 auto AssumedState = getAssumed(); 8753 bool Changed = false; 8754 8755 auto CheckRWInst = [&](Instruction &I) { 8756 MemoryLocationsKind MLK = categorizeAccessedLocations(A, I, Changed); 8757 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I 8758 << ": " << getMemoryLocationsAsStr(MLK) << "\n"); 8759 removeAssumedBits(inverseLocation(MLK, false, false)); 8760 // Stop once only the valid bit set in the *not assumed location*, thus 8761 // once we don't actually exclude any memory locations in the state. 8762 return getAssumedNotAccessedLocation() != VALID_STATE; 8763 }; 8764 8765 bool UsedAssumedInformation = false; 8766 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this, 8767 UsedAssumedInformation)) 8768 return indicatePessimisticFixpoint(); 8769 8770 Changed |= AssumedState != getAssumed(); 8771 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 8772 } 8773 8774 /// See AbstractAttribute::trackStatistics() 8775 void trackStatistics() const override { 8776 if (isAssumedReadNone()) 8777 STATS_DECLTRACK_FN_ATTR(readnone) 8778 else if (isAssumedArgMemOnly()) 8779 STATS_DECLTRACK_FN_ATTR(argmemonly) 8780 else if (isAssumedInaccessibleMemOnly()) 8781 STATS_DECLTRACK_FN_ATTR(inaccessiblememonly) 8782 else if (isAssumedInaccessibleOrArgMemOnly()) 8783 STATS_DECLTRACK_FN_ATTR(inaccessiblememorargmemonly) 8784 } 8785 }; 8786 8787 /// AAMemoryLocation attribute for call sites. 8788 struct AAMemoryLocationCallSite final : AAMemoryLocationImpl { 8789 AAMemoryLocationCallSite(const IRPosition &IRP, Attributor &A) 8790 : AAMemoryLocationImpl(IRP, A) {} 8791 8792 /// See AbstractAttribute::updateImpl(...). 8793 ChangeStatus updateImpl(Attributor &A) override { 8794 // TODO: Once we have call site specific value information we can provide 8795 // call site specific liveness liveness information and then it makes 8796 // sense to specialize attributes for call sites arguments instead of 8797 // redirecting requests to the callee argument. 8798 Function *F = getAssociatedFunction(); 8799 const IRPosition &FnPos = IRPosition::function(*F); 8800 auto *FnAA = 8801 A.getAAFor<AAMemoryLocation>(*this, FnPos, DepClassTy::REQUIRED); 8802 if (!FnAA) 8803 return indicatePessimisticFixpoint(); 8804 bool Changed = false; 8805 auto AccessPred = [&](const Instruction *I, const Value *Ptr, 8806 AccessKind Kind, MemoryLocationsKind MLK) { 8807 updateStateAndAccessesMap(getState(), MLK, I, Ptr, Changed, 8808 getAccessKindFromInst(I)); 8809 return true; 8810 }; 8811 if (!FnAA->checkForAllAccessesToMemoryKind(AccessPred, ALL_LOCATIONS)) 8812 return indicatePessimisticFixpoint(); 8813 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 8814 } 8815 8816 /// See AbstractAttribute::trackStatistics() 8817 void trackStatistics() const override { 8818 if (isAssumedReadNone()) 8819 STATS_DECLTRACK_CS_ATTR(readnone) 8820 } 8821 }; 8822 } // namespace 8823 8824 /// ------------------ Value Constant Range Attribute ------------------------- 8825 8826 namespace { 8827 struct AAValueConstantRangeImpl : AAValueConstantRange { 8828 using StateType = IntegerRangeState; 8829 AAValueConstantRangeImpl(const IRPosition &IRP, Attributor &A) 8830 : AAValueConstantRange(IRP, A) {} 8831 8832 /// See AbstractAttribute::initialize(..). 8833 void initialize(Attributor &A) override { 8834 if (A.hasSimplificationCallback(getIRPosition())) { 8835 indicatePessimisticFixpoint(); 8836 return; 8837 } 8838 8839 // Intersect a range given by SCEV. 8840 intersectKnown(getConstantRangeFromSCEV(A, getCtxI())); 8841 8842 // Intersect a range given by LVI. 8843 intersectKnown(getConstantRangeFromLVI(A, getCtxI())); 8844 } 8845 8846 /// See AbstractAttribute::getAsStr(). 8847 const std::string getAsStr(Attributor *A) const override { 8848 std::string Str; 8849 llvm::raw_string_ostream OS(Str); 8850 OS << "range(" << getBitWidth() << ")<"; 8851 getKnown().print(OS); 8852 OS << " / "; 8853 getAssumed().print(OS); 8854 OS << ">"; 8855 return OS.str(); 8856 } 8857 8858 /// Helper function to get a SCEV expr for the associated value at program 8859 /// point \p I. 8860 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const { 8861 if (!getAnchorScope()) 8862 return nullptr; 8863 8864 ScalarEvolution *SE = 8865 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>( 8866 *getAnchorScope()); 8867 8868 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>( 8869 *getAnchorScope()); 8870 8871 if (!SE || !LI) 8872 return nullptr; 8873 8874 const SCEV *S = SE->getSCEV(&getAssociatedValue()); 8875 if (!I) 8876 return S; 8877 8878 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent())); 8879 } 8880 8881 /// Helper function to get a range from SCEV for the associated value at 8882 /// program point \p I. 8883 ConstantRange getConstantRangeFromSCEV(Attributor &A, 8884 const Instruction *I = nullptr) const { 8885 if (!getAnchorScope()) 8886 return getWorstState(getBitWidth()); 8887 8888 ScalarEvolution *SE = 8889 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>( 8890 *getAnchorScope()); 8891 8892 const SCEV *S = getSCEV(A, I); 8893 if (!SE || !S) 8894 return getWorstState(getBitWidth()); 8895 8896 return SE->getUnsignedRange(S); 8897 } 8898 8899 /// Helper function to get a range from LVI for the associated value at 8900 /// program point \p I. 8901 ConstantRange 8902 getConstantRangeFromLVI(Attributor &A, 8903 const Instruction *CtxI = nullptr) const { 8904 if (!getAnchorScope()) 8905 return getWorstState(getBitWidth()); 8906 8907 LazyValueInfo *LVI = 8908 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>( 8909 *getAnchorScope()); 8910 8911 if (!LVI || !CtxI) 8912 return getWorstState(getBitWidth()); 8913 return LVI->getConstantRange(&getAssociatedValue(), 8914 const_cast<Instruction *>(CtxI)); 8915 } 8916 8917 /// Return true if \p CtxI is valid for querying outside analyses. 8918 /// This basically makes sure we do not ask intra-procedural analysis 8919 /// about a context in the wrong function or a context that violates 8920 /// dominance assumptions they might have. The \p AllowAACtxI flag indicates 8921 /// if the original context of this AA is OK or should be considered invalid. 8922 bool isValidCtxInstructionForOutsideAnalysis(Attributor &A, 8923 const Instruction *CtxI, 8924 bool AllowAACtxI) const { 8925 if (!CtxI || (!AllowAACtxI && CtxI == getCtxI())) 8926 return false; 8927 8928 // Our context might be in a different function, neither intra-procedural 8929 // analysis (ScalarEvolution nor LazyValueInfo) can handle that. 8930 if (!AA::isValidInScope(getAssociatedValue(), CtxI->getFunction())) 8931 return false; 8932 8933 // If the context is not dominated by the value there are paths to the 8934 // context that do not define the value. This cannot be handled by 8935 // LazyValueInfo so we need to bail. 8936 if (auto *I = dyn_cast<Instruction>(&getAssociatedValue())) { 8937 InformationCache &InfoCache = A.getInfoCache(); 8938 const DominatorTree *DT = 8939 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>( 8940 *I->getFunction()); 8941 return DT && DT->dominates(I, CtxI); 8942 } 8943 8944 return true; 8945 } 8946 8947 /// See AAValueConstantRange::getKnownConstantRange(..). 8948 ConstantRange 8949 getKnownConstantRange(Attributor &A, 8950 const Instruction *CtxI = nullptr) const override { 8951 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI, 8952 /* AllowAACtxI */ false)) 8953 return getKnown(); 8954 8955 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI); 8956 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI); 8957 return getKnown().intersectWith(SCEVR).intersectWith(LVIR); 8958 } 8959 8960 /// See AAValueConstantRange::getAssumedConstantRange(..). 8961 ConstantRange 8962 getAssumedConstantRange(Attributor &A, 8963 const Instruction *CtxI = nullptr) const override { 8964 // TODO: Make SCEV use Attributor assumption. 8965 // We may be able to bound a variable range via assumptions in 8966 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to 8967 // evolve to x^2 + x, then we can say that y is in [2, 12]. 8968 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI, 8969 /* AllowAACtxI */ false)) 8970 return getAssumed(); 8971 8972 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI); 8973 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI); 8974 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR); 8975 } 8976 8977 /// Helper function to create MDNode for range metadata. 8978 static MDNode * 8979 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx, 8980 const ConstantRange &AssumedConstantRange) { 8981 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get( 8982 Ty, AssumedConstantRange.getLower())), 8983 ConstantAsMetadata::get(ConstantInt::get( 8984 Ty, AssumedConstantRange.getUpper()))}; 8985 return MDNode::get(Ctx, LowAndHigh); 8986 } 8987 8988 /// Return true if \p Assumed is included in \p KnownRanges. 8989 static bool isBetterRange(const ConstantRange &Assumed, MDNode *KnownRanges) { 8990 8991 if (Assumed.isFullSet()) 8992 return false; 8993 8994 if (!KnownRanges) 8995 return true; 8996 8997 // If multiple ranges are annotated in IR, we give up to annotate assumed 8998 // range for now. 8999 9000 // TODO: If there exists a known range which containts assumed range, we 9001 // can say assumed range is better. 9002 if (KnownRanges->getNumOperands() > 2) 9003 return false; 9004 9005 ConstantInt *Lower = 9006 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0)); 9007 ConstantInt *Upper = 9008 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1)); 9009 9010 ConstantRange Known(Lower->getValue(), Upper->getValue()); 9011 return Known.contains(Assumed) && Known != Assumed; 9012 } 9013 9014 /// Helper function to set range metadata. 9015 static bool 9016 setRangeMetadataIfisBetterRange(Instruction *I, 9017 const ConstantRange &AssumedConstantRange) { 9018 auto *OldRangeMD = I->getMetadata(LLVMContext::MD_range); 9019 if (isBetterRange(AssumedConstantRange, OldRangeMD)) { 9020 if (!AssumedConstantRange.isEmptySet()) { 9021 I->setMetadata(LLVMContext::MD_range, 9022 getMDNodeForConstantRange(I->getType(), I->getContext(), 9023 AssumedConstantRange)); 9024 return true; 9025 } 9026 } 9027 return false; 9028 } 9029 9030 /// See AbstractAttribute::manifest() 9031 ChangeStatus manifest(Attributor &A) override { 9032 ChangeStatus Changed = ChangeStatus::UNCHANGED; 9033 ConstantRange AssumedConstantRange = getAssumedConstantRange(A); 9034 assert(!AssumedConstantRange.isFullSet() && "Invalid state"); 9035 9036 auto &V = getAssociatedValue(); 9037 if (!AssumedConstantRange.isEmptySet() && 9038 !AssumedConstantRange.isSingleElement()) { 9039 if (Instruction *I = dyn_cast<Instruction>(&V)) { 9040 assert(I == getCtxI() && "Should not annotate an instruction which is " 9041 "not the context instruction"); 9042 if (isa<CallInst>(I) || isa<LoadInst>(I)) 9043 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange)) 9044 Changed = ChangeStatus::CHANGED; 9045 } 9046 } 9047 9048 return Changed; 9049 } 9050 }; 9051 9052 struct AAValueConstantRangeArgument final 9053 : AAArgumentFromCallSiteArguments< 9054 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState, 9055 true /* BridgeCallBaseContext */> { 9056 using Base = AAArgumentFromCallSiteArguments< 9057 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState, 9058 true /* BridgeCallBaseContext */>; 9059 AAValueConstantRangeArgument(const IRPosition &IRP, Attributor &A) 9060 : Base(IRP, A) {} 9061 9062 /// See AbstractAttribute::trackStatistics() 9063 void trackStatistics() const override { 9064 STATS_DECLTRACK_ARG_ATTR(value_range) 9065 } 9066 }; 9067 9068 struct AAValueConstantRangeReturned 9069 : AAReturnedFromReturnedValues<AAValueConstantRange, 9070 AAValueConstantRangeImpl, 9071 AAValueConstantRangeImpl::StateType, 9072 /* PropogateCallBaseContext */ true> { 9073 using Base = 9074 AAReturnedFromReturnedValues<AAValueConstantRange, 9075 AAValueConstantRangeImpl, 9076 AAValueConstantRangeImpl::StateType, 9077 /* PropogateCallBaseContext */ true>; 9078 AAValueConstantRangeReturned(const IRPosition &IRP, Attributor &A) 9079 : Base(IRP, A) {} 9080 9081 /// See AbstractAttribute::initialize(...). 9082 void initialize(Attributor &A) override { 9083 if (!A.isFunctionIPOAmendable(*getAssociatedFunction())) 9084 indicatePessimisticFixpoint(); 9085 } 9086 9087 /// See AbstractAttribute::trackStatistics() 9088 void trackStatistics() const override { 9089 STATS_DECLTRACK_FNRET_ATTR(value_range) 9090 } 9091 }; 9092 9093 struct AAValueConstantRangeFloating : AAValueConstantRangeImpl { 9094 AAValueConstantRangeFloating(const IRPosition &IRP, Attributor &A) 9095 : AAValueConstantRangeImpl(IRP, A) {} 9096 9097 /// See AbstractAttribute::initialize(...). 9098 void initialize(Attributor &A) override { 9099 AAValueConstantRangeImpl::initialize(A); 9100 if (isAtFixpoint()) 9101 return; 9102 9103 Value &V = getAssociatedValue(); 9104 9105 if (auto *C = dyn_cast<ConstantInt>(&V)) { 9106 unionAssumed(ConstantRange(C->getValue())); 9107 indicateOptimisticFixpoint(); 9108 return; 9109 } 9110 9111 if (isa<UndefValue>(&V)) { 9112 // Collapse the undef state to 0. 9113 unionAssumed(ConstantRange(APInt(getBitWidth(), 0))); 9114 indicateOptimisticFixpoint(); 9115 return; 9116 } 9117 9118 if (isa<CallBase>(&V)) 9119 return; 9120 9121 if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V)) 9122 return; 9123 9124 // If it is a load instruction with range metadata, use it. 9125 if (LoadInst *LI = dyn_cast<LoadInst>(&V)) 9126 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) { 9127 intersectKnown(getConstantRangeFromMetadata(*RangeMD)); 9128 return; 9129 } 9130 9131 // We can work with PHI and select instruction as we traverse their operands 9132 // during update. 9133 if (isa<SelectInst>(V) || isa<PHINode>(V)) 9134 return; 9135 9136 // Otherwise we give up. 9137 indicatePessimisticFixpoint(); 9138 9139 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: " 9140 << getAssociatedValue() << "\n"); 9141 } 9142 9143 bool calculateBinaryOperator( 9144 Attributor &A, BinaryOperator *BinOp, IntegerRangeState &T, 9145 const Instruction *CtxI, 9146 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) { 9147 Value *LHS = BinOp->getOperand(0); 9148 Value *RHS = BinOp->getOperand(1); 9149 9150 // Simplify the operands first. 9151 bool UsedAssumedInformation = false; 9152 const auto &SimplifiedLHS = A.getAssumedSimplified( 9153 IRPosition::value(*LHS, getCallBaseContext()), *this, 9154 UsedAssumedInformation, AA::Interprocedural); 9155 if (!SimplifiedLHS.has_value()) 9156 return true; 9157 if (!*SimplifiedLHS) 9158 return false; 9159 LHS = *SimplifiedLHS; 9160 9161 const auto &SimplifiedRHS = A.getAssumedSimplified( 9162 IRPosition::value(*RHS, getCallBaseContext()), *this, 9163 UsedAssumedInformation, AA::Interprocedural); 9164 if (!SimplifiedRHS.has_value()) 9165 return true; 9166 if (!*SimplifiedRHS) 9167 return false; 9168 RHS = *SimplifiedRHS; 9169 9170 // TODO: Allow non integers as well. 9171 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy()) 9172 return false; 9173 9174 auto *LHSAA = A.getAAFor<AAValueConstantRange>( 9175 *this, IRPosition::value(*LHS, getCallBaseContext()), 9176 DepClassTy::REQUIRED); 9177 if (!LHSAA) 9178 return false; 9179 QuerriedAAs.push_back(LHSAA); 9180 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI); 9181 9182 auto *RHSAA = A.getAAFor<AAValueConstantRange>( 9183 *this, IRPosition::value(*RHS, getCallBaseContext()), 9184 DepClassTy::REQUIRED); 9185 if (!RHSAA) 9186 return false; 9187 QuerriedAAs.push_back(RHSAA); 9188 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI); 9189 9190 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange); 9191 9192 T.unionAssumed(AssumedRange); 9193 9194 // TODO: Track a known state too. 9195 9196 return T.isValidState(); 9197 } 9198 9199 bool calculateCastInst( 9200 Attributor &A, CastInst *CastI, IntegerRangeState &T, 9201 const Instruction *CtxI, 9202 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) { 9203 assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!"); 9204 // TODO: Allow non integers as well. 9205 Value *OpV = CastI->getOperand(0); 9206 9207 // Simplify the operand first. 9208 bool UsedAssumedInformation = false; 9209 const auto &SimplifiedOpV = A.getAssumedSimplified( 9210 IRPosition::value(*OpV, getCallBaseContext()), *this, 9211 UsedAssumedInformation, AA::Interprocedural); 9212 if (!SimplifiedOpV.has_value()) 9213 return true; 9214 if (!*SimplifiedOpV) 9215 return false; 9216 OpV = *SimplifiedOpV; 9217 9218 if (!OpV->getType()->isIntegerTy()) 9219 return false; 9220 9221 auto *OpAA = A.getAAFor<AAValueConstantRange>( 9222 *this, IRPosition::value(*OpV, getCallBaseContext()), 9223 DepClassTy::REQUIRED); 9224 if (!OpAA) 9225 return false; 9226 QuerriedAAs.push_back(OpAA); 9227 T.unionAssumed(OpAA->getAssumed().castOp(CastI->getOpcode(), 9228 getState().getBitWidth())); 9229 return T.isValidState(); 9230 } 9231 9232 bool 9233 calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T, 9234 const Instruction *CtxI, 9235 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) { 9236 Value *LHS = CmpI->getOperand(0); 9237 Value *RHS = CmpI->getOperand(1); 9238 9239 // Simplify the operands first. 9240 bool UsedAssumedInformation = false; 9241 const auto &SimplifiedLHS = A.getAssumedSimplified( 9242 IRPosition::value(*LHS, getCallBaseContext()), *this, 9243 UsedAssumedInformation, AA::Interprocedural); 9244 if (!SimplifiedLHS.has_value()) 9245 return true; 9246 if (!*SimplifiedLHS) 9247 return false; 9248 LHS = *SimplifiedLHS; 9249 9250 const auto &SimplifiedRHS = A.getAssumedSimplified( 9251 IRPosition::value(*RHS, getCallBaseContext()), *this, 9252 UsedAssumedInformation, AA::Interprocedural); 9253 if (!SimplifiedRHS.has_value()) 9254 return true; 9255 if (!*SimplifiedRHS) 9256 return false; 9257 RHS = *SimplifiedRHS; 9258 9259 // TODO: Allow non integers as well. 9260 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy()) 9261 return false; 9262 9263 auto *LHSAA = A.getAAFor<AAValueConstantRange>( 9264 *this, IRPosition::value(*LHS, getCallBaseContext()), 9265 DepClassTy::REQUIRED); 9266 if (!LHSAA) 9267 return false; 9268 QuerriedAAs.push_back(LHSAA); 9269 auto *RHSAA = A.getAAFor<AAValueConstantRange>( 9270 *this, IRPosition::value(*RHS, getCallBaseContext()), 9271 DepClassTy::REQUIRED); 9272 if (!RHSAA) 9273 return false; 9274 QuerriedAAs.push_back(RHSAA); 9275 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI); 9276 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI); 9277 9278 // If one of them is empty set, we can't decide. 9279 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet()) 9280 return true; 9281 9282 bool MustTrue = false, MustFalse = false; 9283 9284 auto AllowedRegion = 9285 ConstantRange::makeAllowedICmpRegion(CmpI->getPredicate(), RHSAARange); 9286 9287 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet()) 9288 MustFalse = true; 9289 9290 if (LHSAARange.icmp(CmpI->getPredicate(), RHSAARange)) 9291 MustTrue = true; 9292 9293 assert((!MustTrue || !MustFalse) && 9294 "Either MustTrue or MustFalse should be false!"); 9295 9296 if (MustTrue) 9297 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1))); 9298 else if (MustFalse) 9299 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0))); 9300 else 9301 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true)); 9302 9303 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " after " 9304 << (MustTrue ? "true" : (MustFalse ? "false" : "unknown")) 9305 << ": " << T << "\n\t" << *LHSAA << "\t<op>\n\t" 9306 << *RHSAA); 9307 9308 // TODO: Track a known state too. 9309 return T.isValidState(); 9310 } 9311 9312 /// See AbstractAttribute::updateImpl(...). 9313 ChangeStatus updateImpl(Attributor &A) override { 9314 9315 IntegerRangeState T(getBitWidth()); 9316 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool { 9317 Instruction *I = dyn_cast<Instruction>(&V); 9318 if (!I || isa<CallBase>(I)) { 9319 9320 // Simplify the operand first. 9321 bool UsedAssumedInformation = false; 9322 const auto &SimplifiedOpV = A.getAssumedSimplified( 9323 IRPosition::value(V, getCallBaseContext()), *this, 9324 UsedAssumedInformation, AA::Interprocedural); 9325 if (!SimplifiedOpV.has_value()) 9326 return true; 9327 if (!*SimplifiedOpV) 9328 return false; 9329 Value *VPtr = *SimplifiedOpV; 9330 9331 // If the value is not instruction, we query AA to Attributor. 9332 const auto *AA = A.getAAFor<AAValueConstantRange>( 9333 *this, IRPosition::value(*VPtr, getCallBaseContext()), 9334 DepClassTy::REQUIRED); 9335 9336 // Clamp operator is not used to utilize a program point CtxI. 9337 if (AA) 9338 T.unionAssumed(AA->getAssumedConstantRange(A, CtxI)); 9339 else 9340 return false; 9341 9342 return T.isValidState(); 9343 } 9344 9345 SmallVector<const AAValueConstantRange *, 4> QuerriedAAs; 9346 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) { 9347 if (!calculateBinaryOperator(A, BinOp, T, CtxI, QuerriedAAs)) 9348 return false; 9349 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) { 9350 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs)) 9351 return false; 9352 } else if (auto *CastI = dyn_cast<CastInst>(I)) { 9353 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs)) 9354 return false; 9355 } else { 9356 // Give up with other instructions. 9357 // TODO: Add other instructions 9358 9359 T.indicatePessimisticFixpoint(); 9360 return false; 9361 } 9362 9363 // Catch circular reasoning in a pessimistic way for now. 9364 // TODO: Check how the range evolves and if we stripped anything, see also 9365 // AADereferenceable or AAAlign for similar situations. 9366 for (const AAValueConstantRange *QueriedAA : QuerriedAAs) { 9367 if (QueriedAA != this) 9368 continue; 9369 // If we are in a stady state we do not need to worry. 9370 if (T.getAssumed() == getState().getAssumed()) 9371 continue; 9372 T.indicatePessimisticFixpoint(); 9373 } 9374 9375 return T.isValidState(); 9376 }; 9377 9378 if (!VisitValueCB(getAssociatedValue(), getCtxI())) 9379 return indicatePessimisticFixpoint(); 9380 9381 // Ensure that long def-use chains can't cause circular reasoning either by 9382 // introducing a cutoff below. 9383 if (clampStateAndIndicateChange(getState(), T) == ChangeStatus::UNCHANGED) 9384 return ChangeStatus::UNCHANGED; 9385 if (++NumChanges > MaxNumChanges) { 9386 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] performed " << NumChanges 9387 << " but only " << MaxNumChanges 9388 << " are allowed to avoid cyclic reasoning."); 9389 return indicatePessimisticFixpoint(); 9390 } 9391 return ChangeStatus::CHANGED; 9392 } 9393 9394 /// See AbstractAttribute::trackStatistics() 9395 void trackStatistics() const override { 9396 STATS_DECLTRACK_FLOATING_ATTR(value_range) 9397 } 9398 9399 /// Tracker to bail after too many widening steps of the constant range. 9400 int NumChanges = 0; 9401 9402 /// Upper bound for the number of allowed changes (=widening steps) for the 9403 /// constant range before we give up. 9404 static constexpr int MaxNumChanges = 5; 9405 }; 9406 9407 struct AAValueConstantRangeFunction : AAValueConstantRangeImpl { 9408 AAValueConstantRangeFunction(const IRPosition &IRP, Attributor &A) 9409 : AAValueConstantRangeImpl(IRP, A) {} 9410 9411 /// See AbstractAttribute::initialize(...). 9412 ChangeStatus updateImpl(Attributor &A) override { 9413 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will " 9414 "not be called"); 9415 } 9416 9417 /// See AbstractAttribute::trackStatistics() 9418 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) } 9419 }; 9420 9421 struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction { 9422 AAValueConstantRangeCallSite(const IRPosition &IRP, Attributor &A) 9423 : AAValueConstantRangeFunction(IRP, A) {} 9424 9425 /// See AbstractAttribute::trackStatistics() 9426 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) } 9427 }; 9428 9429 struct AAValueConstantRangeCallSiteReturned 9430 : AACallSiteReturnedFromReturned<AAValueConstantRange, 9431 AAValueConstantRangeImpl, 9432 AAValueConstantRangeImpl::StateType, 9433 /* IntroduceCallBaseContext */ true> { 9434 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP, Attributor &A) 9435 : AACallSiteReturnedFromReturned<AAValueConstantRange, 9436 AAValueConstantRangeImpl, 9437 AAValueConstantRangeImpl::StateType, 9438 /* IntroduceCallBaseContext */ true>(IRP, 9439 A) { 9440 } 9441 9442 /// See AbstractAttribute::initialize(...). 9443 void initialize(Attributor &A) override { 9444 // If it is a load instruction with range metadata, use the metadata. 9445 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue())) 9446 if (auto *RangeMD = CI->getMetadata(LLVMContext::MD_range)) 9447 intersectKnown(getConstantRangeFromMetadata(*RangeMD)); 9448 9449 AAValueConstantRangeImpl::initialize(A); 9450 } 9451 9452 /// See AbstractAttribute::trackStatistics() 9453 void trackStatistics() const override { 9454 STATS_DECLTRACK_CSRET_ATTR(value_range) 9455 } 9456 }; 9457 struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating { 9458 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP, Attributor &A) 9459 : AAValueConstantRangeFloating(IRP, A) {} 9460 9461 /// See AbstractAttribute::manifest() 9462 ChangeStatus manifest(Attributor &A) override { 9463 return ChangeStatus::UNCHANGED; 9464 } 9465 9466 /// See AbstractAttribute::trackStatistics() 9467 void trackStatistics() const override { 9468 STATS_DECLTRACK_CSARG_ATTR(value_range) 9469 } 9470 }; 9471 } // namespace 9472 9473 /// ------------------ Potential Values Attribute ------------------------- 9474 9475 namespace { 9476 struct AAPotentialConstantValuesImpl : AAPotentialConstantValues { 9477 using StateType = PotentialConstantIntValuesState; 9478 9479 AAPotentialConstantValuesImpl(const IRPosition &IRP, Attributor &A) 9480 : AAPotentialConstantValues(IRP, A) {} 9481 9482 /// See AbstractAttribute::initialize(..). 9483 void initialize(Attributor &A) override { 9484 if (A.hasSimplificationCallback(getIRPosition())) 9485 indicatePessimisticFixpoint(); 9486 else 9487 AAPotentialConstantValues::initialize(A); 9488 } 9489 9490 bool fillSetWithConstantValues(Attributor &A, const IRPosition &IRP, SetTy &S, 9491 bool &ContainsUndef, bool ForSelf) { 9492 SmallVector<AA::ValueAndContext> Values; 9493 bool UsedAssumedInformation = false; 9494 if (!A.getAssumedSimplifiedValues(IRP, *this, Values, AA::Interprocedural, 9495 UsedAssumedInformation)) { 9496 // Avoid recursion when the caller is computing constant values for this 9497 // IRP itself. 9498 if (ForSelf) 9499 return false; 9500 if (!IRP.getAssociatedType()->isIntegerTy()) 9501 return false; 9502 auto *PotentialValuesAA = A.getAAFor<AAPotentialConstantValues>( 9503 *this, IRP, DepClassTy::REQUIRED); 9504 if (!PotentialValuesAA || !PotentialValuesAA->getState().isValidState()) 9505 return false; 9506 ContainsUndef = PotentialValuesAA->getState().undefIsContained(); 9507 S = PotentialValuesAA->getState().getAssumedSet(); 9508 return true; 9509 } 9510 9511 // Copy all the constant values, except UndefValue. ContainsUndef is true 9512 // iff Values contains only UndefValue instances. If there are other known 9513 // constants, then UndefValue is dropped. 9514 ContainsUndef = false; 9515 for (auto &It : Values) { 9516 if (isa<UndefValue>(It.getValue())) { 9517 ContainsUndef = true; 9518 continue; 9519 } 9520 auto *CI = dyn_cast<ConstantInt>(It.getValue()); 9521 if (!CI) 9522 return false; 9523 S.insert(CI->getValue()); 9524 } 9525 ContainsUndef &= S.empty(); 9526 9527 return true; 9528 } 9529 9530 /// See AbstractAttribute::getAsStr(). 9531 const std::string getAsStr(Attributor *A) const override { 9532 std::string Str; 9533 llvm::raw_string_ostream OS(Str); 9534 OS << getState(); 9535 return OS.str(); 9536 } 9537 9538 /// See AbstractAttribute::updateImpl(...). 9539 ChangeStatus updateImpl(Attributor &A) override { 9540 return indicatePessimisticFixpoint(); 9541 } 9542 }; 9543 9544 struct AAPotentialConstantValuesArgument final 9545 : AAArgumentFromCallSiteArguments<AAPotentialConstantValues, 9546 AAPotentialConstantValuesImpl, 9547 PotentialConstantIntValuesState> { 9548 using Base = AAArgumentFromCallSiteArguments<AAPotentialConstantValues, 9549 AAPotentialConstantValuesImpl, 9550 PotentialConstantIntValuesState>; 9551 AAPotentialConstantValuesArgument(const IRPosition &IRP, Attributor &A) 9552 : Base(IRP, A) {} 9553 9554 /// See AbstractAttribute::trackStatistics() 9555 void trackStatistics() const override { 9556 STATS_DECLTRACK_ARG_ATTR(potential_values) 9557 } 9558 }; 9559 9560 struct AAPotentialConstantValuesReturned 9561 : AAReturnedFromReturnedValues<AAPotentialConstantValues, 9562 AAPotentialConstantValuesImpl> { 9563 using Base = AAReturnedFromReturnedValues<AAPotentialConstantValues, 9564 AAPotentialConstantValuesImpl>; 9565 AAPotentialConstantValuesReturned(const IRPosition &IRP, Attributor &A) 9566 : Base(IRP, A) {} 9567 9568 void initialize(Attributor &A) override { 9569 if (!A.isFunctionIPOAmendable(*getAssociatedFunction())) 9570 indicatePessimisticFixpoint(); 9571 Base::initialize(A); 9572 } 9573 9574 /// See AbstractAttribute::trackStatistics() 9575 void trackStatistics() const override { 9576 STATS_DECLTRACK_FNRET_ATTR(potential_values) 9577 } 9578 }; 9579 9580 struct AAPotentialConstantValuesFloating : AAPotentialConstantValuesImpl { 9581 AAPotentialConstantValuesFloating(const IRPosition &IRP, Attributor &A) 9582 : AAPotentialConstantValuesImpl(IRP, A) {} 9583 9584 /// See AbstractAttribute::initialize(..). 9585 void initialize(Attributor &A) override { 9586 AAPotentialConstantValuesImpl::initialize(A); 9587 if (isAtFixpoint()) 9588 return; 9589 9590 Value &V = getAssociatedValue(); 9591 9592 if (auto *C = dyn_cast<ConstantInt>(&V)) { 9593 unionAssumed(C->getValue()); 9594 indicateOptimisticFixpoint(); 9595 return; 9596 } 9597 9598 if (isa<UndefValue>(&V)) { 9599 unionAssumedWithUndef(); 9600 indicateOptimisticFixpoint(); 9601 return; 9602 } 9603 9604 if (isa<BinaryOperator>(&V) || isa<ICmpInst>(&V) || isa<CastInst>(&V)) 9605 return; 9606 9607 if (isa<SelectInst>(V) || isa<PHINode>(V) || isa<LoadInst>(V)) 9608 return; 9609 9610 indicatePessimisticFixpoint(); 9611 9612 LLVM_DEBUG(dbgs() << "[AAPotentialConstantValues] We give up: " 9613 << getAssociatedValue() << "\n"); 9614 } 9615 9616 static bool calculateICmpInst(const ICmpInst *ICI, const APInt &LHS, 9617 const APInt &RHS) { 9618 return ICmpInst::compare(LHS, RHS, ICI->getPredicate()); 9619 } 9620 9621 static APInt calculateCastInst(const CastInst *CI, const APInt &Src, 9622 uint32_t ResultBitWidth) { 9623 Instruction::CastOps CastOp = CI->getOpcode(); 9624 switch (CastOp) { 9625 default: 9626 llvm_unreachable("unsupported or not integer cast"); 9627 case Instruction::Trunc: 9628 return Src.trunc(ResultBitWidth); 9629 case Instruction::SExt: 9630 return Src.sext(ResultBitWidth); 9631 case Instruction::ZExt: 9632 return Src.zext(ResultBitWidth); 9633 case Instruction::BitCast: 9634 return Src; 9635 } 9636 } 9637 9638 static APInt calculateBinaryOperator(const BinaryOperator *BinOp, 9639 const APInt &LHS, const APInt &RHS, 9640 bool &SkipOperation, bool &Unsupported) { 9641 Instruction::BinaryOps BinOpcode = BinOp->getOpcode(); 9642 // Unsupported is set to true when the binary operator is not supported. 9643 // SkipOperation is set to true when UB occur with the given operand pair 9644 // (LHS, RHS). 9645 // TODO: we should look at nsw and nuw keywords to handle operations 9646 // that create poison or undef value. 9647 switch (BinOpcode) { 9648 default: 9649 Unsupported = true; 9650 return LHS; 9651 case Instruction::Add: 9652 return LHS + RHS; 9653 case Instruction::Sub: 9654 return LHS - RHS; 9655 case Instruction::Mul: 9656 return LHS * RHS; 9657 case Instruction::UDiv: 9658 if (RHS.isZero()) { 9659 SkipOperation = true; 9660 return LHS; 9661 } 9662 return LHS.udiv(RHS); 9663 case Instruction::SDiv: 9664 if (RHS.isZero()) { 9665 SkipOperation = true; 9666 return LHS; 9667 } 9668 return LHS.sdiv(RHS); 9669 case Instruction::URem: 9670 if (RHS.isZero()) { 9671 SkipOperation = true; 9672 return LHS; 9673 } 9674 return LHS.urem(RHS); 9675 case Instruction::SRem: 9676 if (RHS.isZero()) { 9677 SkipOperation = true; 9678 return LHS; 9679 } 9680 return LHS.srem(RHS); 9681 case Instruction::Shl: 9682 return LHS.shl(RHS); 9683 case Instruction::LShr: 9684 return LHS.lshr(RHS); 9685 case Instruction::AShr: 9686 return LHS.ashr(RHS); 9687 case Instruction::And: 9688 return LHS & RHS; 9689 case Instruction::Or: 9690 return LHS | RHS; 9691 case Instruction::Xor: 9692 return LHS ^ RHS; 9693 } 9694 } 9695 9696 bool calculateBinaryOperatorAndTakeUnion(const BinaryOperator *BinOp, 9697 const APInt &LHS, const APInt &RHS) { 9698 bool SkipOperation = false; 9699 bool Unsupported = false; 9700 APInt Result = 9701 calculateBinaryOperator(BinOp, LHS, RHS, SkipOperation, Unsupported); 9702 if (Unsupported) 9703 return false; 9704 // If SkipOperation is true, we can ignore this operand pair (L, R). 9705 if (!SkipOperation) 9706 unionAssumed(Result); 9707 return isValidState(); 9708 } 9709 9710 ChangeStatus updateWithICmpInst(Attributor &A, ICmpInst *ICI) { 9711 auto AssumedBefore = getAssumed(); 9712 Value *LHS = ICI->getOperand(0); 9713 Value *RHS = ICI->getOperand(1); 9714 9715 bool LHSContainsUndef = false, RHSContainsUndef = false; 9716 SetTy LHSAAPVS, RHSAAPVS; 9717 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS, 9718 LHSContainsUndef, /* ForSelf */ false) || 9719 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS, 9720 RHSContainsUndef, /* ForSelf */ false)) 9721 return indicatePessimisticFixpoint(); 9722 9723 // TODO: make use of undef flag to limit potential values aggressively. 9724 bool MaybeTrue = false, MaybeFalse = false; 9725 const APInt Zero(RHS->getType()->getIntegerBitWidth(), 0); 9726 if (LHSContainsUndef && RHSContainsUndef) { 9727 // The result of any comparison between undefs can be soundly replaced 9728 // with undef. 9729 unionAssumedWithUndef(); 9730 } else if (LHSContainsUndef) { 9731 for (const APInt &R : RHSAAPVS) { 9732 bool CmpResult = calculateICmpInst(ICI, Zero, R); 9733 MaybeTrue |= CmpResult; 9734 MaybeFalse |= !CmpResult; 9735 if (MaybeTrue & MaybeFalse) 9736 return indicatePessimisticFixpoint(); 9737 } 9738 } else if (RHSContainsUndef) { 9739 for (const APInt &L : LHSAAPVS) { 9740 bool CmpResult = calculateICmpInst(ICI, L, Zero); 9741 MaybeTrue |= CmpResult; 9742 MaybeFalse |= !CmpResult; 9743 if (MaybeTrue & MaybeFalse) 9744 return indicatePessimisticFixpoint(); 9745 } 9746 } else { 9747 for (const APInt &L : LHSAAPVS) { 9748 for (const APInt &R : RHSAAPVS) { 9749 bool CmpResult = calculateICmpInst(ICI, L, R); 9750 MaybeTrue |= CmpResult; 9751 MaybeFalse |= !CmpResult; 9752 if (MaybeTrue & MaybeFalse) 9753 return indicatePessimisticFixpoint(); 9754 } 9755 } 9756 } 9757 if (MaybeTrue) 9758 unionAssumed(APInt(/* numBits */ 1, /* val */ 1)); 9759 if (MaybeFalse) 9760 unionAssumed(APInt(/* numBits */ 1, /* val */ 0)); 9761 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 9762 : ChangeStatus::CHANGED; 9763 } 9764 9765 ChangeStatus updateWithSelectInst(Attributor &A, SelectInst *SI) { 9766 auto AssumedBefore = getAssumed(); 9767 Value *LHS = SI->getTrueValue(); 9768 Value *RHS = SI->getFalseValue(); 9769 9770 bool UsedAssumedInformation = false; 9771 std::optional<Constant *> C = A.getAssumedConstant( 9772 *SI->getCondition(), *this, UsedAssumedInformation); 9773 9774 // Check if we only need one operand. 9775 bool OnlyLeft = false, OnlyRight = false; 9776 if (C && *C && (*C)->isOneValue()) 9777 OnlyLeft = true; 9778 else if (C && *C && (*C)->isZeroValue()) 9779 OnlyRight = true; 9780 9781 bool LHSContainsUndef = false, RHSContainsUndef = false; 9782 SetTy LHSAAPVS, RHSAAPVS; 9783 if (!OnlyRight && 9784 !fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS, 9785 LHSContainsUndef, /* ForSelf */ false)) 9786 return indicatePessimisticFixpoint(); 9787 9788 if (!OnlyLeft && 9789 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS, 9790 RHSContainsUndef, /* ForSelf */ false)) 9791 return indicatePessimisticFixpoint(); 9792 9793 if (OnlyLeft || OnlyRight) { 9794 // select (true/false), lhs, rhs 9795 auto *OpAA = OnlyLeft ? &LHSAAPVS : &RHSAAPVS; 9796 auto Undef = OnlyLeft ? LHSContainsUndef : RHSContainsUndef; 9797 9798 if (Undef) 9799 unionAssumedWithUndef(); 9800 else { 9801 for (const auto &It : *OpAA) 9802 unionAssumed(It); 9803 } 9804 9805 } else if (LHSContainsUndef && RHSContainsUndef) { 9806 // select i1 *, undef , undef => undef 9807 unionAssumedWithUndef(); 9808 } else { 9809 for (const auto &It : LHSAAPVS) 9810 unionAssumed(It); 9811 for (const auto &It : RHSAAPVS) 9812 unionAssumed(It); 9813 } 9814 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 9815 : ChangeStatus::CHANGED; 9816 } 9817 9818 ChangeStatus updateWithCastInst(Attributor &A, CastInst *CI) { 9819 auto AssumedBefore = getAssumed(); 9820 if (!CI->isIntegerCast()) 9821 return indicatePessimisticFixpoint(); 9822 assert(CI->getNumOperands() == 1 && "Expected cast to be unary!"); 9823 uint32_t ResultBitWidth = CI->getDestTy()->getIntegerBitWidth(); 9824 Value *Src = CI->getOperand(0); 9825 9826 bool SrcContainsUndef = false; 9827 SetTy SrcPVS; 9828 if (!fillSetWithConstantValues(A, IRPosition::value(*Src), SrcPVS, 9829 SrcContainsUndef, /* ForSelf */ false)) 9830 return indicatePessimisticFixpoint(); 9831 9832 if (SrcContainsUndef) 9833 unionAssumedWithUndef(); 9834 else { 9835 for (const APInt &S : SrcPVS) { 9836 APInt T = calculateCastInst(CI, S, ResultBitWidth); 9837 unionAssumed(T); 9838 } 9839 } 9840 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 9841 : ChangeStatus::CHANGED; 9842 } 9843 9844 ChangeStatus updateWithBinaryOperator(Attributor &A, BinaryOperator *BinOp) { 9845 auto AssumedBefore = getAssumed(); 9846 Value *LHS = BinOp->getOperand(0); 9847 Value *RHS = BinOp->getOperand(1); 9848 9849 bool LHSContainsUndef = false, RHSContainsUndef = false; 9850 SetTy LHSAAPVS, RHSAAPVS; 9851 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS, 9852 LHSContainsUndef, /* ForSelf */ false) || 9853 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS, 9854 RHSContainsUndef, /* ForSelf */ false)) 9855 return indicatePessimisticFixpoint(); 9856 9857 const APInt Zero = APInt(LHS->getType()->getIntegerBitWidth(), 0); 9858 9859 // TODO: make use of undef flag to limit potential values aggressively. 9860 if (LHSContainsUndef && RHSContainsUndef) { 9861 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, Zero)) 9862 return indicatePessimisticFixpoint(); 9863 } else if (LHSContainsUndef) { 9864 for (const APInt &R : RHSAAPVS) { 9865 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, R)) 9866 return indicatePessimisticFixpoint(); 9867 } 9868 } else if (RHSContainsUndef) { 9869 for (const APInt &L : LHSAAPVS) { 9870 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, Zero)) 9871 return indicatePessimisticFixpoint(); 9872 } 9873 } else { 9874 for (const APInt &L : LHSAAPVS) { 9875 for (const APInt &R : RHSAAPVS) { 9876 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, R)) 9877 return indicatePessimisticFixpoint(); 9878 } 9879 } 9880 } 9881 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 9882 : ChangeStatus::CHANGED; 9883 } 9884 9885 ChangeStatus updateWithInstruction(Attributor &A, Instruction *Inst) { 9886 auto AssumedBefore = getAssumed(); 9887 SetTy Incoming; 9888 bool ContainsUndef; 9889 if (!fillSetWithConstantValues(A, IRPosition::value(*Inst), Incoming, 9890 ContainsUndef, /* ForSelf */ true)) 9891 return indicatePessimisticFixpoint(); 9892 if (ContainsUndef) { 9893 unionAssumedWithUndef(); 9894 } else { 9895 for (const auto &It : Incoming) 9896 unionAssumed(It); 9897 } 9898 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 9899 : ChangeStatus::CHANGED; 9900 } 9901 9902 /// See AbstractAttribute::updateImpl(...). 9903 ChangeStatus updateImpl(Attributor &A) override { 9904 Value &V = getAssociatedValue(); 9905 Instruction *I = dyn_cast<Instruction>(&V); 9906 9907 if (auto *ICI = dyn_cast<ICmpInst>(I)) 9908 return updateWithICmpInst(A, ICI); 9909 9910 if (auto *SI = dyn_cast<SelectInst>(I)) 9911 return updateWithSelectInst(A, SI); 9912 9913 if (auto *CI = dyn_cast<CastInst>(I)) 9914 return updateWithCastInst(A, CI); 9915 9916 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) 9917 return updateWithBinaryOperator(A, BinOp); 9918 9919 if (isa<PHINode>(I) || isa<LoadInst>(I)) 9920 return updateWithInstruction(A, I); 9921 9922 return indicatePessimisticFixpoint(); 9923 } 9924 9925 /// See AbstractAttribute::trackStatistics() 9926 void trackStatistics() const override { 9927 STATS_DECLTRACK_FLOATING_ATTR(potential_values) 9928 } 9929 }; 9930 9931 struct AAPotentialConstantValuesFunction : AAPotentialConstantValuesImpl { 9932 AAPotentialConstantValuesFunction(const IRPosition &IRP, Attributor &A) 9933 : AAPotentialConstantValuesImpl(IRP, A) {} 9934 9935 /// See AbstractAttribute::initialize(...). 9936 ChangeStatus updateImpl(Attributor &A) override { 9937 llvm_unreachable( 9938 "AAPotentialConstantValues(Function|CallSite)::updateImpl will " 9939 "not be called"); 9940 } 9941 9942 /// See AbstractAttribute::trackStatistics() 9943 void trackStatistics() const override { 9944 STATS_DECLTRACK_FN_ATTR(potential_values) 9945 } 9946 }; 9947 9948 struct AAPotentialConstantValuesCallSite : AAPotentialConstantValuesFunction { 9949 AAPotentialConstantValuesCallSite(const IRPosition &IRP, Attributor &A) 9950 : AAPotentialConstantValuesFunction(IRP, A) {} 9951 9952 /// See AbstractAttribute::trackStatistics() 9953 void trackStatistics() const override { 9954 STATS_DECLTRACK_CS_ATTR(potential_values) 9955 } 9956 }; 9957 9958 struct AAPotentialConstantValuesCallSiteReturned 9959 : AACallSiteReturnedFromReturned<AAPotentialConstantValues, 9960 AAPotentialConstantValuesImpl> { 9961 AAPotentialConstantValuesCallSiteReturned(const IRPosition &IRP, 9962 Attributor &A) 9963 : AACallSiteReturnedFromReturned<AAPotentialConstantValues, 9964 AAPotentialConstantValuesImpl>(IRP, A) {} 9965 9966 /// See AbstractAttribute::trackStatistics() 9967 void trackStatistics() const override { 9968 STATS_DECLTRACK_CSRET_ATTR(potential_values) 9969 } 9970 }; 9971 9972 struct AAPotentialConstantValuesCallSiteArgument 9973 : AAPotentialConstantValuesFloating { 9974 AAPotentialConstantValuesCallSiteArgument(const IRPosition &IRP, 9975 Attributor &A) 9976 : AAPotentialConstantValuesFloating(IRP, A) {} 9977 9978 /// See AbstractAttribute::initialize(..). 9979 void initialize(Attributor &A) override { 9980 AAPotentialConstantValuesImpl::initialize(A); 9981 if (isAtFixpoint()) 9982 return; 9983 9984 Value &V = getAssociatedValue(); 9985 9986 if (auto *C = dyn_cast<ConstantInt>(&V)) { 9987 unionAssumed(C->getValue()); 9988 indicateOptimisticFixpoint(); 9989 return; 9990 } 9991 9992 if (isa<UndefValue>(&V)) { 9993 unionAssumedWithUndef(); 9994 indicateOptimisticFixpoint(); 9995 return; 9996 } 9997 } 9998 9999 /// See AbstractAttribute::updateImpl(...). 10000 ChangeStatus updateImpl(Attributor &A) override { 10001 Value &V = getAssociatedValue(); 10002 auto AssumedBefore = getAssumed(); 10003 auto *AA = A.getAAFor<AAPotentialConstantValues>( 10004 *this, IRPosition::value(V), DepClassTy::REQUIRED); 10005 if (!AA) 10006 return indicatePessimisticFixpoint(); 10007 const auto &S = AA->getAssumed(); 10008 unionAssumed(S); 10009 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 10010 : ChangeStatus::CHANGED; 10011 } 10012 10013 /// See AbstractAttribute::trackStatistics() 10014 void trackStatistics() const override { 10015 STATS_DECLTRACK_CSARG_ATTR(potential_values) 10016 } 10017 }; 10018 } // namespace 10019 10020 /// ------------------------ NoUndef Attribute --------------------------------- 10021 bool AANoUndef::isImpliedByIR(Attributor &A, const IRPosition &IRP, 10022 Attribute::AttrKind ImpliedAttributeKind, 10023 bool IgnoreSubsumingPositions) { 10024 assert(ImpliedAttributeKind == Attribute::NoUndef && 10025 "Unexpected attribute kind"); 10026 if (A.hasAttr(IRP, {Attribute::NoUndef}, IgnoreSubsumingPositions, 10027 Attribute::NoUndef)) 10028 return true; 10029 10030 Value &Val = IRP.getAssociatedValue(); 10031 if (IRP.getPositionKind() != IRPosition::IRP_RETURNED && 10032 isGuaranteedNotToBeUndefOrPoison(&Val)) { 10033 LLVMContext &Ctx = Val.getContext(); 10034 A.manifestAttrs(IRP, Attribute::get(Ctx, Attribute::NoUndef)); 10035 return true; 10036 } 10037 10038 return false; 10039 } 10040 10041 namespace { 10042 struct AANoUndefImpl : AANoUndef { 10043 AANoUndefImpl(const IRPosition &IRP, Attributor &A) : AANoUndef(IRP, A) {} 10044 10045 /// See AbstractAttribute::initialize(...). 10046 void initialize(Attributor &A) override { 10047 Value &V = getAssociatedValue(); 10048 if (isa<UndefValue>(V)) 10049 indicatePessimisticFixpoint(); 10050 assert(!isImpliedByIR(A, getIRPosition(), Attribute::NoUndef)); 10051 } 10052 10053 /// See followUsesInMBEC 10054 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I, 10055 AANoUndef::StateType &State) { 10056 const Value *UseV = U->get(); 10057 const DominatorTree *DT = nullptr; 10058 AssumptionCache *AC = nullptr; 10059 InformationCache &InfoCache = A.getInfoCache(); 10060 if (Function *F = getAnchorScope()) { 10061 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F); 10062 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F); 10063 } 10064 State.setKnown(isGuaranteedNotToBeUndefOrPoison(UseV, AC, I, DT)); 10065 bool TrackUse = false; 10066 // Track use for instructions which must produce undef or poison bits when 10067 // at least one operand contains such bits. 10068 if (isa<CastInst>(*I) || isa<GetElementPtrInst>(*I)) 10069 TrackUse = true; 10070 return TrackUse; 10071 } 10072 10073 /// See AbstractAttribute::getAsStr(). 10074 const std::string getAsStr(Attributor *A) const override { 10075 return getAssumed() ? "noundef" : "may-undef-or-poison"; 10076 } 10077 10078 ChangeStatus manifest(Attributor &A) override { 10079 // We don't manifest noundef attribute for dead positions because the 10080 // associated values with dead positions would be replaced with undef 10081 // values. 10082 bool UsedAssumedInformation = false; 10083 if (A.isAssumedDead(getIRPosition(), nullptr, nullptr, 10084 UsedAssumedInformation)) 10085 return ChangeStatus::UNCHANGED; 10086 // A position whose simplified value does not have any value is 10087 // considered to be dead. We don't manifest noundef in such positions for 10088 // the same reason above. 10089 if (!A.getAssumedSimplified(getIRPosition(), *this, UsedAssumedInformation, 10090 AA::Interprocedural) 10091 .has_value()) 10092 return ChangeStatus::UNCHANGED; 10093 return AANoUndef::manifest(A); 10094 } 10095 }; 10096 10097 struct AANoUndefFloating : public AANoUndefImpl { 10098 AANoUndefFloating(const IRPosition &IRP, Attributor &A) 10099 : AANoUndefImpl(IRP, A) {} 10100 10101 /// See AbstractAttribute::initialize(...). 10102 void initialize(Attributor &A) override { 10103 AANoUndefImpl::initialize(A); 10104 if (!getState().isAtFixpoint()) 10105 if (Instruction *CtxI = getCtxI()) 10106 followUsesInMBEC(*this, A, getState(), *CtxI); 10107 } 10108 10109 /// See AbstractAttribute::updateImpl(...). 10110 ChangeStatus updateImpl(Attributor &A) override { 10111 auto VisitValueCB = [&](const IRPosition &IRP) -> bool { 10112 bool IsKnownNoUndef; 10113 return AA::hasAssumedIRAttr<Attribute::NoUndef>( 10114 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoUndef); 10115 }; 10116 10117 bool Stripped; 10118 bool UsedAssumedInformation = false; 10119 Value *AssociatedValue = &getAssociatedValue(); 10120 SmallVector<AA::ValueAndContext> Values; 10121 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values, 10122 AA::AnyScope, UsedAssumedInformation)) 10123 Stripped = false; 10124 else 10125 Stripped = 10126 Values.size() != 1 || Values.front().getValue() != AssociatedValue; 10127 10128 if (!Stripped) { 10129 // If we haven't stripped anything we might still be able to use a 10130 // different AA, but only if the IRP changes. Effectively when we 10131 // interpret this not as a call site value but as a floating/argument 10132 // value. 10133 const IRPosition AVIRP = IRPosition::value(*AssociatedValue); 10134 if (AVIRP == getIRPosition() || !VisitValueCB(AVIRP)) 10135 return indicatePessimisticFixpoint(); 10136 return ChangeStatus::UNCHANGED; 10137 } 10138 10139 for (const auto &VAC : Values) 10140 if (!VisitValueCB(IRPosition::value(*VAC.getValue()))) 10141 return indicatePessimisticFixpoint(); 10142 10143 return ChangeStatus::UNCHANGED; 10144 } 10145 10146 /// See AbstractAttribute::trackStatistics() 10147 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) } 10148 }; 10149 10150 struct AANoUndefReturned final 10151 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl, 10152 AANoUndef::StateType, false, 10153 Attribute::NoUndef> { 10154 AANoUndefReturned(const IRPosition &IRP, Attributor &A) 10155 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl, 10156 AANoUndef::StateType, false, 10157 Attribute::NoUndef>(IRP, A) {} 10158 10159 /// See AbstractAttribute::trackStatistics() 10160 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) } 10161 }; 10162 10163 struct AANoUndefArgument final 10164 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl, 10165 AANoUndef::StateType, false, 10166 Attribute::NoUndef> { 10167 AANoUndefArgument(const IRPosition &IRP, Attributor &A) 10168 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl, 10169 AANoUndef::StateType, false, 10170 Attribute::NoUndef>(IRP, A) {} 10171 10172 /// See AbstractAttribute::trackStatistics() 10173 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noundef) } 10174 }; 10175 10176 struct AANoUndefCallSiteArgument final : AANoUndefFloating { 10177 AANoUndefCallSiteArgument(const IRPosition &IRP, Attributor &A) 10178 : AANoUndefFloating(IRP, A) {} 10179 10180 /// See AbstractAttribute::trackStatistics() 10181 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noundef) } 10182 }; 10183 10184 struct AANoUndefCallSiteReturned final 10185 : AACallSiteReturnedFromReturned<AANoUndef, AANoUndefImpl, 10186 AANoUndef::StateType, false, 10187 Attribute::NoUndef> { 10188 AANoUndefCallSiteReturned(const IRPosition &IRP, Attributor &A) 10189 : AACallSiteReturnedFromReturned<AANoUndef, AANoUndefImpl, 10190 AANoUndef::StateType, false, 10191 Attribute::NoUndef>(IRP, A) {} 10192 10193 /// See AbstractAttribute::trackStatistics() 10194 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) } 10195 }; 10196 10197 /// ------------------------ NoFPClass Attribute ------------------------------- 10198 10199 struct AANoFPClassImpl : AANoFPClass { 10200 AANoFPClassImpl(const IRPosition &IRP, Attributor &A) : AANoFPClass(IRP, A) {} 10201 10202 void initialize(Attributor &A) override { 10203 const IRPosition &IRP = getIRPosition(); 10204 10205 Value &V = IRP.getAssociatedValue(); 10206 if (isa<UndefValue>(V)) { 10207 indicateOptimisticFixpoint(); 10208 return; 10209 } 10210 10211 SmallVector<Attribute> Attrs; 10212 A.getAttrs(getIRPosition(), {Attribute::NoFPClass}, Attrs, false); 10213 for (const auto &Attr : Attrs) { 10214 addKnownBits(Attr.getNoFPClass()); 10215 return; 10216 } 10217 10218 const DataLayout &DL = A.getDataLayout(); 10219 if (getPositionKind() != IRPosition::IRP_RETURNED) { 10220 KnownFPClass KnownFPClass = computeKnownFPClass(&V, DL); 10221 addKnownBits(~KnownFPClass.KnownFPClasses); 10222 } 10223 10224 if (Instruction *CtxI = getCtxI()) 10225 followUsesInMBEC(*this, A, getState(), *CtxI); 10226 } 10227 10228 /// See followUsesInMBEC 10229 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I, 10230 AANoFPClass::StateType &State) { 10231 const Value *UseV = U->get(); 10232 const DominatorTree *DT = nullptr; 10233 AssumptionCache *AC = nullptr; 10234 const TargetLibraryInfo *TLI = nullptr; 10235 InformationCache &InfoCache = A.getInfoCache(); 10236 10237 if (Function *F = getAnchorScope()) { 10238 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F); 10239 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F); 10240 TLI = InfoCache.getTargetLibraryInfoForFunction(*F); 10241 } 10242 10243 const DataLayout &DL = A.getDataLayout(); 10244 10245 KnownFPClass KnownFPClass = 10246 computeKnownFPClass(UseV, DL, 10247 /*InterestedClasses=*/fcAllFlags, 10248 /*Depth=*/0, TLI, AC, I, DT); 10249 State.addKnownBits(~KnownFPClass.KnownFPClasses); 10250 10251 bool TrackUse = false; 10252 return TrackUse; 10253 } 10254 10255 const std::string getAsStr(Attributor *A) const override { 10256 std::string Result = "nofpclass"; 10257 raw_string_ostream OS(Result); 10258 OS << getAssumedNoFPClass(); 10259 return Result; 10260 } 10261 10262 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, 10263 SmallVectorImpl<Attribute> &Attrs) const override { 10264 Attrs.emplace_back(Attribute::getWithNoFPClass(Ctx, getAssumedNoFPClass())); 10265 } 10266 }; 10267 10268 struct AANoFPClassFloating : public AANoFPClassImpl { 10269 AANoFPClassFloating(const IRPosition &IRP, Attributor &A) 10270 : AANoFPClassImpl(IRP, A) {} 10271 10272 /// See AbstractAttribute::updateImpl(...). 10273 ChangeStatus updateImpl(Attributor &A) override { 10274 SmallVector<AA::ValueAndContext> Values; 10275 bool UsedAssumedInformation = false; 10276 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values, 10277 AA::AnyScope, UsedAssumedInformation)) { 10278 Values.push_back({getAssociatedValue(), getCtxI()}); 10279 } 10280 10281 StateType T; 10282 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool { 10283 const auto *AA = A.getAAFor<AANoFPClass>(*this, IRPosition::value(V), 10284 DepClassTy::REQUIRED); 10285 if (!AA || this == AA) { 10286 T.indicatePessimisticFixpoint(); 10287 } else { 10288 const AANoFPClass::StateType &S = 10289 static_cast<const AANoFPClass::StateType &>(AA->getState()); 10290 T ^= S; 10291 } 10292 return T.isValidState(); 10293 }; 10294 10295 for (const auto &VAC : Values) 10296 if (!VisitValueCB(*VAC.getValue(), VAC.getCtxI())) 10297 return indicatePessimisticFixpoint(); 10298 10299 return clampStateAndIndicateChange(getState(), T); 10300 } 10301 10302 /// See AbstractAttribute::trackStatistics() 10303 void trackStatistics() const override { 10304 STATS_DECLTRACK_FNRET_ATTR(nofpclass) 10305 } 10306 }; 10307 10308 struct AANoFPClassReturned final 10309 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl, 10310 AANoFPClassImpl::StateType, false, Attribute::None, false> { 10311 AANoFPClassReturned(const IRPosition &IRP, Attributor &A) 10312 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl, 10313 AANoFPClassImpl::StateType, false, Attribute::None, false>( 10314 IRP, A) {} 10315 10316 /// See AbstractAttribute::trackStatistics() 10317 void trackStatistics() const override { 10318 STATS_DECLTRACK_FNRET_ATTR(nofpclass) 10319 } 10320 }; 10321 10322 struct AANoFPClassArgument final 10323 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl> { 10324 AANoFPClassArgument(const IRPosition &IRP, Attributor &A) 10325 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl>(IRP, A) {} 10326 10327 /// See AbstractAttribute::trackStatistics() 10328 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofpclass) } 10329 }; 10330 10331 struct AANoFPClassCallSiteArgument final : AANoFPClassFloating { 10332 AANoFPClassCallSiteArgument(const IRPosition &IRP, Attributor &A) 10333 : AANoFPClassFloating(IRP, A) {} 10334 10335 /// See AbstractAttribute::trackStatistics() 10336 void trackStatistics() const override { 10337 STATS_DECLTRACK_CSARG_ATTR(nofpclass) 10338 } 10339 }; 10340 10341 struct AANoFPClassCallSiteReturned final 10342 : AACallSiteReturnedFromReturned<AANoFPClass, AANoFPClassImpl> { 10343 AANoFPClassCallSiteReturned(const IRPosition &IRP, Attributor &A) 10344 : AACallSiteReturnedFromReturned<AANoFPClass, AANoFPClassImpl>(IRP, A) {} 10345 10346 /// See AbstractAttribute::trackStatistics() 10347 void trackStatistics() const override { 10348 STATS_DECLTRACK_CSRET_ATTR(nofpclass) 10349 } 10350 }; 10351 10352 struct AACallEdgesImpl : public AACallEdges { 10353 AACallEdgesImpl(const IRPosition &IRP, Attributor &A) : AACallEdges(IRP, A) {} 10354 10355 const SetVector<Function *> &getOptimisticEdges() const override { 10356 return CalledFunctions; 10357 } 10358 10359 bool hasUnknownCallee() const override { return HasUnknownCallee; } 10360 10361 bool hasNonAsmUnknownCallee() const override { 10362 return HasUnknownCalleeNonAsm; 10363 } 10364 10365 const std::string getAsStr(Attributor *A) const override { 10366 return "CallEdges[" + std::to_string(HasUnknownCallee) + "," + 10367 std::to_string(CalledFunctions.size()) + "]"; 10368 } 10369 10370 void trackStatistics() const override {} 10371 10372 protected: 10373 void addCalledFunction(Function *Fn, ChangeStatus &Change) { 10374 if (CalledFunctions.insert(Fn)) { 10375 Change = ChangeStatus::CHANGED; 10376 LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn->getName() 10377 << "\n"); 10378 } 10379 } 10380 10381 void setHasUnknownCallee(bool NonAsm, ChangeStatus &Change) { 10382 if (!HasUnknownCallee) 10383 Change = ChangeStatus::CHANGED; 10384 if (NonAsm && !HasUnknownCalleeNonAsm) 10385 Change = ChangeStatus::CHANGED; 10386 HasUnknownCalleeNonAsm |= NonAsm; 10387 HasUnknownCallee = true; 10388 } 10389 10390 private: 10391 /// Optimistic set of functions that might be called by this position. 10392 SetVector<Function *> CalledFunctions; 10393 10394 /// Is there any call with a unknown callee. 10395 bool HasUnknownCallee = false; 10396 10397 /// Is there any call with a unknown callee, excluding any inline asm. 10398 bool HasUnknownCalleeNonAsm = false; 10399 }; 10400 10401 struct AACallEdgesCallSite : public AACallEdgesImpl { 10402 AACallEdgesCallSite(const IRPosition &IRP, Attributor &A) 10403 : AACallEdgesImpl(IRP, A) {} 10404 /// See AbstractAttribute::updateImpl(...). 10405 ChangeStatus updateImpl(Attributor &A) override { 10406 ChangeStatus Change = ChangeStatus::UNCHANGED; 10407 10408 auto VisitValue = [&](Value &V, const Instruction *CtxI) -> bool { 10409 if (Function *Fn = dyn_cast<Function>(&V)) { 10410 addCalledFunction(Fn, Change); 10411 } else { 10412 LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n"); 10413 setHasUnknownCallee(true, Change); 10414 } 10415 10416 // Explore all values. 10417 return true; 10418 }; 10419 10420 SmallVector<AA::ValueAndContext> Values; 10421 // Process any value that we might call. 10422 auto ProcessCalledOperand = [&](Value *V, Instruction *CtxI) { 10423 if (isa<Constant>(V)) { 10424 VisitValue(*V, CtxI); 10425 return; 10426 } 10427 10428 bool UsedAssumedInformation = false; 10429 Values.clear(); 10430 if (!A.getAssumedSimplifiedValues(IRPosition::value(*V), *this, Values, 10431 AA::AnyScope, UsedAssumedInformation)) { 10432 Values.push_back({*V, CtxI}); 10433 } 10434 for (auto &VAC : Values) 10435 VisitValue(*VAC.getValue(), VAC.getCtxI()); 10436 }; 10437 10438 CallBase *CB = cast<CallBase>(getCtxI()); 10439 10440 if (auto *IA = dyn_cast<InlineAsm>(CB->getCalledOperand())) { 10441 if (IA->hasSideEffects() && 10442 !hasAssumption(*CB->getCaller(), "ompx_no_call_asm") && 10443 !hasAssumption(*CB, "ompx_no_call_asm")) { 10444 setHasUnknownCallee(false, Change); 10445 } 10446 return Change; 10447 } 10448 10449 // Process callee metadata if available. 10450 if (auto *MD = getCtxI()->getMetadata(LLVMContext::MD_callees)) { 10451 for (const auto &Op : MD->operands()) { 10452 Function *Callee = mdconst::dyn_extract_or_null<Function>(Op); 10453 if (Callee) 10454 addCalledFunction(Callee, Change); 10455 } 10456 return Change; 10457 } 10458 10459 // The most simple case. 10460 ProcessCalledOperand(CB->getCalledOperand(), CB); 10461 10462 // Process callback functions. 10463 SmallVector<const Use *, 4u> CallbackUses; 10464 AbstractCallSite::getCallbackUses(*CB, CallbackUses); 10465 for (const Use *U : CallbackUses) 10466 ProcessCalledOperand(U->get(), CB); 10467 10468 return Change; 10469 } 10470 }; 10471 10472 struct AACallEdgesFunction : public AACallEdgesImpl { 10473 AACallEdgesFunction(const IRPosition &IRP, Attributor &A) 10474 : AACallEdgesImpl(IRP, A) {} 10475 10476 /// See AbstractAttribute::updateImpl(...). 10477 ChangeStatus updateImpl(Attributor &A) override { 10478 ChangeStatus Change = ChangeStatus::UNCHANGED; 10479 10480 auto ProcessCallInst = [&](Instruction &Inst) { 10481 CallBase &CB = cast<CallBase>(Inst); 10482 10483 auto *CBEdges = A.getAAFor<AACallEdges>( 10484 *this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED); 10485 if (!CBEdges) 10486 return false; 10487 if (CBEdges->hasNonAsmUnknownCallee()) 10488 setHasUnknownCallee(true, Change); 10489 if (CBEdges->hasUnknownCallee()) 10490 setHasUnknownCallee(false, Change); 10491 10492 for (Function *F : CBEdges->getOptimisticEdges()) 10493 addCalledFunction(F, Change); 10494 10495 return true; 10496 }; 10497 10498 // Visit all callable instructions. 10499 bool UsedAssumedInformation = false; 10500 if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this, 10501 UsedAssumedInformation, 10502 /* CheckBBLivenessOnly */ true)) { 10503 // If we haven't looked at all call like instructions, assume that there 10504 // are unknown callees. 10505 setHasUnknownCallee(true, Change); 10506 } 10507 10508 return Change; 10509 } 10510 }; 10511 10512 /// -------------------AAInterFnReachability Attribute-------------------------- 10513 10514 struct AAInterFnReachabilityFunction 10515 : public CachedReachabilityAA<AAInterFnReachability, Function> { 10516 using Base = CachedReachabilityAA<AAInterFnReachability, Function>; 10517 AAInterFnReachabilityFunction(const IRPosition &IRP, Attributor &A) 10518 : Base(IRP, A) {} 10519 10520 bool instructionCanReach( 10521 Attributor &A, const Instruction &From, const Function &To, 10522 const AA::InstExclusionSetTy *ExclusionSet, 10523 SmallPtrSet<const Function *, 16> *Visited) const override { 10524 assert(From.getFunction() == getAnchorScope() && "Queried the wrong AA!"); 10525 auto *NonConstThis = const_cast<AAInterFnReachabilityFunction *>(this); 10526 10527 RQITy StackRQI(A, From, To, ExclusionSet, false); 10528 typename RQITy::Reachable Result; 10529 if (!NonConstThis->checkQueryCache(A, StackRQI, Result)) 10530 return NonConstThis->isReachableImpl(A, StackRQI); 10531 return Result == RQITy::Reachable::Yes; 10532 } 10533 10534 bool isReachableImpl(Attributor &A, RQITy &RQI) override { 10535 return isReachableImpl(A, RQI, nullptr); 10536 } 10537 10538 bool isReachableImpl(Attributor &A, RQITy &RQI, 10539 SmallPtrSet<const Function *, 16> *Visited) { 10540 10541 SmallPtrSet<const Function *, 16> LocalVisited; 10542 if (!Visited) 10543 Visited = &LocalVisited; 10544 10545 auto CheckReachableCallBase = [&](CallBase *CB) { 10546 auto *CBEdges = A.getAAFor<AACallEdges>( 10547 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL); 10548 if (!CBEdges || !CBEdges->getState().isValidState()) 10549 return false; 10550 // TODO Check To backwards in this case. 10551 if (CBEdges->hasUnknownCallee()) 10552 return false; 10553 10554 for (Function *Fn : CBEdges->getOptimisticEdges()) { 10555 if (Fn == RQI.To) 10556 return false; 10557 if (!Visited->insert(Fn).second) 10558 continue; 10559 if (Fn->isDeclaration()) { 10560 if (Fn->hasFnAttribute(Attribute::NoCallback)) 10561 continue; 10562 // TODO Check To backwards in this case. 10563 return false; 10564 } 10565 10566 const AAInterFnReachability *InterFnReachability = this; 10567 if (Fn != getAnchorScope()) 10568 InterFnReachability = A.getAAFor<AAInterFnReachability>( 10569 *this, IRPosition::function(*Fn), DepClassTy::OPTIONAL); 10570 10571 const Instruction &FnFirstInst = Fn->getEntryBlock().front(); 10572 if (!InterFnReachability || 10573 InterFnReachability->instructionCanReach(A, FnFirstInst, *RQI.To, 10574 RQI.ExclusionSet, Visited)) 10575 return false; 10576 } 10577 return true; 10578 }; 10579 10580 const auto *IntraFnReachability = A.getAAFor<AAIntraFnReachability>( 10581 *this, IRPosition::function(*RQI.From->getFunction()), 10582 DepClassTy::OPTIONAL); 10583 10584 // Determine call like instructions that we can reach from the inst. 10585 auto CheckCallBase = [&](Instruction &CBInst) { 10586 if (!IntraFnReachability || !IntraFnReachability->isAssumedReachable( 10587 A, *RQI.From, CBInst, RQI.ExclusionSet)) 10588 return true; 10589 return CheckReachableCallBase(cast<CallBase>(&CBInst)); 10590 }; 10591 10592 bool UsedExclusionSet = /* conservative */ true; 10593 bool UsedAssumedInformation = false; 10594 if (!A.checkForAllCallLikeInstructions(CheckCallBase, *this, 10595 UsedAssumedInformation, 10596 /* CheckBBLivenessOnly */ true)) 10597 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet); 10598 10599 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet); 10600 } 10601 10602 void trackStatistics() const override {} 10603 10604 private: 10605 SmallVector<RQITy *> QueryVector; 10606 DenseSet<RQITy *> QueryCache; 10607 }; 10608 } // namespace 10609 10610 template <typename AAType> 10611 static std::optional<Constant *> 10612 askForAssumedConstant(Attributor &A, const AbstractAttribute &QueryingAA, 10613 const IRPosition &IRP, Type &Ty) { 10614 if (!Ty.isIntegerTy()) 10615 return nullptr; 10616 10617 // This will also pass the call base context. 10618 const auto *AA = A.getAAFor<AAType>(QueryingAA, IRP, DepClassTy::NONE); 10619 if (!AA) 10620 return nullptr; 10621 10622 std::optional<Constant *> COpt = AA->getAssumedConstant(A); 10623 10624 if (!COpt.has_value()) { 10625 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL); 10626 return std::nullopt; 10627 } 10628 if (auto *C = *COpt) { 10629 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL); 10630 return C; 10631 } 10632 return nullptr; 10633 } 10634 10635 Value *AAPotentialValues::getSingleValue( 10636 Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP, 10637 SmallVectorImpl<AA::ValueAndContext> &Values) { 10638 Type &Ty = *IRP.getAssociatedType(); 10639 std::optional<Value *> V; 10640 for (auto &It : Values) { 10641 V = AA::combineOptionalValuesInAAValueLatice(V, It.getValue(), &Ty); 10642 if (V.has_value() && !*V) 10643 break; 10644 } 10645 if (!V.has_value()) 10646 return UndefValue::get(&Ty); 10647 return *V; 10648 } 10649 10650 namespace { 10651 struct AAPotentialValuesImpl : AAPotentialValues { 10652 using StateType = PotentialLLVMValuesState; 10653 10654 AAPotentialValuesImpl(const IRPosition &IRP, Attributor &A) 10655 : AAPotentialValues(IRP, A) {} 10656 10657 /// See AbstractAttribute::initialize(..). 10658 void initialize(Attributor &A) override { 10659 if (A.hasSimplificationCallback(getIRPosition())) { 10660 indicatePessimisticFixpoint(); 10661 return; 10662 } 10663 Value *Stripped = getAssociatedValue().stripPointerCasts(); 10664 auto *CE = dyn_cast<ConstantExpr>(Stripped); 10665 if (isa<Constant>(Stripped) && 10666 (!CE || CE->getOpcode() != Instruction::ICmp)) { 10667 addValue(A, getState(), *Stripped, getCtxI(), AA::AnyScope, 10668 getAnchorScope()); 10669 indicateOptimisticFixpoint(); 10670 return; 10671 } 10672 AAPotentialValues::initialize(A); 10673 } 10674 10675 /// See AbstractAttribute::getAsStr(). 10676 const std::string getAsStr(Attributor *A) const override { 10677 std::string Str; 10678 llvm::raw_string_ostream OS(Str); 10679 OS << getState(); 10680 return OS.str(); 10681 } 10682 10683 template <typename AAType> 10684 static std::optional<Value *> askOtherAA(Attributor &A, 10685 const AbstractAttribute &AA, 10686 const IRPosition &IRP, Type &Ty) { 10687 if (isa<Constant>(IRP.getAssociatedValue())) 10688 return &IRP.getAssociatedValue(); 10689 std::optional<Constant *> C = askForAssumedConstant<AAType>(A, AA, IRP, Ty); 10690 if (!C) 10691 return std::nullopt; 10692 if (*C) 10693 if (auto *CC = AA::getWithType(**C, Ty)) 10694 return CC; 10695 return nullptr; 10696 } 10697 10698 virtual void addValue(Attributor &A, StateType &State, Value &V, 10699 const Instruction *CtxI, AA::ValueScope S, 10700 Function *AnchorScope) const { 10701 10702 IRPosition ValIRP = IRPosition::value(V); 10703 if (auto *CB = dyn_cast_or_null<CallBase>(CtxI)) { 10704 for (const auto &U : CB->args()) { 10705 if (U.get() != &V) 10706 continue; 10707 ValIRP = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U)); 10708 break; 10709 } 10710 } 10711 10712 Value *VPtr = &V; 10713 if (ValIRP.getAssociatedType()->isIntegerTy()) { 10714 Type &Ty = *getAssociatedType(); 10715 std::optional<Value *> SimpleV = 10716 askOtherAA<AAValueConstantRange>(A, *this, ValIRP, Ty); 10717 if (SimpleV.has_value() && !*SimpleV) { 10718 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>( 10719 *this, ValIRP, DepClassTy::OPTIONAL); 10720 if (PotentialConstantsAA && PotentialConstantsAA->isValidState()) { 10721 for (const auto &It : PotentialConstantsAA->getAssumedSet()) 10722 State.unionAssumed({{*ConstantInt::get(&Ty, It), nullptr}, S}); 10723 if (PotentialConstantsAA->undefIsContained()) 10724 State.unionAssumed({{*UndefValue::get(&Ty), nullptr}, S}); 10725 return; 10726 } 10727 } 10728 if (!SimpleV.has_value()) 10729 return; 10730 10731 if (*SimpleV) 10732 VPtr = *SimpleV; 10733 } 10734 10735 if (isa<ConstantInt>(VPtr)) 10736 CtxI = nullptr; 10737 if (!AA::isValidInScope(*VPtr, AnchorScope)) 10738 S = AA::ValueScope(S | AA::Interprocedural); 10739 10740 State.unionAssumed({{*VPtr, CtxI}, S}); 10741 } 10742 10743 /// Helper struct to tie a value+context pair together with the scope for 10744 /// which this is the simplified version. 10745 struct ItemInfo { 10746 AA::ValueAndContext I; 10747 AA::ValueScope S; 10748 10749 bool operator==(const ItemInfo &II) const { 10750 return II.I == I && II.S == S; 10751 }; 10752 bool operator<(const ItemInfo &II) const { 10753 if (I == II.I) 10754 return S < II.S; 10755 return I < II.I; 10756 }; 10757 }; 10758 10759 bool recurseForValue(Attributor &A, const IRPosition &IRP, AA::ValueScope S) { 10760 SmallMapVector<AA::ValueAndContext, int, 8> ValueScopeMap; 10761 for (auto CS : {AA::Intraprocedural, AA::Interprocedural}) { 10762 if (!(CS & S)) 10763 continue; 10764 10765 bool UsedAssumedInformation = false; 10766 SmallVector<AA::ValueAndContext> Values; 10767 if (!A.getAssumedSimplifiedValues(IRP, this, Values, CS, 10768 UsedAssumedInformation)) 10769 return false; 10770 10771 for (auto &It : Values) 10772 ValueScopeMap[It] += CS; 10773 } 10774 for (auto &It : ValueScopeMap) 10775 addValue(A, getState(), *It.first.getValue(), It.first.getCtxI(), 10776 AA::ValueScope(It.second), getAnchorScope()); 10777 10778 return true; 10779 } 10780 10781 void giveUpOnIntraprocedural(Attributor &A) { 10782 auto NewS = StateType::getBestState(getState()); 10783 for (const auto &It : getAssumedSet()) { 10784 if (It.second == AA::Intraprocedural) 10785 continue; 10786 addValue(A, NewS, *It.first.getValue(), It.first.getCtxI(), 10787 AA::Interprocedural, getAnchorScope()); 10788 } 10789 assert(!undefIsContained() && "Undef should be an explicit value!"); 10790 addValue(A, NewS, getAssociatedValue(), getCtxI(), AA::Intraprocedural, 10791 getAnchorScope()); 10792 getState() = NewS; 10793 } 10794 10795 /// See AbstractState::indicatePessimisticFixpoint(...). 10796 ChangeStatus indicatePessimisticFixpoint() override { 10797 getState() = StateType::getBestState(getState()); 10798 getState().unionAssumed({{getAssociatedValue(), getCtxI()}, AA::AnyScope}); 10799 AAPotentialValues::indicateOptimisticFixpoint(); 10800 return ChangeStatus::CHANGED; 10801 } 10802 10803 /// See AbstractAttribute::updateImpl(...). 10804 ChangeStatus updateImpl(Attributor &A) override { 10805 return indicatePessimisticFixpoint(); 10806 } 10807 10808 /// See AbstractAttribute::manifest(...). 10809 ChangeStatus manifest(Attributor &A) override { 10810 SmallVector<AA::ValueAndContext> Values; 10811 for (AA::ValueScope S : {AA::Interprocedural, AA::Intraprocedural}) { 10812 Values.clear(); 10813 if (!getAssumedSimplifiedValues(A, Values, S)) 10814 continue; 10815 Value &OldV = getAssociatedValue(); 10816 if (isa<UndefValue>(OldV)) 10817 continue; 10818 Value *NewV = getSingleValue(A, *this, getIRPosition(), Values); 10819 if (!NewV || NewV == &OldV) 10820 continue; 10821 if (getCtxI() && 10822 !AA::isValidAtPosition({*NewV, *getCtxI()}, A.getInfoCache())) 10823 continue; 10824 if (A.changeAfterManifest(getIRPosition(), *NewV)) 10825 return ChangeStatus::CHANGED; 10826 } 10827 return ChangeStatus::UNCHANGED; 10828 } 10829 10830 bool getAssumedSimplifiedValues( 10831 Attributor &A, SmallVectorImpl<AA::ValueAndContext> &Values, 10832 AA::ValueScope S, bool RecurseForSelectAndPHI = false) const override { 10833 if (!isValidState()) 10834 return false; 10835 bool UsedAssumedInformation = false; 10836 for (const auto &It : getAssumedSet()) 10837 if (It.second & S) { 10838 if (RecurseForSelectAndPHI && (isa<PHINode>(It.first.getValue()) || 10839 isa<SelectInst>(It.first.getValue()))) { 10840 if (A.getAssumedSimplifiedValues( 10841 IRPosition::inst(*cast<Instruction>(It.first.getValue())), 10842 this, Values, S, UsedAssumedInformation)) 10843 continue; 10844 } 10845 Values.push_back(It.first); 10846 } 10847 assert(!undefIsContained() && "Undef should be an explicit value!"); 10848 return true; 10849 } 10850 }; 10851 10852 struct AAPotentialValuesFloating : AAPotentialValuesImpl { 10853 AAPotentialValuesFloating(const IRPosition &IRP, Attributor &A) 10854 : AAPotentialValuesImpl(IRP, A) {} 10855 10856 /// See AbstractAttribute::updateImpl(...). 10857 ChangeStatus updateImpl(Attributor &A) override { 10858 auto AssumedBefore = getAssumed(); 10859 10860 genericValueTraversal(A, &getAssociatedValue()); 10861 10862 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED 10863 : ChangeStatus::CHANGED; 10864 } 10865 10866 /// Helper struct to remember which AAIsDead instances we actually used. 10867 struct LivenessInfo { 10868 const AAIsDead *LivenessAA = nullptr; 10869 bool AnyDead = false; 10870 }; 10871 10872 /// Check if \p Cmp is a comparison we can simplify. 10873 /// 10874 /// We handle multiple cases, one in which at least one operand is an 10875 /// (assumed) nullptr. If so, try to simplify it using AANonNull on the other 10876 /// operand. Return true if successful, in that case Worklist will be updated. 10877 bool handleCmp(Attributor &A, Value &Cmp, Value *LHS, Value *RHS, 10878 CmpInst::Predicate Pred, ItemInfo II, 10879 SmallVectorImpl<ItemInfo> &Worklist) { 10880 10881 // Simplify the operands first. 10882 bool UsedAssumedInformation = false; 10883 const auto &SimplifiedLHS = A.getAssumedSimplified( 10884 IRPosition::value(*LHS, getCallBaseContext()), *this, 10885 UsedAssumedInformation, AA::Intraprocedural); 10886 if (!SimplifiedLHS.has_value()) 10887 return true; 10888 if (!*SimplifiedLHS) 10889 return false; 10890 LHS = *SimplifiedLHS; 10891 10892 const auto &SimplifiedRHS = A.getAssumedSimplified( 10893 IRPosition::value(*RHS, getCallBaseContext()), *this, 10894 UsedAssumedInformation, AA::Intraprocedural); 10895 if (!SimplifiedRHS.has_value()) 10896 return true; 10897 if (!*SimplifiedRHS) 10898 return false; 10899 RHS = *SimplifiedRHS; 10900 10901 LLVMContext &Ctx = LHS->getContext(); 10902 // Handle the trivial case first in which we don't even need to think about 10903 // null or non-null. 10904 if (LHS == RHS && 10905 (CmpInst::isTrueWhenEqual(Pred) || CmpInst::isFalseWhenEqual(Pred))) { 10906 Constant *NewV = ConstantInt::get(Type::getInt1Ty(Ctx), 10907 CmpInst::isTrueWhenEqual(Pred)); 10908 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S, 10909 getAnchorScope()); 10910 return true; 10911 } 10912 10913 // From now on we only handle equalities (==, !=). 10914 if (!CmpInst::isEquality(Pred)) 10915 return false; 10916 10917 bool LHSIsNull = isa<ConstantPointerNull>(LHS); 10918 bool RHSIsNull = isa<ConstantPointerNull>(RHS); 10919 if (!LHSIsNull && !RHSIsNull) 10920 return false; 10921 10922 // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the 10923 // non-nullptr operand and if we assume it's non-null we can conclude the 10924 // result of the comparison. 10925 assert((LHSIsNull || RHSIsNull) && 10926 "Expected nullptr versus non-nullptr comparison at this point"); 10927 10928 // The index is the operand that we assume is not null. 10929 unsigned PtrIdx = LHSIsNull; 10930 bool IsKnownNonNull; 10931 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>( 10932 A, this, IRPosition::value(*(PtrIdx ? RHS : LHS)), DepClassTy::REQUIRED, 10933 IsKnownNonNull); 10934 if (!IsAssumedNonNull) 10935 return false; 10936 10937 // The new value depends on the predicate, true for != and false for ==. 10938 Constant *NewV = 10939 ConstantInt::get(Type::getInt1Ty(Ctx), Pred == CmpInst::ICMP_NE); 10940 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S, getAnchorScope()); 10941 return true; 10942 } 10943 10944 bool handleSelectInst(Attributor &A, SelectInst &SI, ItemInfo II, 10945 SmallVectorImpl<ItemInfo> &Worklist) { 10946 const Instruction *CtxI = II.I.getCtxI(); 10947 bool UsedAssumedInformation = false; 10948 10949 std::optional<Constant *> C = 10950 A.getAssumedConstant(*SI.getCondition(), *this, UsedAssumedInformation); 10951 bool NoValueYet = !C.has_value(); 10952 if (NoValueYet || isa_and_nonnull<UndefValue>(*C)) 10953 return true; 10954 if (auto *CI = dyn_cast_or_null<ConstantInt>(*C)) { 10955 if (CI->isZero()) 10956 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S}); 10957 else 10958 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S}); 10959 } else if (&SI == &getAssociatedValue()) { 10960 // We could not simplify the condition, assume both values. 10961 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S}); 10962 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S}); 10963 } else { 10964 std::optional<Value *> SimpleV = A.getAssumedSimplified( 10965 IRPosition::inst(SI), *this, UsedAssumedInformation, II.S); 10966 if (!SimpleV.has_value()) 10967 return true; 10968 if (*SimpleV) { 10969 addValue(A, getState(), **SimpleV, CtxI, II.S, getAnchorScope()); 10970 return true; 10971 } 10972 return false; 10973 } 10974 return true; 10975 } 10976 10977 bool handleLoadInst(Attributor &A, LoadInst &LI, ItemInfo II, 10978 SmallVectorImpl<ItemInfo> &Worklist) { 10979 SmallSetVector<Value *, 4> PotentialCopies; 10980 SmallSetVector<Instruction *, 4> PotentialValueOrigins; 10981 bool UsedAssumedInformation = false; 10982 if (!AA::getPotentiallyLoadedValues(A, LI, PotentialCopies, 10983 PotentialValueOrigins, *this, 10984 UsedAssumedInformation, 10985 /* OnlyExact */ true)) { 10986 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Failed to get potentially " 10987 "loaded values for load instruction " 10988 << LI << "\n"); 10989 return false; 10990 } 10991 10992 // Do not simplify loads that are only used in llvm.assume if we cannot also 10993 // remove all stores that may feed into the load. The reason is that the 10994 // assume is probably worth something as long as the stores are around. 10995 InformationCache &InfoCache = A.getInfoCache(); 10996 if (InfoCache.isOnlyUsedByAssume(LI)) { 10997 if (!llvm::all_of(PotentialValueOrigins, [&](Instruction *I) { 10998 if (!I || isa<AssumeInst>(I)) 10999 return true; 11000 if (auto *SI = dyn_cast<StoreInst>(I)) 11001 return A.isAssumedDead(SI->getOperandUse(0), this, 11002 /* LivenessAA */ nullptr, 11003 UsedAssumedInformation, 11004 /* CheckBBLivenessOnly */ false); 11005 return A.isAssumedDead(*I, this, /* LivenessAA */ nullptr, 11006 UsedAssumedInformation, 11007 /* CheckBBLivenessOnly */ false); 11008 })) { 11009 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Load is onl used by assumes " 11010 "and we cannot delete all the stores: " 11011 << LI << "\n"); 11012 return false; 11013 } 11014 } 11015 11016 // Values have to be dynamically unique or we loose the fact that a 11017 // single llvm::Value might represent two runtime values (e.g., 11018 // stack locations in different recursive calls). 11019 const Instruction *CtxI = II.I.getCtxI(); 11020 bool ScopeIsLocal = (II.S & AA::Intraprocedural); 11021 bool AllLocal = ScopeIsLocal; 11022 bool DynamicallyUnique = llvm::all_of(PotentialCopies, [&](Value *PC) { 11023 AllLocal &= AA::isValidInScope(*PC, getAnchorScope()); 11024 return AA::isDynamicallyUnique(A, *this, *PC); 11025 }); 11026 if (!DynamicallyUnique) { 11027 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Not all potentially loaded " 11028 "values are dynamically unique: " 11029 << LI << "\n"); 11030 return false; 11031 } 11032 11033 for (auto *PotentialCopy : PotentialCopies) { 11034 if (AllLocal) { 11035 Worklist.push_back({{*PotentialCopy, CtxI}, II.S}); 11036 } else { 11037 Worklist.push_back({{*PotentialCopy, CtxI}, AA::Interprocedural}); 11038 } 11039 } 11040 if (!AllLocal && ScopeIsLocal) 11041 addValue(A, getState(), LI, CtxI, AA::Intraprocedural, getAnchorScope()); 11042 return true; 11043 } 11044 11045 bool handlePHINode( 11046 Attributor &A, PHINode &PHI, ItemInfo II, 11047 SmallVectorImpl<ItemInfo> &Worklist, 11048 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) { 11049 auto GetLivenessInfo = [&](const Function &F) -> LivenessInfo & { 11050 LivenessInfo &LI = LivenessAAs[&F]; 11051 if (!LI.LivenessAA) 11052 LI.LivenessAA = A.getAAFor<AAIsDead>(*this, IRPosition::function(F), 11053 DepClassTy::NONE); 11054 return LI; 11055 }; 11056 11057 if (&PHI == &getAssociatedValue()) { 11058 LivenessInfo &LI = GetLivenessInfo(*PHI.getFunction()); 11059 const auto *CI = 11060 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>( 11061 *PHI.getFunction()); 11062 11063 Cycle *C = nullptr; 11064 bool CyclePHI = mayBeInCycle(CI, &PHI, /* HeaderOnly */ true, &C); 11065 for (unsigned u = 0, e = PHI.getNumIncomingValues(); u < e; u++) { 11066 BasicBlock *IncomingBB = PHI.getIncomingBlock(u); 11067 if (LI.LivenessAA && 11068 LI.LivenessAA->isEdgeDead(IncomingBB, PHI.getParent())) { 11069 LI.AnyDead = true; 11070 continue; 11071 } 11072 Value *V = PHI.getIncomingValue(u); 11073 if (V == &PHI) 11074 continue; 11075 11076 // If the incoming value is not the PHI but an instruction in the same 11077 // cycle we might have multiple versions of it flying around. 11078 if (CyclePHI && isa<Instruction>(V) && 11079 (!C || C->contains(cast<Instruction>(V)->getParent()))) 11080 return false; 11081 11082 Worklist.push_back({{*V, IncomingBB->getTerminator()}, II.S}); 11083 } 11084 return true; 11085 } 11086 11087 bool UsedAssumedInformation = false; 11088 std::optional<Value *> SimpleV = A.getAssumedSimplified( 11089 IRPosition::inst(PHI), *this, UsedAssumedInformation, II.S); 11090 if (!SimpleV.has_value()) 11091 return true; 11092 if (!(*SimpleV)) 11093 return false; 11094 addValue(A, getState(), **SimpleV, &PHI, II.S, getAnchorScope()); 11095 return true; 11096 } 11097 11098 /// Use the generic, non-optimistic InstSimplfy functionality if we managed to 11099 /// simplify any operand of the instruction \p I. Return true if successful, 11100 /// in that case Worklist will be updated. 11101 bool handleGenericInst(Attributor &A, Instruction &I, ItemInfo II, 11102 SmallVectorImpl<ItemInfo> &Worklist) { 11103 bool SomeSimplified = false; 11104 bool UsedAssumedInformation = false; 11105 11106 SmallVector<Value *, 8> NewOps(I.getNumOperands()); 11107 int Idx = 0; 11108 for (Value *Op : I.operands()) { 11109 const auto &SimplifiedOp = A.getAssumedSimplified( 11110 IRPosition::value(*Op, getCallBaseContext()), *this, 11111 UsedAssumedInformation, AA::Intraprocedural); 11112 // If we are not sure about any operand we are not sure about the entire 11113 // instruction, we'll wait. 11114 if (!SimplifiedOp.has_value()) 11115 return true; 11116 11117 if (*SimplifiedOp) 11118 NewOps[Idx] = *SimplifiedOp; 11119 else 11120 NewOps[Idx] = Op; 11121 11122 SomeSimplified |= (NewOps[Idx] != Op); 11123 ++Idx; 11124 } 11125 11126 // We won't bother with the InstSimplify interface if we didn't simplify any 11127 // operand ourselves. 11128 if (!SomeSimplified) 11129 return false; 11130 11131 InformationCache &InfoCache = A.getInfoCache(); 11132 Function *F = I.getFunction(); 11133 const auto *DT = 11134 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F); 11135 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F); 11136 auto *AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F); 11137 11138 const DataLayout &DL = I.getModule()->getDataLayout(); 11139 SimplifyQuery Q(DL, TLI, DT, AC, &I); 11140 Value *NewV = simplifyInstructionWithOperands(&I, NewOps, Q); 11141 if (!NewV || NewV == &I) 11142 return false; 11143 11144 LLVM_DEBUG(dbgs() << "Generic inst " << I << " assumed simplified to " 11145 << *NewV << "\n"); 11146 Worklist.push_back({{*NewV, II.I.getCtxI()}, II.S}); 11147 return true; 11148 } 11149 11150 bool simplifyInstruction( 11151 Attributor &A, Instruction &I, ItemInfo II, 11152 SmallVectorImpl<ItemInfo> &Worklist, 11153 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) { 11154 if (auto *CI = dyn_cast<CmpInst>(&I)) 11155 if (handleCmp(A, *CI, CI->getOperand(0), CI->getOperand(1), 11156 CI->getPredicate(), II, Worklist)) 11157 return true; 11158 11159 switch (I.getOpcode()) { 11160 case Instruction::Select: 11161 return handleSelectInst(A, cast<SelectInst>(I), II, Worklist); 11162 case Instruction::PHI: 11163 return handlePHINode(A, cast<PHINode>(I), II, Worklist, LivenessAAs); 11164 case Instruction::Load: 11165 return handleLoadInst(A, cast<LoadInst>(I), II, Worklist); 11166 default: 11167 return handleGenericInst(A, I, II, Worklist); 11168 }; 11169 return false; 11170 } 11171 11172 void genericValueTraversal(Attributor &A, Value *InitialV) { 11173 SmallMapVector<const Function *, LivenessInfo, 4> LivenessAAs; 11174 11175 SmallSet<ItemInfo, 16> Visited; 11176 SmallVector<ItemInfo, 16> Worklist; 11177 Worklist.push_back({{*InitialV, getCtxI()}, AA::AnyScope}); 11178 11179 int Iteration = 0; 11180 do { 11181 ItemInfo II = Worklist.pop_back_val(); 11182 Value *V = II.I.getValue(); 11183 assert(V); 11184 const Instruction *CtxI = II.I.getCtxI(); 11185 AA::ValueScope S = II.S; 11186 11187 // Check if we should process the current value. To prevent endless 11188 // recursion keep a record of the values we followed! 11189 if (!Visited.insert(II).second) 11190 continue; 11191 11192 // Make sure we limit the compile time for complex expressions. 11193 if (Iteration++ >= MaxPotentialValuesIterations) { 11194 LLVM_DEBUG(dbgs() << "Generic value traversal reached iteration limit: " 11195 << Iteration << "!\n"); 11196 addValue(A, getState(), *V, CtxI, S, getAnchorScope()); 11197 continue; 11198 } 11199 11200 // Explicitly look through calls with a "returned" attribute if we do 11201 // not have a pointer as stripPointerCasts only works on them. 11202 Value *NewV = nullptr; 11203 if (V->getType()->isPointerTy()) { 11204 NewV = AA::getWithType(*V->stripPointerCasts(), *V->getType()); 11205 } else { 11206 if (auto *CB = dyn_cast<CallBase>(V)) 11207 if (auto *Callee = 11208 dyn_cast_if_present<Function>(CB->getCalledOperand())) { 11209 for (Argument &Arg : Callee->args()) 11210 if (Arg.hasReturnedAttr()) { 11211 NewV = CB->getArgOperand(Arg.getArgNo()); 11212 break; 11213 } 11214 } 11215 } 11216 if (NewV && NewV != V) { 11217 Worklist.push_back({{*NewV, CtxI}, S}); 11218 continue; 11219 } 11220 11221 if (auto *CE = dyn_cast<ConstantExpr>(V)) { 11222 if (CE->getOpcode() == Instruction::ICmp) 11223 if (handleCmp(A, *CE, CE->getOperand(0), CE->getOperand(1), 11224 CmpInst::Predicate(CE->getPredicate()), II, Worklist)) 11225 continue; 11226 } 11227 11228 if (auto *I = dyn_cast<Instruction>(V)) { 11229 if (simplifyInstruction(A, *I, II, Worklist, LivenessAAs)) 11230 continue; 11231 } 11232 11233 if (V != InitialV || isa<Argument>(V)) 11234 if (recurseForValue(A, IRPosition::value(*V), II.S)) 11235 continue; 11236 11237 // If we haven't stripped anything we give up. 11238 if (V == InitialV && CtxI == getCtxI()) { 11239 indicatePessimisticFixpoint(); 11240 return; 11241 } 11242 11243 addValue(A, getState(), *V, CtxI, S, getAnchorScope()); 11244 } while (!Worklist.empty()); 11245 11246 // If we actually used liveness information so we have to record a 11247 // dependence. 11248 for (auto &It : LivenessAAs) 11249 if (It.second.AnyDead) 11250 A.recordDependence(*It.second.LivenessAA, *this, DepClassTy::OPTIONAL); 11251 } 11252 11253 /// See AbstractAttribute::trackStatistics() 11254 void trackStatistics() const override { 11255 STATS_DECLTRACK_FLOATING_ATTR(potential_values) 11256 } 11257 }; 11258 11259 struct AAPotentialValuesArgument final : AAPotentialValuesImpl { 11260 using Base = AAPotentialValuesImpl; 11261 AAPotentialValuesArgument(const IRPosition &IRP, Attributor &A) 11262 : Base(IRP, A) {} 11263 11264 /// See AbstractAttribute::initialize(..). 11265 void initialize(Attributor &A) override { 11266 auto &Arg = cast<Argument>(getAssociatedValue()); 11267 if (Arg.hasPointeeInMemoryValueAttr()) 11268 indicatePessimisticFixpoint(); 11269 } 11270 11271 /// See AbstractAttribute::updateImpl(...). 11272 ChangeStatus updateImpl(Attributor &A) override { 11273 auto AssumedBefore = getAssumed(); 11274 11275 unsigned CSArgNo = getCallSiteArgNo(); 11276 11277 bool UsedAssumedInformation = false; 11278 SmallVector<AA::ValueAndContext> Values; 11279 auto CallSitePred = [&](AbstractCallSite ACS) { 11280 const auto CSArgIRP = IRPosition::callsite_argument(ACS, CSArgNo); 11281 if (CSArgIRP.getPositionKind() == IRP_INVALID) 11282 return false; 11283 11284 if (!A.getAssumedSimplifiedValues(CSArgIRP, this, Values, 11285 AA::Interprocedural, 11286 UsedAssumedInformation)) 11287 return false; 11288 11289 return isValidState(); 11290 }; 11291 11292 if (!A.checkForAllCallSites(CallSitePred, *this, 11293 /* RequireAllCallSites */ true, 11294 UsedAssumedInformation)) 11295 return indicatePessimisticFixpoint(); 11296 11297 Function *Fn = getAssociatedFunction(); 11298 bool AnyNonLocal = false; 11299 for (auto &It : Values) { 11300 if (isa<Constant>(It.getValue())) { 11301 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope, 11302 getAnchorScope()); 11303 continue; 11304 } 11305 if (!AA::isDynamicallyUnique(A, *this, *It.getValue())) 11306 return indicatePessimisticFixpoint(); 11307 11308 if (auto *Arg = dyn_cast<Argument>(It.getValue())) 11309 if (Arg->getParent() == Fn) { 11310 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope, 11311 getAnchorScope()); 11312 continue; 11313 } 11314 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::Interprocedural, 11315 getAnchorScope()); 11316 AnyNonLocal = true; 11317 } 11318 assert(!undefIsContained() && "Undef should be an explicit value!"); 11319 if (AnyNonLocal) 11320 giveUpOnIntraprocedural(A); 11321 11322 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED 11323 : ChangeStatus::CHANGED; 11324 } 11325 11326 /// See AbstractAttribute::trackStatistics() 11327 void trackStatistics() const override { 11328 STATS_DECLTRACK_ARG_ATTR(potential_values) 11329 } 11330 }; 11331 11332 struct AAPotentialValuesReturned : public AAPotentialValuesFloating { 11333 using Base = AAPotentialValuesFloating; 11334 AAPotentialValuesReturned(const IRPosition &IRP, Attributor &A) 11335 : Base(IRP, A) {} 11336 11337 /// See AbstractAttribute::initialize(..). 11338 void initialize(Attributor &A) override { 11339 Function *F = getAssociatedFunction(); 11340 if (!F || F->isDeclaration() || F->getReturnType()->isVoidTy()) { 11341 indicatePessimisticFixpoint(); 11342 return; 11343 } 11344 11345 for (Argument &Arg : F->args()) 11346 if (Arg.hasReturnedAttr()) { 11347 addValue(A, getState(), Arg, nullptr, AA::AnyScope, F); 11348 ReturnedArg = &Arg; 11349 break; 11350 } 11351 if (!A.isFunctionIPOAmendable(*F) || 11352 A.hasSimplificationCallback(getIRPosition())) { 11353 if (!ReturnedArg) 11354 indicatePessimisticFixpoint(); 11355 else 11356 indicateOptimisticFixpoint(); 11357 } 11358 } 11359 11360 /// See AbstractAttribute::updateImpl(...). 11361 ChangeStatus updateImpl(Attributor &A) override { 11362 auto AssumedBefore = getAssumed(); 11363 bool UsedAssumedInformation = false; 11364 11365 SmallVector<AA::ValueAndContext> Values; 11366 Function *AnchorScope = getAnchorScope(); 11367 auto HandleReturnedValue = [&](Value &V, Instruction *CtxI, 11368 bool AddValues) { 11369 for (AA::ValueScope S : {AA::Interprocedural, AA::Intraprocedural}) { 11370 Values.clear(); 11371 if (!A.getAssumedSimplifiedValues(IRPosition::value(V), this, Values, S, 11372 UsedAssumedInformation, 11373 /* RecurseForSelectAndPHI */ true)) 11374 return false; 11375 if (!AddValues) 11376 continue; 11377 for (const AA::ValueAndContext &VAC : Values) 11378 addValue(A, getState(), *VAC.getValue(), 11379 VAC.getCtxI() ? VAC.getCtxI() : CtxI, S, AnchorScope); 11380 } 11381 return true; 11382 }; 11383 11384 if (ReturnedArg) { 11385 HandleReturnedValue(*ReturnedArg, nullptr, true); 11386 } else { 11387 auto RetInstPred = [&](Instruction &RetI) { 11388 bool AddValues = true; 11389 if (isa<PHINode>(RetI.getOperand(0)) || 11390 isa<SelectInst>(RetI.getOperand(0))) { 11391 addValue(A, getState(), *RetI.getOperand(0), &RetI, AA::AnyScope, 11392 AnchorScope); 11393 AddValues = false; 11394 } 11395 return HandleReturnedValue(*RetI.getOperand(0), &RetI, AddValues); 11396 }; 11397 11398 if (!A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret}, 11399 UsedAssumedInformation, 11400 /* CheckBBLivenessOnly */ true)) 11401 return indicatePessimisticFixpoint(); 11402 } 11403 11404 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED 11405 : ChangeStatus::CHANGED; 11406 } 11407 11408 void addValue(Attributor &A, StateType &State, Value &V, 11409 const Instruction *CtxI, AA::ValueScope S, 11410 Function *AnchorScope) const override { 11411 Function *F = getAssociatedFunction(); 11412 if (auto *CB = dyn_cast<CallBase>(&V)) 11413 if (CB->getCalledOperand() == F) 11414 return; 11415 Base::addValue(A, State, V, CtxI, S, AnchorScope); 11416 } 11417 11418 ChangeStatus manifest(Attributor &A) override { 11419 if (ReturnedArg) 11420 return ChangeStatus::UNCHANGED; 11421 SmallVector<AA::ValueAndContext> Values; 11422 if (!getAssumedSimplifiedValues(A, Values, AA::ValueScope::Intraprocedural, 11423 /* RecurseForSelectAndPHI */ true)) 11424 return ChangeStatus::UNCHANGED; 11425 Value *NewVal = getSingleValue(A, *this, getIRPosition(), Values); 11426 if (!NewVal) 11427 return ChangeStatus::UNCHANGED; 11428 11429 ChangeStatus Changed = ChangeStatus::UNCHANGED; 11430 if (auto *Arg = dyn_cast<Argument>(NewVal)) { 11431 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn, 11432 "Number of function with unique return"); 11433 Changed |= A.manifestAttrs( 11434 IRPosition::argument(*Arg), 11435 {Attribute::get(Arg->getContext(), Attribute::Returned)}); 11436 STATS_DECLTRACK_ARG_ATTR(returned); 11437 } 11438 11439 auto RetInstPred = [&](Instruction &RetI) { 11440 Value *RetOp = RetI.getOperand(0); 11441 if (isa<UndefValue>(RetOp) || RetOp == NewVal) 11442 return true; 11443 if (AA::isValidAtPosition({*NewVal, RetI}, A.getInfoCache())) 11444 if (A.changeUseAfterManifest(RetI.getOperandUse(0), *NewVal)) 11445 Changed = ChangeStatus::CHANGED; 11446 return true; 11447 }; 11448 bool UsedAssumedInformation = false; 11449 (void)A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret}, 11450 UsedAssumedInformation, 11451 /* CheckBBLivenessOnly */ true); 11452 return Changed; 11453 } 11454 11455 ChangeStatus indicatePessimisticFixpoint() override { 11456 return AAPotentialValues::indicatePessimisticFixpoint(); 11457 } 11458 11459 /// See AbstractAttribute::trackStatistics() 11460 void trackStatistics() const override{ 11461 STATS_DECLTRACK_FNRET_ATTR(potential_values)} 11462 11463 /// The argumented with an existing `returned` attribute. 11464 Argument *ReturnedArg = nullptr; 11465 }; 11466 11467 struct AAPotentialValuesFunction : AAPotentialValuesImpl { 11468 AAPotentialValuesFunction(const IRPosition &IRP, Attributor &A) 11469 : AAPotentialValuesImpl(IRP, A) {} 11470 11471 /// See AbstractAttribute::updateImpl(...). 11472 ChangeStatus updateImpl(Attributor &A) override { 11473 llvm_unreachable("AAPotentialValues(Function|CallSite)::updateImpl will " 11474 "not be called"); 11475 } 11476 11477 /// See AbstractAttribute::trackStatistics() 11478 void trackStatistics() const override { 11479 STATS_DECLTRACK_FN_ATTR(potential_values) 11480 } 11481 }; 11482 11483 struct AAPotentialValuesCallSite : AAPotentialValuesFunction { 11484 AAPotentialValuesCallSite(const IRPosition &IRP, Attributor &A) 11485 : AAPotentialValuesFunction(IRP, A) {} 11486 11487 /// See AbstractAttribute::trackStatistics() 11488 void trackStatistics() const override { 11489 STATS_DECLTRACK_CS_ATTR(potential_values) 11490 } 11491 }; 11492 11493 struct AAPotentialValuesCallSiteReturned : AAPotentialValuesImpl { 11494 AAPotentialValuesCallSiteReturned(const IRPosition &IRP, Attributor &A) 11495 : AAPotentialValuesImpl(IRP, A) {} 11496 11497 /// See AbstractAttribute::updateImpl(...). 11498 ChangeStatus updateImpl(Attributor &A) override { 11499 auto AssumedBefore = getAssumed(); 11500 11501 Function *Callee = getAssociatedFunction(); 11502 if (!Callee) 11503 return indicatePessimisticFixpoint(); 11504 11505 bool UsedAssumedInformation = false; 11506 auto *CB = cast<CallBase>(getCtxI()); 11507 if (CB->isMustTailCall() && 11508 !A.isAssumedDead(IRPosition::inst(*CB), this, nullptr, 11509 UsedAssumedInformation)) 11510 return indicatePessimisticFixpoint(); 11511 11512 SmallVector<AA::ValueAndContext> Values; 11513 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this, 11514 Values, AA::Intraprocedural, 11515 UsedAssumedInformation)) 11516 return indicatePessimisticFixpoint(); 11517 11518 Function *Caller = CB->getCaller(); 11519 11520 bool AnyNonLocal = false; 11521 for (auto &It : Values) { 11522 Value *V = It.getValue(); 11523 std::optional<Value *> CallerV = A.translateArgumentToCallSiteContent( 11524 V, *CB, *this, UsedAssumedInformation); 11525 if (!CallerV.has_value()) { 11526 // Nothing to do as long as no value was determined. 11527 continue; 11528 } 11529 V = *CallerV ? *CallerV : V; 11530 if (AA::isDynamicallyUnique(A, *this, *V) && 11531 AA::isValidInScope(*V, Caller)) { 11532 if (*CallerV) { 11533 SmallVector<AA::ValueAndContext> ArgValues; 11534 IRPosition IRP = IRPosition::value(*V); 11535 if (auto *Arg = dyn_cast<Argument>(V)) 11536 if (Arg->getParent() == CB->getCalledOperand()) 11537 IRP = IRPosition::callsite_argument(*CB, Arg->getArgNo()); 11538 if (recurseForValue(A, IRP, AA::AnyScope)) 11539 continue; 11540 } 11541 addValue(A, getState(), *V, CB, AA::AnyScope, getAnchorScope()); 11542 } else { 11543 AnyNonLocal = true; 11544 break; 11545 } 11546 } 11547 if (AnyNonLocal) { 11548 Values.clear(); 11549 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this, 11550 Values, AA::Interprocedural, 11551 UsedAssumedInformation)) 11552 return indicatePessimisticFixpoint(); 11553 AnyNonLocal = false; 11554 getState() = PotentialLLVMValuesState::getBestState(); 11555 for (auto &It : Values) { 11556 Value *V = It.getValue(); 11557 if (!AA::isDynamicallyUnique(A, *this, *V)) 11558 return indicatePessimisticFixpoint(); 11559 if (AA::isValidInScope(*V, Caller)) { 11560 addValue(A, getState(), *V, CB, AA::AnyScope, getAnchorScope()); 11561 } else { 11562 AnyNonLocal = true; 11563 addValue(A, getState(), *V, CB, AA::Interprocedural, 11564 getAnchorScope()); 11565 } 11566 } 11567 if (AnyNonLocal) 11568 giveUpOnIntraprocedural(A); 11569 } 11570 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED 11571 : ChangeStatus::CHANGED; 11572 } 11573 11574 ChangeStatus indicatePessimisticFixpoint() override { 11575 return AAPotentialValues::indicatePessimisticFixpoint(); 11576 } 11577 11578 /// See AbstractAttribute::trackStatistics() 11579 void trackStatistics() const override { 11580 STATS_DECLTRACK_CSRET_ATTR(potential_values) 11581 } 11582 }; 11583 11584 struct AAPotentialValuesCallSiteArgument : AAPotentialValuesFloating { 11585 AAPotentialValuesCallSiteArgument(const IRPosition &IRP, Attributor &A) 11586 : AAPotentialValuesFloating(IRP, A) {} 11587 11588 /// See AbstractAttribute::trackStatistics() 11589 void trackStatistics() const override { 11590 STATS_DECLTRACK_CSARG_ATTR(potential_values) 11591 } 11592 }; 11593 } // namespace 11594 11595 /// ---------------------- Assumption Propagation ------------------------------ 11596 namespace { 11597 struct AAAssumptionInfoImpl : public AAAssumptionInfo { 11598 AAAssumptionInfoImpl(const IRPosition &IRP, Attributor &A, 11599 const DenseSet<StringRef> &Known) 11600 : AAAssumptionInfo(IRP, A, Known) {} 11601 11602 /// See AbstractAttribute::manifest(...). 11603 ChangeStatus manifest(Attributor &A) override { 11604 // Don't manifest a universal set if it somehow made it here. 11605 if (getKnown().isUniversal()) 11606 return ChangeStatus::UNCHANGED; 11607 11608 const IRPosition &IRP = getIRPosition(); 11609 return A.manifestAttrs( 11610 IRP, 11611 Attribute::get(IRP.getAnchorValue().getContext(), AssumptionAttrKey, 11612 llvm::join(getAssumed().getSet(), ",")), 11613 /* ForceReplace */ true); 11614 } 11615 11616 bool hasAssumption(const StringRef Assumption) const override { 11617 return isValidState() && setContains(Assumption); 11618 } 11619 11620 /// See AbstractAttribute::getAsStr() 11621 const std::string getAsStr(Attributor *A) const override { 11622 const SetContents &Known = getKnown(); 11623 const SetContents &Assumed = getAssumed(); 11624 11625 const std::string KnownStr = 11626 llvm::join(Known.getSet().begin(), Known.getSet().end(), ","); 11627 const std::string AssumedStr = 11628 (Assumed.isUniversal()) 11629 ? "Universal" 11630 : llvm::join(Assumed.getSet().begin(), Assumed.getSet().end(), ","); 11631 11632 return "Known [" + KnownStr + "]," + " Assumed [" + AssumedStr + "]"; 11633 } 11634 }; 11635 11636 /// Propagates assumption information from parent functions to all of their 11637 /// successors. An assumption can be propagated if the containing function 11638 /// dominates the called function. 11639 /// 11640 /// We start with a "known" set of assumptions already valid for the associated 11641 /// function and an "assumed" set that initially contains all possible 11642 /// assumptions. The assumed set is inter-procedurally updated by narrowing its 11643 /// contents as concrete values are known. The concrete values are seeded by the 11644 /// first nodes that are either entries into the call graph, or contains no 11645 /// assumptions. Each node is updated as the intersection of the assumed state 11646 /// with all of its predecessors. 11647 struct AAAssumptionInfoFunction final : AAAssumptionInfoImpl { 11648 AAAssumptionInfoFunction(const IRPosition &IRP, Attributor &A) 11649 : AAAssumptionInfoImpl(IRP, A, 11650 getAssumptions(*IRP.getAssociatedFunction())) {} 11651 11652 /// See AbstractAttribute::updateImpl(...). 11653 ChangeStatus updateImpl(Attributor &A) override { 11654 bool Changed = false; 11655 11656 auto CallSitePred = [&](AbstractCallSite ACS) { 11657 const auto *AssumptionAA = A.getAAFor<AAAssumptionInfo>( 11658 *this, IRPosition::callsite_function(*ACS.getInstruction()), 11659 DepClassTy::REQUIRED); 11660 if (!AssumptionAA) 11661 return false; 11662 // Get the set of assumptions shared by all of this function's callers. 11663 Changed |= getIntersection(AssumptionAA->getAssumed()); 11664 return !getAssumed().empty() || !getKnown().empty(); 11665 }; 11666 11667 bool UsedAssumedInformation = false; 11668 // Get the intersection of all assumptions held by this node's predecessors. 11669 // If we don't know all the call sites then this is either an entry into the 11670 // call graph or an empty node. This node is known to only contain its own 11671 // assumptions and can be propagated to its successors. 11672 if (!A.checkForAllCallSites(CallSitePred, *this, true, 11673 UsedAssumedInformation)) 11674 return indicatePessimisticFixpoint(); 11675 11676 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 11677 } 11678 11679 void trackStatistics() const override {} 11680 }; 11681 11682 /// Assumption Info defined for call sites. 11683 struct AAAssumptionInfoCallSite final : AAAssumptionInfoImpl { 11684 11685 AAAssumptionInfoCallSite(const IRPosition &IRP, Attributor &A) 11686 : AAAssumptionInfoImpl(IRP, A, getInitialAssumptions(IRP)) {} 11687 11688 /// See AbstractAttribute::initialize(...). 11689 void initialize(Attributor &A) override { 11690 const IRPosition &FnPos = IRPosition::function(*getAnchorScope()); 11691 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED); 11692 } 11693 11694 /// See AbstractAttribute::updateImpl(...). 11695 ChangeStatus updateImpl(Attributor &A) override { 11696 const IRPosition &FnPos = IRPosition::function(*getAnchorScope()); 11697 auto *AssumptionAA = 11698 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED); 11699 if (!AssumptionAA) 11700 return indicatePessimisticFixpoint(); 11701 bool Changed = getIntersection(AssumptionAA->getAssumed()); 11702 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 11703 } 11704 11705 /// See AbstractAttribute::trackStatistics() 11706 void trackStatistics() const override {} 11707 11708 private: 11709 /// Helper to initialized the known set as all the assumptions this call and 11710 /// the callee contain. 11711 DenseSet<StringRef> getInitialAssumptions(const IRPosition &IRP) { 11712 const CallBase &CB = cast<CallBase>(IRP.getAssociatedValue()); 11713 auto Assumptions = getAssumptions(CB); 11714 if (const Function *F = CB.getCaller()) 11715 set_union(Assumptions, getAssumptions(*F)); 11716 if (Function *F = IRP.getAssociatedFunction()) 11717 set_union(Assumptions, getAssumptions(*F)); 11718 return Assumptions; 11719 } 11720 }; 11721 } // namespace 11722 11723 AACallGraphNode *AACallEdgeIterator::operator*() const { 11724 return static_cast<AACallGraphNode *>(const_cast<AACallEdges *>( 11725 A.getOrCreateAAFor<AACallEdges>(IRPosition::function(**I)))); 11726 } 11727 11728 void AttributorCallGraph::print() { llvm::WriteGraph(outs(), this); } 11729 11730 /// ------------------------ UnderlyingObjects --------------------------------- 11731 11732 namespace { 11733 struct AAUnderlyingObjectsImpl 11734 : StateWrapper<BooleanState, AAUnderlyingObjects> { 11735 using BaseTy = StateWrapper<BooleanState, AAUnderlyingObjects>; 11736 AAUnderlyingObjectsImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {} 11737 11738 /// See AbstractAttribute::getAsStr(). 11739 const std::string getAsStr(Attributor *A) const override { 11740 return std::string("UnderlyingObjects ") + 11741 (isValidState() 11742 ? (std::string("inter #") + 11743 std::to_string(InterAssumedUnderlyingObjects.size()) + 11744 " objs" + std::string(", intra #") + 11745 std::to_string(IntraAssumedUnderlyingObjects.size()) + 11746 " objs") 11747 : "<invalid>"); 11748 } 11749 11750 /// See AbstractAttribute::trackStatistics() 11751 void trackStatistics() const override {} 11752 11753 /// See AbstractAttribute::updateImpl(...). 11754 ChangeStatus updateImpl(Attributor &A) override { 11755 auto &Ptr = getAssociatedValue(); 11756 11757 auto DoUpdate = [&](SmallSetVector<Value *, 8> &UnderlyingObjects, 11758 AA::ValueScope Scope) { 11759 bool UsedAssumedInformation = false; 11760 SmallPtrSet<Value *, 8> SeenObjects; 11761 SmallVector<AA::ValueAndContext> Values; 11762 11763 if (!A.getAssumedSimplifiedValues(IRPosition::value(Ptr), *this, Values, 11764 Scope, UsedAssumedInformation)) 11765 return UnderlyingObjects.insert(&Ptr); 11766 11767 bool Changed = false; 11768 11769 for (unsigned I = 0; I < Values.size(); ++I) { 11770 auto &VAC = Values[I]; 11771 auto *Obj = VAC.getValue(); 11772 Value *UO = getUnderlyingObject(Obj); 11773 if (UO && UO != VAC.getValue() && SeenObjects.insert(UO).second) { 11774 const auto *OtherAA = A.getAAFor<AAUnderlyingObjects>( 11775 *this, IRPosition::value(*UO), DepClassTy::OPTIONAL); 11776 auto Pred = [&Values](Value &V) { 11777 Values.emplace_back(V, nullptr); 11778 return true; 11779 }; 11780 11781 if (!OtherAA || !OtherAA->forallUnderlyingObjects(Pred, Scope)) 11782 llvm_unreachable( 11783 "The forall call should not return false at this position"); 11784 11785 continue; 11786 } 11787 11788 if (isa<SelectInst>(Obj)) { 11789 Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope); 11790 continue; 11791 } 11792 if (auto *PHI = dyn_cast<PHINode>(Obj)) { 11793 // Explicitly look through PHIs as we do not care about dynamically 11794 // uniqueness. 11795 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) { 11796 Changed |= handleIndirect(A, *PHI->getIncomingValue(u), 11797 UnderlyingObjects, Scope); 11798 } 11799 continue; 11800 } 11801 11802 Changed |= UnderlyingObjects.insert(Obj); 11803 } 11804 11805 return Changed; 11806 }; 11807 11808 bool Changed = false; 11809 Changed |= DoUpdate(IntraAssumedUnderlyingObjects, AA::Intraprocedural); 11810 Changed |= DoUpdate(InterAssumedUnderlyingObjects, AA::Interprocedural); 11811 11812 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 11813 } 11814 11815 bool forallUnderlyingObjects( 11816 function_ref<bool(Value &)> Pred, 11817 AA::ValueScope Scope = AA::Interprocedural) const override { 11818 if (!isValidState()) 11819 return Pred(getAssociatedValue()); 11820 11821 auto &AssumedUnderlyingObjects = Scope == AA::Intraprocedural 11822 ? IntraAssumedUnderlyingObjects 11823 : InterAssumedUnderlyingObjects; 11824 for (Value *Obj : AssumedUnderlyingObjects) 11825 if (!Pred(*Obj)) 11826 return false; 11827 11828 return true; 11829 } 11830 11831 private: 11832 /// Handle the case where the value is not the actual underlying value, such 11833 /// as a phi node or a select instruction. 11834 bool handleIndirect(Attributor &A, Value &V, 11835 SmallSetVector<Value *, 8> &UnderlyingObjects, 11836 AA::ValueScope Scope) { 11837 bool Changed = false; 11838 const auto *AA = A.getAAFor<AAUnderlyingObjects>( 11839 *this, IRPosition::value(V), DepClassTy::OPTIONAL); 11840 auto Pred = [&](Value &V) { 11841 Changed |= UnderlyingObjects.insert(&V); 11842 return true; 11843 }; 11844 if (!AA || !AA->forallUnderlyingObjects(Pred, Scope)) 11845 llvm_unreachable( 11846 "The forall call should not return false at this position"); 11847 return Changed; 11848 } 11849 11850 /// All the underlying objects collected so far via intra procedural scope. 11851 SmallSetVector<Value *, 8> IntraAssumedUnderlyingObjects; 11852 /// All the underlying objects collected so far via inter procedural scope. 11853 SmallSetVector<Value *, 8> InterAssumedUnderlyingObjects; 11854 }; 11855 11856 struct AAUnderlyingObjectsFloating final : AAUnderlyingObjectsImpl { 11857 AAUnderlyingObjectsFloating(const IRPosition &IRP, Attributor &A) 11858 : AAUnderlyingObjectsImpl(IRP, A) {} 11859 }; 11860 11861 struct AAUnderlyingObjectsArgument final : AAUnderlyingObjectsImpl { 11862 AAUnderlyingObjectsArgument(const IRPosition &IRP, Attributor &A) 11863 : AAUnderlyingObjectsImpl(IRP, A) {} 11864 }; 11865 11866 struct AAUnderlyingObjectsCallSite final : AAUnderlyingObjectsImpl { 11867 AAUnderlyingObjectsCallSite(const IRPosition &IRP, Attributor &A) 11868 : AAUnderlyingObjectsImpl(IRP, A) {} 11869 }; 11870 11871 struct AAUnderlyingObjectsCallSiteArgument final : AAUnderlyingObjectsImpl { 11872 AAUnderlyingObjectsCallSiteArgument(const IRPosition &IRP, Attributor &A) 11873 : AAUnderlyingObjectsImpl(IRP, A) {} 11874 }; 11875 11876 struct AAUnderlyingObjectsReturned final : AAUnderlyingObjectsImpl { 11877 AAUnderlyingObjectsReturned(const IRPosition &IRP, Attributor &A) 11878 : AAUnderlyingObjectsImpl(IRP, A) {} 11879 }; 11880 11881 struct AAUnderlyingObjectsCallSiteReturned final : AAUnderlyingObjectsImpl { 11882 AAUnderlyingObjectsCallSiteReturned(const IRPosition &IRP, Attributor &A) 11883 : AAUnderlyingObjectsImpl(IRP, A) {} 11884 }; 11885 11886 struct AAUnderlyingObjectsFunction final : AAUnderlyingObjectsImpl { 11887 AAUnderlyingObjectsFunction(const IRPosition &IRP, Attributor &A) 11888 : AAUnderlyingObjectsImpl(IRP, A) {} 11889 }; 11890 } // namespace 11891 11892 /// ------------------------ Address Space ------------------------------------ 11893 namespace { 11894 struct AAAddressSpaceImpl : public AAAddressSpace { 11895 AAAddressSpaceImpl(const IRPosition &IRP, Attributor &A) 11896 : AAAddressSpace(IRP, A) {} 11897 11898 int32_t getAddressSpace() const override { 11899 assert(isValidState() && "the AA is invalid"); 11900 return AssumedAddressSpace; 11901 } 11902 11903 /// See AbstractAttribute::initialize(...). 11904 void initialize(Attributor &A) override { 11905 assert(getAssociatedType()->isPtrOrPtrVectorTy() && 11906 "Associated value is not a pointer"); 11907 } 11908 11909 ChangeStatus updateImpl(Attributor &A) override { 11910 int32_t OldAddressSpace = AssumedAddressSpace; 11911 auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this, 11912 DepClassTy::REQUIRED); 11913 auto Pred = [&](Value &Obj) { 11914 if (isa<UndefValue>(&Obj)) 11915 return true; 11916 return takeAddressSpace(Obj.getType()->getPointerAddressSpace()); 11917 }; 11918 11919 if (!AUO->forallUnderlyingObjects(Pred)) 11920 return indicatePessimisticFixpoint(); 11921 11922 return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED 11923 : ChangeStatus::CHANGED; 11924 } 11925 11926 /// See AbstractAttribute::manifest(...). 11927 ChangeStatus manifest(Attributor &A) override { 11928 Value *AssociatedValue = &getAssociatedValue(); 11929 Value *OriginalValue = peelAddrspacecast(AssociatedValue); 11930 if (getAddressSpace() == NoAddressSpace || 11931 static_cast<uint32_t>(getAddressSpace()) == 11932 getAssociatedType()->getPointerAddressSpace()) 11933 return ChangeStatus::UNCHANGED; 11934 11935 Type *NewPtrTy = PointerType::get(getAssociatedType()->getContext(), 11936 static_cast<uint32_t>(getAddressSpace())); 11937 bool UseOriginalValue = 11938 OriginalValue->getType()->getPointerAddressSpace() == 11939 static_cast<uint32_t>(getAddressSpace()); 11940 11941 bool Changed = false; 11942 11943 auto MakeChange = [&](Instruction *I, Use &U) { 11944 Changed = true; 11945 if (UseOriginalValue) { 11946 A.changeUseAfterManifest(U, *OriginalValue); 11947 return; 11948 } 11949 Instruction *CastInst = new AddrSpaceCastInst(OriginalValue, NewPtrTy); 11950 CastInst->insertBefore(cast<Instruction>(I)); 11951 A.changeUseAfterManifest(U, *CastInst); 11952 }; 11953 11954 auto Pred = [&](const Use &U, bool &) { 11955 if (U.get() != AssociatedValue) 11956 return true; 11957 auto *Inst = dyn_cast<Instruction>(U.getUser()); 11958 if (!Inst) 11959 return true; 11960 // This is a WA to make sure we only change uses from the corresponding 11961 // CGSCC if the AA is run on CGSCC instead of the entire module. 11962 if (!A.isRunOn(Inst->getFunction())) 11963 return true; 11964 if (isa<LoadInst>(Inst) || isa<StoreInst>(Inst)) 11965 MakeChange(Inst, const_cast<Use &>(U)); 11966 return true; 11967 }; 11968 11969 // It doesn't matter if we can't check all uses as we can simply 11970 // conservatively ignore those that can not be visited. 11971 (void)A.checkForAllUses(Pred, *this, getAssociatedValue(), 11972 /* CheckBBLivenessOnly */ true); 11973 11974 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 11975 } 11976 11977 /// See AbstractAttribute::getAsStr(). 11978 const std::string getAsStr(Attributor *A) const override { 11979 if (!isValidState()) 11980 return "addrspace(<invalid>)"; 11981 return "addrspace(" + 11982 (AssumedAddressSpace == NoAddressSpace 11983 ? "none" 11984 : std::to_string(AssumedAddressSpace)) + 11985 ")"; 11986 } 11987 11988 private: 11989 int32_t AssumedAddressSpace = NoAddressSpace; 11990 11991 bool takeAddressSpace(int32_t AS) { 11992 if (AssumedAddressSpace == NoAddressSpace) { 11993 AssumedAddressSpace = AS; 11994 return true; 11995 } 11996 return AssumedAddressSpace == AS; 11997 } 11998 11999 static Value *peelAddrspacecast(Value *V) { 12000 if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) 12001 return peelAddrspacecast(I->getPointerOperand()); 12002 if (auto *C = dyn_cast<ConstantExpr>(V)) 12003 if (C->getOpcode() == Instruction::AddrSpaceCast) 12004 return peelAddrspacecast(C->getOperand(0)); 12005 return V; 12006 } 12007 }; 12008 12009 struct AAAddressSpaceFloating final : AAAddressSpaceImpl { 12010 AAAddressSpaceFloating(const IRPosition &IRP, Attributor &A) 12011 : AAAddressSpaceImpl(IRP, A) {} 12012 12013 void trackStatistics() const override { 12014 STATS_DECLTRACK_FLOATING_ATTR(addrspace); 12015 } 12016 }; 12017 12018 struct AAAddressSpaceReturned final : AAAddressSpaceImpl { 12019 AAAddressSpaceReturned(const IRPosition &IRP, Attributor &A) 12020 : AAAddressSpaceImpl(IRP, A) {} 12021 12022 /// See AbstractAttribute::initialize(...). 12023 void initialize(Attributor &A) override { 12024 // TODO: we don't rewrite function argument for now because it will need to 12025 // rewrite the function signature and all call sites. 12026 (void)indicatePessimisticFixpoint(); 12027 } 12028 12029 void trackStatistics() const override { 12030 STATS_DECLTRACK_FNRET_ATTR(addrspace); 12031 } 12032 }; 12033 12034 struct AAAddressSpaceCallSiteReturned final : AAAddressSpaceImpl { 12035 AAAddressSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A) 12036 : AAAddressSpaceImpl(IRP, A) {} 12037 12038 void trackStatistics() const override { 12039 STATS_DECLTRACK_CSRET_ATTR(addrspace); 12040 } 12041 }; 12042 12043 struct AAAddressSpaceArgument final : AAAddressSpaceImpl { 12044 AAAddressSpaceArgument(const IRPosition &IRP, Attributor &A) 12045 : AAAddressSpaceImpl(IRP, A) {} 12046 12047 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(addrspace); } 12048 }; 12049 12050 struct AAAddressSpaceCallSiteArgument final : AAAddressSpaceImpl { 12051 AAAddressSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A) 12052 : AAAddressSpaceImpl(IRP, A) {} 12053 12054 /// See AbstractAttribute::initialize(...). 12055 void initialize(Attributor &A) override { 12056 // TODO: we don't rewrite call site argument for now because it will need to 12057 // rewrite the function signature of the callee. 12058 (void)indicatePessimisticFixpoint(); 12059 } 12060 12061 void trackStatistics() const override { 12062 STATS_DECLTRACK_CSARG_ATTR(addrspace); 12063 } 12064 }; 12065 } // namespace 12066 12067 const char AANoUnwind::ID = 0; 12068 const char AANoSync::ID = 0; 12069 const char AANoFree::ID = 0; 12070 const char AANonNull::ID = 0; 12071 const char AAMustProgress::ID = 0; 12072 const char AANoRecurse::ID = 0; 12073 const char AANonConvergent::ID = 0; 12074 const char AAWillReturn::ID = 0; 12075 const char AAUndefinedBehavior::ID = 0; 12076 const char AANoAlias::ID = 0; 12077 const char AAIntraFnReachability::ID = 0; 12078 const char AANoReturn::ID = 0; 12079 const char AAIsDead::ID = 0; 12080 const char AADereferenceable::ID = 0; 12081 const char AAAlign::ID = 0; 12082 const char AAInstanceInfo::ID = 0; 12083 const char AANoCapture::ID = 0; 12084 const char AAValueSimplify::ID = 0; 12085 const char AAHeapToStack::ID = 0; 12086 const char AAPrivatizablePtr::ID = 0; 12087 const char AAMemoryBehavior::ID = 0; 12088 const char AAMemoryLocation::ID = 0; 12089 const char AAValueConstantRange::ID = 0; 12090 const char AAPotentialConstantValues::ID = 0; 12091 const char AAPotentialValues::ID = 0; 12092 const char AANoUndef::ID = 0; 12093 const char AANoFPClass::ID = 0; 12094 const char AACallEdges::ID = 0; 12095 const char AAInterFnReachability::ID = 0; 12096 const char AAPointerInfo::ID = 0; 12097 const char AAAssumptionInfo::ID = 0; 12098 const char AAUnderlyingObjects::ID = 0; 12099 const char AAAddressSpace::ID = 0; 12100 12101 // Macro magic to create the static generator function for attributes that 12102 // follow the naming scheme. 12103 12104 #define SWITCH_PK_INV(CLASS, PK, POS_NAME) \ 12105 case IRPosition::PK: \ 12106 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!"); 12107 12108 #define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \ 12109 case IRPosition::PK: \ 12110 AA = new (A.Allocator) CLASS##SUFFIX(IRP, A); \ 12111 ++NumAAs; \ 12112 break; 12113 12114 #define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \ 12115 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 12116 CLASS *AA = nullptr; \ 12117 switch (IRP.getPositionKind()) { \ 12118 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \ 12119 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \ 12120 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \ 12121 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \ 12122 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \ 12123 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \ 12124 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \ 12125 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \ 12126 } \ 12127 return *AA; \ 12128 } 12129 12130 #define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \ 12131 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 12132 CLASS *AA = nullptr; \ 12133 switch (IRP.getPositionKind()) { \ 12134 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \ 12135 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \ 12136 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \ 12137 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \ 12138 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \ 12139 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \ 12140 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \ 12141 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \ 12142 } \ 12143 return *AA; \ 12144 } 12145 12146 #define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \ 12147 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 12148 CLASS *AA = nullptr; \ 12149 switch (IRP.getPositionKind()) { \ 12150 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \ 12151 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \ 12152 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \ 12153 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \ 12154 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \ 12155 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \ 12156 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \ 12157 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \ 12158 } \ 12159 return *AA; \ 12160 } 12161 12162 #define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \ 12163 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 12164 CLASS *AA = nullptr; \ 12165 switch (IRP.getPositionKind()) { \ 12166 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \ 12167 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \ 12168 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \ 12169 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \ 12170 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \ 12171 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \ 12172 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \ 12173 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \ 12174 } \ 12175 return *AA; \ 12176 } 12177 12178 #define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \ 12179 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 12180 CLASS *AA = nullptr; \ 12181 switch (IRP.getPositionKind()) { \ 12182 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \ 12183 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \ 12184 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \ 12185 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \ 12186 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \ 12187 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \ 12188 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \ 12189 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \ 12190 } \ 12191 return *AA; \ 12192 } 12193 12194 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUnwind) 12195 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoSync) 12196 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoRecurse) 12197 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAWillReturn) 12198 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoReturn) 12199 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryLocation) 12200 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AACallEdges) 12201 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAssumptionInfo) 12202 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMustProgress) 12203 12204 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonNull) 12205 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoAlias) 12206 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPrivatizablePtr) 12207 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADereferenceable) 12208 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAlign) 12209 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAInstanceInfo) 12210 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoCapture) 12211 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueConstantRange) 12212 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPotentialConstantValues) 12213 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPotentialValues) 12214 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUndef) 12215 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFPClass) 12216 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPointerInfo) 12217 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAddressSpace) 12218 12219 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify) 12220 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIsDead) 12221 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree) 12222 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAUnderlyingObjects) 12223 12224 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAHeapToStack) 12225 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAUndefinedBehavior) 12226 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonConvergent) 12227 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIntraFnReachability) 12228 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAInterFnReachability) 12229 12230 CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryBehavior) 12231 12232 #undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION 12233 #undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION 12234 #undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION 12235 #undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION 12236 #undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION 12237 #undef SWITCH_PK_CREATE 12238 #undef SWITCH_PK_INV 12239