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/ScalarEvolution.h" 37 #include "llvm/Analysis/TargetTransformInfo.h" 38 #include "llvm/Analysis/ValueTracking.h" 39 #include "llvm/IR/Argument.h" 40 #include "llvm/IR/Assumptions.h" 41 #include "llvm/IR/Attributes.h" 42 #include "llvm/IR/BasicBlock.h" 43 #include "llvm/IR/Constant.h" 44 #include "llvm/IR/Constants.h" 45 #include "llvm/IR/DataLayout.h" 46 #include "llvm/IR/DerivedTypes.h" 47 #include "llvm/IR/GlobalValue.h" 48 #include "llvm/IR/IRBuilder.h" 49 #include "llvm/IR/InlineAsm.h" 50 #include "llvm/IR/InstrTypes.h" 51 #include "llvm/IR/Instruction.h" 52 #include "llvm/IR/Instructions.h" 53 #include "llvm/IR/IntrinsicInst.h" 54 #include "llvm/IR/IntrinsicsAMDGPU.h" 55 #include "llvm/IR/IntrinsicsNVPTX.h" 56 #include "llvm/IR/LLVMContext.h" 57 #include "llvm/IR/MDBuilder.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/InterleavedRange.h" 67 #include "llvm/Support/KnownFPClass.h" 68 #include "llvm/Support/MathExtras.h" 69 #include "llvm/Support/TypeSize.h" 70 #include "llvm/Support/raw_ostream.h" 71 #include "llvm/Transforms/Utils/BasicBlockUtils.h" 72 #include "llvm/Transforms/Utils/CallPromotionUtils.h" 73 #include "llvm/Transforms/Utils/Local.h" 74 #include "llvm/Transforms/Utils/ValueMapper.h" 75 #include <cassert> 76 #include <numeric> 77 #include <optional> 78 #include <string> 79 80 using namespace llvm; 81 82 #define DEBUG_TYPE "attributor" 83 84 static cl::opt<bool> ManifestInternal( 85 "attributor-manifest-internal", cl::Hidden, 86 cl::desc("Manifest Attributor internal string attributes."), 87 cl::init(false)); 88 89 static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128), 90 cl::Hidden); 91 92 template <> 93 unsigned llvm::PotentialConstantIntValuesState::MaxPotentialValues = 0; 94 95 template <> unsigned llvm::PotentialLLVMValuesState::MaxPotentialValues = -1; 96 97 static cl::opt<unsigned, true> MaxPotentialValues( 98 "attributor-max-potential-values", cl::Hidden, 99 cl::desc("Maximum number of potential values to be " 100 "tracked for each position."), 101 cl::location(llvm::PotentialConstantIntValuesState::MaxPotentialValues), 102 cl::init(7)); 103 104 static cl::opt<int> MaxPotentialValuesIterations( 105 "attributor-max-potential-values-iterations", cl::Hidden, 106 cl::desc( 107 "Maximum number of iterations we keep dismantling potential values."), 108 cl::init(64)); 109 110 STATISTIC(NumAAs, "Number of abstract attributes created"); 111 STATISTIC(NumIndirectCallsPromoted, "Number of indirect calls promoted"); 112 113 // Some helper macros to deal with statistics tracking. 114 // 115 // Usage: 116 // For simple IR attribute tracking overload trackStatistics in the abstract 117 // attribute and choose the right STATS_DECLTRACK_********* macro, 118 // e.g.,: 119 // void trackStatistics() const override { 120 // STATS_DECLTRACK_ARG_ATTR(returned) 121 // } 122 // If there is a single "increment" side one can use the macro 123 // STATS_DECLTRACK with a custom message. If there are multiple increment 124 // sides, STATS_DECL and STATS_TRACK can also be used separately. 125 // 126 #define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \ 127 ("Number of " #TYPE " marked '" #NAME "'") 128 #define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME 129 #define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG); 130 #define STATS_DECL(NAME, TYPE, MSG) \ 131 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG); 132 #define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE)); 133 #define STATS_DECLTRACK(NAME, TYPE, MSG) \ 134 {STATS_DECL(NAME, TYPE, MSG) STATS_TRACK(NAME, TYPE)} 135 #define STATS_DECLTRACK_ARG_ATTR(NAME) \ 136 STATS_DECLTRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME)) 137 #define STATS_DECLTRACK_CSARG_ATTR(NAME) \ 138 STATS_DECLTRACK(NAME, CSArguments, \ 139 BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME)) 140 #define STATS_DECLTRACK_FN_ATTR(NAME) \ 141 STATS_DECLTRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME)) 142 #define STATS_DECLTRACK_CS_ATTR(NAME) \ 143 STATS_DECLTRACK(NAME, CS, BUILD_STAT_MSG_IR_ATTR(call site, NAME)) 144 #define STATS_DECLTRACK_FNRET_ATTR(NAME) \ 145 STATS_DECLTRACK(NAME, FunctionReturn, \ 146 BUILD_STAT_MSG_IR_ATTR(function returns, NAME)) 147 #define STATS_DECLTRACK_CSRET_ATTR(NAME) \ 148 STATS_DECLTRACK(NAME, CSReturn, \ 149 BUILD_STAT_MSG_IR_ATTR(call site returns, NAME)) 150 #define STATS_DECLTRACK_FLOATING_ATTR(NAME) \ 151 STATS_DECLTRACK(NAME, Floating, \ 152 ("Number of floating values known to be '" #NAME "'")) 153 154 // Specialization of the operator<< for abstract attributes subclasses. This 155 // disambiguates situations where multiple operators are applicable. 156 namespace llvm { 157 #define PIPE_OPERATOR(CLASS) \ 158 raw_ostream &operator<<(raw_ostream &OS, const CLASS &AA) { \ 159 return OS << static_cast<const AbstractAttribute &>(AA); \ 160 } 161 162 PIPE_OPERATOR(AAIsDead) 163 PIPE_OPERATOR(AANoUnwind) 164 PIPE_OPERATOR(AANoSync) 165 PIPE_OPERATOR(AANoRecurse) 166 PIPE_OPERATOR(AANonConvergent) 167 PIPE_OPERATOR(AAWillReturn) 168 PIPE_OPERATOR(AANoReturn) 169 PIPE_OPERATOR(AANonNull) 170 PIPE_OPERATOR(AAMustProgress) 171 PIPE_OPERATOR(AANoAlias) 172 PIPE_OPERATOR(AADereferenceable) 173 PIPE_OPERATOR(AAAlign) 174 PIPE_OPERATOR(AAInstanceInfo) 175 PIPE_OPERATOR(AANoCapture) 176 PIPE_OPERATOR(AAValueSimplify) 177 PIPE_OPERATOR(AANoFree) 178 PIPE_OPERATOR(AAHeapToStack) 179 PIPE_OPERATOR(AAIntraFnReachability) 180 PIPE_OPERATOR(AAMemoryBehavior) 181 PIPE_OPERATOR(AAMemoryLocation) 182 PIPE_OPERATOR(AAValueConstantRange) 183 PIPE_OPERATOR(AAPrivatizablePtr) 184 PIPE_OPERATOR(AAUndefinedBehavior) 185 PIPE_OPERATOR(AAPotentialConstantValues) 186 PIPE_OPERATOR(AAPotentialValues) 187 PIPE_OPERATOR(AANoUndef) 188 PIPE_OPERATOR(AANoFPClass) 189 PIPE_OPERATOR(AACallEdges) 190 PIPE_OPERATOR(AAInterFnReachability) 191 PIPE_OPERATOR(AAPointerInfo) 192 PIPE_OPERATOR(AAAssumptionInfo) 193 PIPE_OPERATOR(AAUnderlyingObjects) 194 PIPE_OPERATOR(AAInvariantLoadPointer) 195 PIPE_OPERATOR(AAAddressSpace) 196 PIPE_OPERATOR(AANoAliasAddrSpace) 197 PIPE_OPERATOR(AAAllocationInfo) 198 PIPE_OPERATOR(AAIndirectCallInfo) 199 PIPE_OPERATOR(AAGlobalValueInfo) 200 PIPE_OPERATOR(AADenormalFPMath) 201 202 #undef PIPE_OPERATOR 203 204 template <> 205 ChangeStatus clampStateAndIndicateChange<DerefState>(DerefState &S, 206 const DerefState &R) { 207 ChangeStatus CS0 = 208 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState); 209 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState); 210 return CS0 | CS1; 211 } 212 213 } // namespace llvm 214 215 static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I, 216 bool HeaderOnly, Cycle **CPtr = nullptr) { 217 if (!CI) 218 return true; 219 auto *BB = I->getParent(); 220 auto *C = CI->getCycle(BB); 221 if (!C) 222 return false; 223 if (CPtr) 224 *CPtr = C; 225 return !HeaderOnly || BB == C->getHeader(); 226 } 227 228 /// Checks if a type could have padding bytes. 229 static bool isDenselyPacked(Type *Ty, const DataLayout &DL) { 230 // There is no size information, so be conservative. 231 if (!Ty->isSized()) 232 return false; 233 234 // If the alloc size is not equal to the storage size, then there are padding 235 // bytes. For x86_fp80 on x86-64, size: 80 alloc size: 128. 236 if (DL.getTypeSizeInBits(Ty) != DL.getTypeAllocSizeInBits(Ty)) 237 return false; 238 239 // FIXME: This isn't the right way to check for padding in vectors with 240 // non-byte-size elements. 241 if (VectorType *SeqTy = dyn_cast<VectorType>(Ty)) 242 return isDenselyPacked(SeqTy->getElementType(), DL); 243 244 // For array types, check for padding within members. 245 if (ArrayType *SeqTy = dyn_cast<ArrayType>(Ty)) 246 return isDenselyPacked(SeqTy->getElementType(), DL); 247 248 if (!isa<StructType>(Ty)) 249 return true; 250 251 // Check for padding within and between elements of a struct. 252 StructType *StructTy = cast<StructType>(Ty); 253 const StructLayout *Layout = DL.getStructLayout(StructTy); 254 uint64_t StartPos = 0; 255 for (unsigned I = 0, E = StructTy->getNumElements(); I < E; ++I) { 256 Type *ElTy = StructTy->getElementType(I); 257 if (!isDenselyPacked(ElTy, DL)) 258 return false; 259 if (StartPos != Layout->getElementOffsetInBits(I)) 260 return false; 261 StartPos += DL.getTypeAllocSizeInBits(ElTy); 262 } 263 264 return true; 265 } 266 267 /// Get pointer operand of memory accessing instruction. If \p I is 268 /// not a memory accessing instruction, return nullptr. If \p AllowVolatile, 269 /// is set to false and the instruction is volatile, return nullptr. 270 static const Value *getPointerOperand(const Instruction *I, 271 bool AllowVolatile) { 272 if (!AllowVolatile && I->isVolatile()) 273 return nullptr; 274 275 if (auto *LI = dyn_cast<LoadInst>(I)) { 276 return LI->getPointerOperand(); 277 } 278 279 if (auto *SI = dyn_cast<StoreInst>(I)) { 280 return SI->getPointerOperand(); 281 } 282 283 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(I)) { 284 return CXI->getPointerOperand(); 285 } 286 287 if (auto *RMWI = dyn_cast<AtomicRMWInst>(I)) { 288 return RMWI->getPointerOperand(); 289 } 290 291 return nullptr; 292 } 293 294 /// Helper function to create a pointer based on \p Ptr, and advanced by \p 295 /// Offset bytes. 296 static Value *constructPointer(Value *Ptr, int64_t Offset, 297 IRBuilder<NoFolder> &IRB) { 298 LLVM_DEBUG(dbgs() << "Construct pointer: " << *Ptr << " + " << Offset 299 << "-bytes\n"); 300 301 if (Offset) 302 Ptr = IRB.CreatePtrAdd(Ptr, IRB.getInt64(Offset), 303 Ptr->getName() + ".b" + Twine(Offset)); 304 return Ptr; 305 } 306 307 static const Value * 308 stripAndAccumulateOffsets(Attributor &A, const AbstractAttribute &QueryingAA, 309 const Value *Val, const DataLayout &DL, APInt &Offset, 310 bool GetMinOffset, bool AllowNonInbounds, 311 bool UseAssumed = false) { 312 313 auto AttributorAnalysis = [&](Value &V, APInt &ROffset) -> bool { 314 const IRPosition &Pos = IRPosition::value(V); 315 // Only track dependence if we are going to use the assumed info. 316 const AAValueConstantRange *ValueConstantRangeAA = 317 A.getAAFor<AAValueConstantRange>(QueryingAA, Pos, 318 UseAssumed ? DepClassTy::OPTIONAL 319 : DepClassTy::NONE); 320 if (!ValueConstantRangeAA) 321 return false; 322 ConstantRange Range = UseAssumed ? ValueConstantRangeAA->getAssumed() 323 : ValueConstantRangeAA->getKnown(); 324 if (Range.isFullSet()) 325 return false; 326 327 // We can only use the lower part of the range because the upper part can 328 // be higher than what the value can really be. 329 if (GetMinOffset) 330 ROffset = Range.getSignedMin(); 331 else 332 ROffset = Range.getSignedMax(); 333 return true; 334 }; 335 336 return Val->stripAndAccumulateConstantOffsets(DL, Offset, AllowNonInbounds, 337 /* AllowInvariant */ true, 338 AttributorAnalysis); 339 } 340 341 static const Value * 342 getMinimalBaseOfPointer(Attributor &A, const AbstractAttribute &QueryingAA, 343 const Value *Ptr, int64_t &BytesOffset, 344 const DataLayout &DL, bool AllowNonInbounds = false) { 345 APInt OffsetAPInt(DL.getIndexTypeSizeInBits(Ptr->getType()), 0); 346 const Value *Base = 347 stripAndAccumulateOffsets(A, QueryingAA, Ptr, DL, OffsetAPInt, 348 /* GetMinOffset */ true, AllowNonInbounds); 349 350 BytesOffset = OffsetAPInt.getSExtValue(); 351 return Base; 352 } 353 354 /// Clamp the information known for all returned values of a function 355 /// (identified by \p QueryingAA) into \p S. 356 template <typename AAType, typename StateType = typename AAType::StateType, 357 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind, 358 bool RecurseForSelectAndPHI = true> 359 static void clampReturnedValueStates( 360 Attributor &A, const AAType &QueryingAA, StateType &S, 361 const IRPosition::CallBaseContext *CBContext = nullptr) { 362 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for " 363 << QueryingAA << " into " << S << "\n"); 364 365 assert((QueryingAA.getIRPosition().getPositionKind() == 366 IRPosition::IRP_RETURNED || 367 QueryingAA.getIRPosition().getPositionKind() == 368 IRPosition::IRP_CALL_SITE_RETURNED) && 369 "Can only clamp returned value states for a function returned or call " 370 "site returned position!"); 371 372 // Use an optional state as there might not be any return values and we want 373 // to join (IntegerState::operator&) the state of all there are. 374 std::optional<StateType> T; 375 376 // Callback for each possibly returned value. 377 auto CheckReturnValue = [&](Value &RV) -> bool { 378 const IRPosition &RVPos = IRPosition::value(RV, CBContext); 379 // If possible, use the hasAssumedIRAttr interface. 380 if (Attribute::isEnumAttrKind(IRAttributeKind)) { 381 bool IsKnown; 382 return AA::hasAssumedIRAttr<IRAttributeKind>( 383 A, &QueryingAA, RVPos, DepClassTy::REQUIRED, IsKnown); 384 } 385 386 const AAType *AA = 387 A.getAAFor<AAType>(QueryingAA, RVPos, DepClassTy::REQUIRED); 388 if (!AA) 389 return false; 390 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV 391 << " AA: " << AA->getAsStr(&A) << " @ " << RVPos << "\n"); 392 const StateType &AAS = AA->getState(); 393 if (!T) 394 T = StateType::getBestState(AAS); 395 *T &= AAS; 396 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T 397 << "\n"); 398 return T->isValidState(); 399 }; 400 401 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA, 402 AA::ValueScope::Intraprocedural, 403 RecurseForSelectAndPHI)) 404 S.indicatePessimisticFixpoint(); 405 else if (T) 406 S ^= *T; 407 } 408 409 namespace { 410 /// Helper class for generic deduction: return value -> returned position. 411 template <typename AAType, typename BaseType, 412 typename StateType = typename BaseType::StateType, 413 bool PropagateCallBaseContext = false, 414 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind, 415 bool RecurseForSelectAndPHI = true> 416 struct AAReturnedFromReturnedValues : public BaseType { 417 AAReturnedFromReturnedValues(const IRPosition &IRP, Attributor &A) 418 : BaseType(IRP, A) {} 419 420 /// See AbstractAttribute::updateImpl(...). 421 ChangeStatus updateImpl(Attributor &A) override { 422 StateType S(StateType::getBestState(this->getState())); 423 clampReturnedValueStates<AAType, StateType, IRAttributeKind, 424 RecurseForSelectAndPHI>( 425 A, *this, S, 426 PropagateCallBaseContext ? this->getCallBaseContext() : nullptr); 427 // TODO: If we know we visited all returned values, thus no are assumed 428 // dead, we can take the known information from the state T. 429 return clampStateAndIndicateChange<StateType>(this->getState(), S); 430 } 431 }; 432 433 /// Clamp the information known at all call sites for a given argument 434 /// (identified by \p QueryingAA) into \p S. 435 template <typename AAType, typename StateType = typename AAType::StateType, 436 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind> 437 static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA, 438 StateType &S) { 439 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for " 440 << QueryingAA << " into " << S << "\n"); 441 442 assert(QueryingAA.getIRPosition().getPositionKind() == 443 IRPosition::IRP_ARGUMENT && 444 "Can only clamp call site argument states for an argument position!"); 445 446 // Use an optional state as there might not be any return values and we want 447 // to join (IntegerState::operator&) the state of all there are. 448 std::optional<StateType> T; 449 450 // The argument number which is also the call site argument number. 451 unsigned ArgNo = QueryingAA.getIRPosition().getCallSiteArgNo(); 452 453 auto CallSiteCheck = [&](AbstractCallSite ACS) { 454 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo); 455 // Check if a coresponding argument was found or if it is on not associated 456 // (which can happen for callback calls). 457 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID) 458 return false; 459 460 // If possible, use the hasAssumedIRAttr interface. 461 if (Attribute::isEnumAttrKind(IRAttributeKind)) { 462 bool IsKnown; 463 return AA::hasAssumedIRAttr<IRAttributeKind>( 464 A, &QueryingAA, ACSArgPos, DepClassTy::REQUIRED, IsKnown); 465 } 466 467 const AAType *AA = 468 A.getAAFor<AAType>(QueryingAA, ACSArgPos, DepClassTy::REQUIRED); 469 if (!AA) 470 return false; 471 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction() 472 << " AA: " << AA->getAsStr(&A) << " @" << ACSArgPos 473 << "\n"); 474 const StateType &AAS = AA->getState(); 475 if (!T) 476 T = StateType::getBestState(AAS); 477 *T &= AAS; 478 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T 479 << "\n"); 480 return T->isValidState(); 481 }; 482 483 bool UsedAssumedInformation = false; 484 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true, 485 UsedAssumedInformation)) 486 S.indicatePessimisticFixpoint(); 487 else if (T) 488 S ^= *T; 489 } 490 491 /// This function is the bridge between argument position and the call base 492 /// context. 493 template <typename AAType, typename BaseType, 494 typename StateType = typename AAType::StateType, 495 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind> 496 bool getArgumentStateFromCallBaseContext(Attributor &A, 497 BaseType &QueryingAttribute, 498 IRPosition &Pos, StateType &State) { 499 assert((Pos.getPositionKind() == IRPosition::IRP_ARGUMENT) && 500 "Expected an 'argument' position !"); 501 const CallBase *CBContext = Pos.getCallBaseContext(); 502 if (!CBContext) 503 return false; 504 505 int ArgNo = Pos.getCallSiteArgNo(); 506 assert(ArgNo >= 0 && "Invalid Arg No!"); 507 const IRPosition CBArgPos = IRPosition::callsite_argument(*CBContext, ArgNo); 508 509 // If possible, use the hasAssumedIRAttr interface. 510 if (Attribute::isEnumAttrKind(IRAttributeKind)) { 511 bool IsKnown; 512 return AA::hasAssumedIRAttr<IRAttributeKind>( 513 A, &QueryingAttribute, CBArgPos, DepClassTy::REQUIRED, IsKnown); 514 } 515 516 const auto *AA = 517 A.getAAFor<AAType>(QueryingAttribute, CBArgPos, DepClassTy::REQUIRED); 518 if (!AA) 519 return false; 520 const StateType &CBArgumentState = 521 static_cast<const StateType &>(AA->getState()); 522 523 LLVM_DEBUG(dbgs() << "[Attributor] Briding Call site context to argument" 524 << "Position:" << Pos << "CB Arg state:" << CBArgumentState 525 << "\n"); 526 527 // NOTE: If we want to do call site grouping it should happen here. 528 State ^= CBArgumentState; 529 return true; 530 } 531 532 /// Helper class for generic deduction: call site argument -> argument position. 533 template <typename AAType, typename BaseType, 534 typename StateType = typename AAType::StateType, 535 bool BridgeCallBaseContext = false, 536 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind> 537 struct AAArgumentFromCallSiteArguments : public BaseType { 538 AAArgumentFromCallSiteArguments(const IRPosition &IRP, Attributor &A) 539 : BaseType(IRP, A) {} 540 541 /// See AbstractAttribute::updateImpl(...). 542 ChangeStatus updateImpl(Attributor &A) override { 543 StateType S = StateType::getBestState(this->getState()); 544 545 if (BridgeCallBaseContext) { 546 bool Success = 547 getArgumentStateFromCallBaseContext<AAType, BaseType, StateType, 548 IRAttributeKind>( 549 A, *this, this->getIRPosition(), S); 550 if (Success) 551 return clampStateAndIndicateChange<StateType>(this->getState(), S); 552 } 553 clampCallSiteArgumentStates<AAType, StateType, IRAttributeKind>(A, *this, 554 S); 555 556 // TODO: If we know we visited all incoming values, thus no are assumed 557 // dead, we can take the known information from the state T. 558 return clampStateAndIndicateChange<StateType>(this->getState(), S); 559 } 560 }; 561 562 /// Helper class for generic replication: function returned -> cs returned. 563 template <typename AAType, typename BaseType, 564 typename StateType = typename BaseType::StateType, 565 bool IntroduceCallBaseContext = false, 566 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind> 567 struct AACalleeToCallSite : public BaseType { 568 AACalleeToCallSite(const IRPosition &IRP, Attributor &A) : BaseType(IRP, A) {} 569 570 /// See AbstractAttribute::updateImpl(...). 571 ChangeStatus updateImpl(Attributor &A) override { 572 auto IRPKind = this->getIRPosition().getPositionKind(); 573 assert((IRPKind == IRPosition::IRP_CALL_SITE_RETURNED || 574 IRPKind == IRPosition::IRP_CALL_SITE) && 575 "Can only wrap function returned positions for call site " 576 "returned positions!"); 577 auto &S = this->getState(); 578 579 CallBase &CB = cast<CallBase>(this->getAnchorValue()); 580 if (IntroduceCallBaseContext) 581 LLVM_DEBUG(dbgs() << "[Attributor] Introducing call base context:" << CB 582 << "\n"); 583 584 ChangeStatus Changed = ChangeStatus::UNCHANGED; 585 auto CalleePred = [&](ArrayRef<const Function *> Callees) { 586 for (const Function *Callee : Callees) { 587 IRPosition FnPos = 588 IRPKind == llvm::IRPosition::IRP_CALL_SITE_RETURNED 589 ? IRPosition::returned(*Callee, 590 IntroduceCallBaseContext ? &CB : nullptr) 591 : IRPosition::function( 592 *Callee, IntroduceCallBaseContext ? &CB : nullptr); 593 // If possible, use the hasAssumedIRAttr interface. 594 if (Attribute::isEnumAttrKind(IRAttributeKind)) { 595 bool IsKnown; 596 if (!AA::hasAssumedIRAttr<IRAttributeKind>( 597 A, this, FnPos, DepClassTy::REQUIRED, IsKnown)) 598 return false; 599 continue; 600 } 601 602 const AAType *AA = 603 A.getAAFor<AAType>(*this, FnPos, DepClassTy::REQUIRED); 604 if (!AA) 605 return false; 606 Changed |= clampStateAndIndicateChange(S, AA->getState()); 607 if (S.isAtFixpoint()) 608 return S.isValidState(); 609 } 610 return true; 611 }; 612 if (!A.checkForAllCallees(CalleePred, *this, CB)) 613 return S.indicatePessimisticFixpoint(); 614 return Changed; 615 } 616 }; 617 618 /// Helper function to accumulate uses. 619 template <class AAType, typename StateType = typename AAType::StateType> 620 static void followUsesInContext(AAType &AA, Attributor &A, 621 MustBeExecutedContextExplorer &Explorer, 622 const Instruction *CtxI, 623 SetVector<const Use *> &Uses, 624 StateType &State) { 625 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI); 626 for (unsigned u = 0; u < Uses.size(); ++u) { 627 const Use *U = Uses[u]; 628 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) { 629 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd); 630 if (Found && AA.followUseInMBEC(A, U, UserI, State)) 631 Uses.insert_range(llvm::make_pointer_range(UserI->uses())); 632 } 633 } 634 } 635 636 /// Use the must-be-executed-context around \p I to add information into \p S. 637 /// The AAType class is required to have `followUseInMBEC` method with the 638 /// following signature and behaviour: 639 /// 640 /// bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I) 641 /// U - Underlying use. 642 /// I - The user of the \p U. 643 /// Returns true if the value should be tracked transitively. 644 /// 645 template <class AAType, typename StateType = typename AAType::StateType> 646 static void followUsesInMBEC(AAType &AA, Attributor &A, StateType &S, 647 Instruction &CtxI) { 648 const Value &Val = AA.getIRPosition().getAssociatedValue(); 649 if (isa<ConstantData>(Val)) 650 return; 651 652 MustBeExecutedContextExplorer *Explorer = 653 A.getInfoCache().getMustBeExecutedContextExplorer(); 654 if (!Explorer) 655 return; 656 657 // Container for (transitive) uses of the associated value. 658 SetVector<const Use *> Uses; 659 for (const Use &U : Val.uses()) 660 Uses.insert(&U); 661 662 followUsesInContext<AAType>(AA, A, *Explorer, &CtxI, Uses, S); 663 664 if (S.isAtFixpoint()) 665 return; 666 667 SmallVector<const BranchInst *, 4> BrInsts; 668 auto Pred = [&](const Instruction *I) { 669 if (const BranchInst *Br = dyn_cast<BranchInst>(I)) 670 if (Br->isConditional()) 671 BrInsts.push_back(Br); 672 return true; 673 }; 674 675 // Here, accumulate conditional branch instructions in the context. We 676 // explore the child paths and collect the known states. The disjunction of 677 // those states can be merged to its own state. Let ParentState_i be a state 678 // to indicate the known information for an i-th branch instruction in the 679 // context. ChildStates are created for its successors respectively. 680 // 681 // ParentS_1 = ChildS_{1, 1} /\ ChildS_{1, 2} /\ ... /\ ChildS_{1, n_1} 682 // ParentS_2 = ChildS_{2, 1} /\ ChildS_{2, 2} /\ ... /\ ChildS_{2, n_2} 683 // ... 684 // ParentS_m = ChildS_{m, 1} /\ ChildS_{m, 2} /\ ... /\ ChildS_{m, n_m} 685 // 686 // Known State |= ParentS_1 \/ ParentS_2 \/... \/ ParentS_m 687 // 688 // FIXME: Currently, recursive branches are not handled. For example, we 689 // can't deduce that ptr must be dereferenced in below function. 690 // 691 // void f(int a, int c, int *ptr) { 692 // if(a) 693 // if (b) { 694 // *ptr = 0; 695 // } else { 696 // *ptr = 1; 697 // } 698 // else { 699 // if (b) { 700 // *ptr = 0; 701 // } else { 702 // *ptr = 1; 703 // } 704 // } 705 // } 706 707 Explorer->checkForAllContext(&CtxI, Pred); 708 for (const BranchInst *Br : BrInsts) { 709 StateType ParentState; 710 711 // The known state of the parent state is a conjunction of children's 712 // known states so it is initialized with a best state. 713 ParentState.indicateOptimisticFixpoint(); 714 715 for (const BasicBlock *BB : Br->successors()) { 716 StateType ChildState; 717 718 size_t BeforeSize = Uses.size(); 719 followUsesInContext(AA, A, *Explorer, &BB->front(), Uses, ChildState); 720 721 // Erase uses which only appear in the child. 722 for (auto It = Uses.begin() + BeforeSize; It != Uses.end();) 723 It = Uses.erase(It); 724 725 ParentState &= ChildState; 726 } 727 728 // Use only known state. 729 S += ParentState; 730 } 731 } 732 } // namespace 733 734 /// ------------------------ PointerInfo --------------------------------------- 735 736 namespace llvm { 737 namespace AA { 738 namespace PointerInfo { 739 740 struct State; 741 742 } // namespace PointerInfo 743 } // namespace AA 744 745 /// Helper for AA::PointerInfo::Access DenseMap/Set usage. 746 template <> 747 struct DenseMapInfo<AAPointerInfo::Access> : DenseMapInfo<Instruction *> { 748 using Access = AAPointerInfo::Access; 749 static inline Access getEmptyKey(); 750 static inline Access getTombstoneKey(); 751 static unsigned getHashValue(const Access &A); 752 static bool isEqual(const Access &LHS, const Access &RHS); 753 }; 754 755 /// Helper that allows RangeTy as a key in a DenseMap. 756 template <> struct DenseMapInfo<AA::RangeTy> { 757 static inline AA::RangeTy getEmptyKey() { 758 auto EmptyKey = DenseMapInfo<int64_t>::getEmptyKey(); 759 return AA::RangeTy{EmptyKey, EmptyKey}; 760 } 761 762 static inline AA::RangeTy getTombstoneKey() { 763 auto TombstoneKey = DenseMapInfo<int64_t>::getTombstoneKey(); 764 return AA::RangeTy{TombstoneKey, TombstoneKey}; 765 } 766 767 static unsigned getHashValue(const AA::RangeTy &Range) { 768 return detail::combineHashValue( 769 DenseMapInfo<int64_t>::getHashValue(Range.Offset), 770 DenseMapInfo<int64_t>::getHashValue(Range.Size)); 771 } 772 773 static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B) { 774 return A == B; 775 } 776 }; 777 778 /// Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign 779 /// but the instruction 780 struct AccessAsInstructionInfo : DenseMapInfo<Instruction *> { 781 using Base = DenseMapInfo<Instruction *>; 782 using Access = AAPointerInfo::Access; 783 static inline Access getEmptyKey(); 784 static inline Access getTombstoneKey(); 785 static unsigned getHashValue(const Access &A); 786 static bool isEqual(const Access &LHS, const Access &RHS); 787 }; 788 789 } // namespace llvm 790 791 /// A type to track pointer/struct usage and accesses for AAPointerInfo. 792 struct AA::PointerInfo::State : public AbstractState { 793 /// Return the best possible representable state. 794 static State getBestState(const State &SIS) { return State(); } 795 796 /// Return the worst possible representable state. 797 static State getWorstState(const State &SIS) { 798 State R; 799 R.indicatePessimisticFixpoint(); 800 return R; 801 } 802 803 State() = default; 804 State(State &&SIS) = default; 805 806 const State &getAssumed() const { return *this; } 807 808 /// See AbstractState::isValidState(). 809 bool isValidState() const override { return BS.isValidState(); } 810 811 /// See AbstractState::isAtFixpoint(). 812 bool isAtFixpoint() const override { return BS.isAtFixpoint(); } 813 814 /// See AbstractState::indicateOptimisticFixpoint(). 815 ChangeStatus indicateOptimisticFixpoint() override { 816 BS.indicateOptimisticFixpoint(); 817 return ChangeStatus::UNCHANGED; 818 } 819 820 /// See AbstractState::indicatePessimisticFixpoint(). 821 ChangeStatus indicatePessimisticFixpoint() override { 822 BS.indicatePessimisticFixpoint(); 823 return ChangeStatus::CHANGED; 824 } 825 826 State &operator=(const State &R) { 827 if (this == &R) 828 return *this; 829 BS = R.BS; 830 AccessList = R.AccessList; 831 OffsetBins = R.OffsetBins; 832 RemoteIMap = R.RemoteIMap; 833 ReturnedOffsets = R.ReturnedOffsets; 834 return *this; 835 } 836 837 State &operator=(State &&R) { 838 if (this == &R) 839 return *this; 840 std::swap(BS, R.BS); 841 std::swap(AccessList, R.AccessList); 842 std::swap(OffsetBins, R.OffsetBins); 843 std::swap(RemoteIMap, R.RemoteIMap); 844 std::swap(ReturnedOffsets, R.ReturnedOffsets); 845 return *this; 846 } 847 848 /// Add a new Access to the state at offset \p Offset and with size \p Size. 849 /// The access is associated with \p I, writes \p Content (if anything), and 850 /// is of kind \p Kind. If an Access already exists for the same \p I and same 851 /// \p RemoteI, the two are combined, potentially losing information about 852 /// offset and size. The resulting access must now be moved from its original 853 /// OffsetBin to the bin for its new offset. 854 /// 855 /// \Returns CHANGED, if the state changed, UNCHANGED otherwise. 856 ChangeStatus addAccess(Attributor &A, const AAPointerInfo::RangeList &Ranges, 857 Instruction &I, std::optional<Value *> Content, 858 AAPointerInfo::AccessKind Kind, Type *Ty, 859 Instruction *RemoteI = nullptr); 860 861 AAPointerInfo::const_bin_iterator begin() const { return OffsetBins.begin(); } 862 AAPointerInfo::const_bin_iterator end() const { return OffsetBins.end(); } 863 int64_t numOffsetBins() const { return OffsetBins.size(); } 864 865 const AAPointerInfo::Access &getAccess(unsigned Index) const { 866 return AccessList[Index]; 867 } 868 869 protected: 870 // Every memory instruction results in an Access object. We maintain a list of 871 // all Access objects that we own, along with the following maps: 872 // 873 // - OffsetBins: RangeTy -> { Access } 874 // - RemoteIMap: RemoteI x LocalI -> Access 875 // 876 // A RemoteI is any instruction that accesses memory. RemoteI is different 877 // from LocalI if and only if LocalI is a call; then RemoteI is some 878 // instruction in the callgraph starting from LocalI. Multiple paths in the 879 // callgraph from LocalI to RemoteI may produce multiple accesses, but these 880 // are all combined into a single Access object. This may result in loss of 881 // information in RangeTy in the Access object. 882 SmallVector<AAPointerInfo::Access> AccessList; 883 AAPointerInfo::OffsetBinsTy OffsetBins; 884 DenseMap<const Instruction *, SmallVector<unsigned>> RemoteIMap; 885 886 /// Flag to determine if the underlying pointer is reaching a return statement 887 /// in the associated function or not. Returns in other functions cause 888 /// invalidation. 889 AAPointerInfo::OffsetInfo ReturnedOffsets; 890 891 /// See AAPointerInfo::forallInterferingAccesses. 892 template <typename F> 893 bool forallInterferingAccesses(AA::RangeTy Range, F CB) const { 894 if (!isValidState() || !ReturnedOffsets.isUnassigned()) 895 return false; 896 897 for (const auto &It : OffsetBins) { 898 AA::RangeTy ItRange = It.getFirst(); 899 if (!Range.mayOverlap(ItRange)) 900 continue; 901 bool IsExact = Range == ItRange && !Range.offsetOrSizeAreUnknown(); 902 for (auto Index : It.getSecond()) { 903 auto &Access = AccessList[Index]; 904 if (!CB(Access, IsExact)) 905 return false; 906 } 907 } 908 return true; 909 } 910 911 /// See AAPointerInfo::forallInterferingAccesses. 912 template <typename F> 913 bool forallInterferingAccesses(Instruction &I, F CB, 914 AA::RangeTy &Range) const { 915 if (!isValidState() || !ReturnedOffsets.isUnassigned()) 916 return false; 917 918 auto LocalList = RemoteIMap.find(&I); 919 if (LocalList == RemoteIMap.end()) { 920 return true; 921 } 922 923 for (unsigned Index : LocalList->getSecond()) { 924 for (auto &R : AccessList[Index]) { 925 Range &= R; 926 if (Range.offsetAndSizeAreUnknown()) 927 break; 928 } 929 } 930 return forallInterferingAccesses(Range, CB); 931 } 932 933 private: 934 /// State to track fixpoint and validity. 935 BooleanState BS; 936 }; 937 938 ChangeStatus AA::PointerInfo::State::addAccess( 939 Attributor &A, const AAPointerInfo::RangeList &Ranges, Instruction &I, 940 std::optional<Value *> Content, AAPointerInfo::AccessKind Kind, Type *Ty, 941 Instruction *RemoteI) { 942 RemoteI = RemoteI ? RemoteI : &I; 943 944 // Check if we have an access for this instruction, if not, simply add it. 945 auto &LocalList = RemoteIMap[RemoteI]; 946 bool AccExists = false; 947 unsigned AccIndex = AccessList.size(); 948 for (auto Index : LocalList) { 949 auto &A = AccessList[Index]; 950 if (A.getLocalInst() == &I) { 951 AccExists = true; 952 AccIndex = Index; 953 break; 954 } 955 } 956 957 auto AddToBins = [&](const AAPointerInfo::RangeList &ToAdd) { 958 LLVM_DEBUG(if (ToAdd.size()) dbgs() 959 << "[AAPointerInfo] Inserting access in new offset bins\n";); 960 961 for (auto Key : ToAdd) { 962 LLVM_DEBUG(dbgs() << " key " << Key << "\n"); 963 OffsetBins[Key].insert(AccIndex); 964 } 965 }; 966 967 if (!AccExists) { 968 AccessList.emplace_back(&I, RemoteI, Ranges, Content, Kind, Ty); 969 assert((AccessList.size() == AccIndex + 1) && 970 "New Access should have been at AccIndex"); 971 LocalList.push_back(AccIndex); 972 AddToBins(AccessList[AccIndex].getRanges()); 973 return ChangeStatus::CHANGED; 974 } 975 976 // Combine the new Access with the existing Access, and then update the 977 // mapping in the offset bins. 978 AAPointerInfo::Access Acc(&I, RemoteI, Ranges, Content, Kind, Ty); 979 auto &Current = AccessList[AccIndex]; 980 auto Before = Current; 981 Current &= Acc; 982 if (Current == Before) 983 return ChangeStatus::UNCHANGED; 984 985 auto &ExistingRanges = Before.getRanges(); 986 auto &NewRanges = Current.getRanges(); 987 988 // Ranges that are in the old access but not the new access need to be removed 989 // from the offset bins. 990 AAPointerInfo::RangeList ToRemove; 991 AAPointerInfo::RangeList::set_difference(ExistingRanges, NewRanges, ToRemove); 992 LLVM_DEBUG(if (ToRemove.size()) dbgs() 993 << "[AAPointerInfo] Removing access from old offset bins\n";); 994 995 for (auto Key : ToRemove) { 996 LLVM_DEBUG(dbgs() << " key " << Key << "\n"); 997 assert(OffsetBins.count(Key) && "Existing Access must be in some bin."); 998 auto &Bin = OffsetBins[Key]; 999 assert(Bin.count(AccIndex) && 1000 "Expected bin to actually contain the Access."); 1001 Bin.erase(AccIndex); 1002 } 1003 1004 // Ranges that are in the new access but not the old access need to be added 1005 // to the offset bins. 1006 AAPointerInfo::RangeList ToAdd; 1007 AAPointerInfo::RangeList::set_difference(NewRanges, ExistingRanges, ToAdd); 1008 AddToBins(ToAdd); 1009 return ChangeStatus::CHANGED; 1010 } 1011 1012 namespace { 1013 1014 #ifndef NDEBUG 1015 static raw_ostream &operator<<(raw_ostream &OS, 1016 const AAPointerInfo::OffsetInfo &OI) { 1017 OS << llvm::interleaved_array(OI); 1018 return OS; 1019 } 1020 #endif // NDEBUG 1021 1022 struct AAPointerInfoImpl 1023 : public StateWrapper<AA::PointerInfo::State, AAPointerInfo> { 1024 using BaseTy = StateWrapper<AA::PointerInfo::State, AAPointerInfo>; 1025 AAPointerInfoImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {} 1026 1027 /// See AbstractAttribute::getAsStr(). 1028 const std::string getAsStr(Attributor *A) const override { 1029 return std::string("PointerInfo ") + 1030 (isValidState() ? (std::string("#") + 1031 std::to_string(OffsetBins.size()) + " bins") 1032 : "<invalid>") + 1033 (reachesReturn() 1034 ? (" (returned:" + 1035 join(map_range(ReturnedOffsets, 1036 [](int64_t O) { return std::to_string(O); }), 1037 ", ") + 1038 ")") 1039 : ""); 1040 } 1041 1042 /// See AbstractAttribute::manifest(...). 1043 ChangeStatus manifest(Attributor &A) override { 1044 return AAPointerInfo::manifest(A); 1045 } 1046 1047 virtual const_bin_iterator begin() const override { return State::begin(); } 1048 virtual const_bin_iterator end() const override { return State::end(); } 1049 virtual int64_t numOffsetBins() const override { 1050 return State::numOffsetBins(); 1051 } 1052 virtual bool reachesReturn() const override { 1053 return !ReturnedOffsets.isUnassigned(); 1054 } 1055 virtual void addReturnedOffsetsTo(OffsetInfo &OI) const override { 1056 if (ReturnedOffsets.isUnknown()) { 1057 OI.setUnknown(); 1058 return; 1059 } 1060 1061 OffsetInfo MergedOI; 1062 for (auto Offset : ReturnedOffsets) { 1063 OffsetInfo TmpOI = OI; 1064 TmpOI.addToAll(Offset); 1065 MergedOI.merge(TmpOI); 1066 } 1067 OI = std::move(MergedOI); 1068 } 1069 1070 ChangeStatus setReachesReturn(const OffsetInfo &ReachedReturnedOffsets) { 1071 if (ReturnedOffsets.isUnknown()) 1072 return ChangeStatus::UNCHANGED; 1073 if (ReachedReturnedOffsets.isUnknown()) { 1074 ReturnedOffsets.setUnknown(); 1075 return ChangeStatus::CHANGED; 1076 } 1077 if (ReturnedOffsets.merge(ReachedReturnedOffsets)) 1078 return ChangeStatus::CHANGED; 1079 return ChangeStatus::UNCHANGED; 1080 } 1081 1082 bool forallInterferingAccesses( 1083 AA::RangeTy Range, 1084 function_ref<bool(const AAPointerInfo::Access &, bool)> CB) 1085 const override { 1086 return State::forallInterferingAccesses(Range, CB); 1087 } 1088 1089 bool forallInterferingAccesses( 1090 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I, 1091 bool FindInterferingWrites, bool FindInterferingReads, 1092 function_ref<bool(const Access &, bool)> UserCB, bool &HasBeenWrittenTo, 1093 AA::RangeTy &Range, 1094 function_ref<bool(const Access &)> SkipCB) const override { 1095 HasBeenWrittenTo = false; 1096 1097 SmallPtrSet<const Access *, 8> DominatingWrites; 1098 SmallVector<std::pair<const Access *, bool>, 8> InterferingAccesses; 1099 1100 Function &Scope = *I.getFunction(); 1101 bool IsKnownNoSync; 1102 bool IsAssumedNoSync = AA::hasAssumedIRAttr<Attribute::NoSync>( 1103 A, &QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL, 1104 IsKnownNoSync); 1105 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>( 1106 IRPosition::function(Scope), &QueryingAA, DepClassTy::NONE); 1107 bool AllInSameNoSyncFn = IsAssumedNoSync; 1108 bool InstIsExecutedByInitialThreadOnly = 1109 ExecDomainAA && ExecDomainAA->isExecutedByInitialThreadOnly(I); 1110 1111 // If the function is not ending in aligned barriers, we need the stores to 1112 // be in aligned barriers. The load being in one is not sufficient since the 1113 // store might be executed by a thread that disappears after, causing the 1114 // aligned barrier guarding the load to unblock and the load to read a value 1115 // that has no CFG path to the load. 1116 bool InstIsExecutedInAlignedRegion = 1117 FindInterferingReads && ExecDomainAA && 1118 ExecDomainAA->isExecutedInAlignedRegion(A, I); 1119 1120 if (InstIsExecutedInAlignedRegion || InstIsExecutedByInitialThreadOnly) 1121 A.recordDependence(*ExecDomainAA, QueryingAA, DepClassTy::OPTIONAL); 1122 1123 InformationCache &InfoCache = A.getInfoCache(); 1124 bool IsThreadLocalObj = 1125 AA::isAssumedThreadLocalObject(A, getAssociatedValue(), *this); 1126 1127 // Helper to determine if we need to consider threading, which we cannot 1128 // right now. However, if the function is (assumed) nosync or the thread 1129 // executing all instructions is the main thread only we can ignore 1130 // threading. Also, thread-local objects do not require threading reasoning. 1131 // Finally, we can ignore threading if either access is executed in an 1132 // aligned region. 1133 auto CanIgnoreThreadingForInst = [&](const Instruction &I) -> bool { 1134 if (IsThreadLocalObj || AllInSameNoSyncFn) 1135 return true; 1136 const auto *FnExecDomainAA = 1137 I.getFunction() == &Scope 1138 ? ExecDomainAA 1139 : A.lookupAAFor<AAExecutionDomain>( 1140 IRPosition::function(*I.getFunction()), &QueryingAA, 1141 DepClassTy::NONE); 1142 if (!FnExecDomainAA) 1143 return false; 1144 if (InstIsExecutedInAlignedRegion || 1145 (FindInterferingWrites && 1146 FnExecDomainAA->isExecutedInAlignedRegion(A, I))) { 1147 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL); 1148 return true; 1149 } 1150 if (InstIsExecutedByInitialThreadOnly && 1151 FnExecDomainAA->isExecutedByInitialThreadOnly(I)) { 1152 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL); 1153 return true; 1154 } 1155 return false; 1156 }; 1157 1158 // Helper to determine if the access is executed by the same thread as the 1159 // given instruction, for now it is sufficient to avoid any potential 1160 // threading effects as we cannot deal with them anyway. 1161 auto CanIgnoreThreading = [&](const Access &Acc) -> bool { 1162 return CanIgnoreThreadingForInst(*Acc.getRemoteInst()) || 1163 (Acc.getRemoteInst() != Acc.getLocalInst() && 1164 CanIgnoreThreadingForInst(*Acc.getLocalInst())); 1165 }; 1166 1167 // TODO: Use inter-procedural reachability and dominance. 1168 bool IsKnownNoRecurse; 1169 AA::hasAssumedIRAttr<Attribute::NoRecurse>( 1170 A, this, IRPosition::function(Scope), DepClassTy::OPTIONAL, 1171 IsKnownNoRecurse); 1172 1173 // TODO: Use reaching kernels from AAKernelInfo (or move it to 1174 // AAExecutionDomain) such that we allow scopes other than kernels as long 1175 // as the reaching kernels are disjoint. 1176 bool InstInKernel = A.getInfoCache().isKernel(Scope); 1177 bool ObjHasKernelLifetime = false; 1178 const bool UseDominanceReasoning = 1179 FindInterferingWrites && IsKnownNoRecurse; 1180 const DominatorTree *DT = 1181 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(Scope); 1182 1183 // Helper to check if a value has "kernel lifetime", that is it will not 1184 // outlive a GPU kernel. This is true for shared, constant, and local 1185 // globals on AMD and NVIDIA GPUs. 1186 auto HasKernelLifetime = [&](Value *V, Module &M) { 1187 if (!AA::isGPU(M)) 1188 return false; 1189 switch (AA::GPUAddressSpace(V->getType()->getPointerAddressSpace())) { 1190 case AA::GPUAddressSpace::Shared: 1191 case AA::GPUAddressSpace::Constant: 1192 case AA::GPUAddressSpace::Local: 1193 return true; 1194 default: 1195 return false; 1196 }; 1197 }; 1198 1199 // The IsLiveInCalleeCB will be used by the AA::isPotentiallyReachable query 1200 // to determine if we should look at reachability from the callee. For 1201 // certain pointers we know the lifetime and we do not have to step into the 1202 // callee to determine reachability as the pointer would be dead in the 1203 // callee. See the conditional initialization below. 1204 std::function<bool(const Function &)> IsLiveInCalleeCB; 1205 1206 if (auto *AI = dyn_cast<AllocaInst>(&getAssociatedValue())) { 1207 // If the alloca containing function is not recursive the alloca 1208 // must be dead in the callee. 1209 const Function *AIFn = AI->getFunction(); 1210 ObjHasKernelLifetime = A.getInfoCache().isKernel(*AIFn); 1211 bool IsKnownNoRecurse; 1212 if (AA::hasAssumedIRAttr<Attribute::NoRecurse>( 1213 A, this, IRPosition::function(*AIFn), DepClassTy::OPTIONAL, 1214 IsKnownNoRecurse)) { 1215 IsLiveInCalleeCB = [AIFn](const Function &Fn) { return AIFn != &Fn; }; 1216 } 1217 } else if (auto *GV = dyn_cast<GlobalValue>(&getAssociatedValue())) { 1218 // If the global has kernel lifetime we can stop if we reach a kernel 1219 // as it is "dead" in the (unknown) callees. 1220 ObjHasKernelLifetime = HasKernelLifetime(GV, *GV->getParent()); 1221 if (ObjHasKernelLifetime) 1222 IsLiveInCalleeCB = [&A](const Function &Fn) { 1223 return !A.getInfoCache().isKernel(Fn); 1224 }; 1225 } 1226 1227 // Set of accesses/instructions that will overwrite the result and are 1228 // therefore blockers in the reachability traversal. 1229 AA::InstExclusionSetTy ExclusionSet; 1230 1231 auto AccessCB = [&](const Access &Acc, bool Exact) { 1232 Function *AccScope = Acc.getRemoteInst()->getFunction(); 1233 bool AccInSameScope = AccScope == &Scope; 1234 1235 // If the object has kernel lifetime we can ignore accesses only reachable 1236 // by other kernels. For now we only skip accesses *in* other kernels. 1237 if (InstInKernel && ObjHasKernelLifetime && !AccInSameScope && 1238 A.getInfoCache().isKernel(*AccScope)) 1239 return true; 1240 1241 if (Exact && Acc.isMustAccess() && Acc.getRemoteInst() != &I) { 1242 if (Acc.isWrite() || (isa<LoadInst>(I) && Acc.isWriteOrAssumption())) 1243 ExclusionSet.insert(Acc.getRemoteInst()); 1244 } 1245 1246 if ((!FindInterferingWrites || !Acc.isWriteOrAssumption()) && 1247 (!FindInterferingReads || !Acc.isRead())) 1248 return true; 1249 1250 bool Dominates = FindInterferingWrites && DT && Exact && 1251 Acc.isMustAccess() && AccInSameScope && 1252 DT->dominates(Acc.getRemoteInst(), &I); 1253 if (Dominates) 1254 DominatingWrites.insert(&Acc); 1255 1256 // Track if all interesting accesses are in the same `nosync` function as 1257 // the given instruction. 1258 AllInSameNoSyncFn &= Acc.getRemoteInst()->getFunction() == &Scope; 1259 1260 InterferingAccesses.push_back({&Acc, Exact}); 1261 return true; 1262 }; 1263 if (!State::forallInterferingAccesses(I, AccessCB, Range)) 1264 return false; 1265 1266 HasBeenWrittenTo = !DominatingWrites.empty(); 1267 1268 // Dominating writes form a chain, find the least/lowest member. 1269 Instruction *LeastDominatingWriteInst = nullptr; 1270 for (const Access *Acc : DominatingWrites) { 1271 if (!LeastDominatingWriteInst) { 1272 LeastDominatingWriteInst = Acc->getRemoteInst(); 1273 } else if (DT->dominates(LeastDominatingWriteInst, 1274 Acc->getRemoteInst())) { 1275 LeastDominatingWriteInst = Acc->getRemoteInst(); 1276 } 1277 } 1278 1279 // Helper to determine if we can skip a specific write access. 1280 auto CanSkipAccess = [&](const Access &Acc, bool Exact) { 1281 if (SkipCB && SkipCB(Acc)) 1282 return true; 1283 if (!CanIgnoreThreading(Acc)) 1284 return false; 1285 1286 // Check read (RAW) dependences and write (WAR) dependences as necessary. 1287 // If we successfully excluded all effects we are interested in, the 1288 // access can be skipped. 1289 bool ReadChecked = !FindInterferingReads; 1290 bool WriteChecked = !FindInterferingWrites; 1291 1292 // If the instruction cannot reach the access, the former does not 1293 // interfere with what the access reads. 1294 if (!ReadChecked) { 1295 if (!AA::isPotentiallyReachable(A, I, *Acc.getRemoteInst(), QueryingAA, 1296 &ExclusionSet, IsLiveInCalleeCB)) 1297 ReadChecked = true; 1298 } 1299 // If the instruction cannot be reach from the access, the latter does not 1300 // interfere with what the instruction reads. 1301 if (!WriteChecked) { 1302 if (!AA::isPotentiallyReachable(A, *Acc.getRemoteInst(), I, QueryingAA, 1303 &ExclusionSet, IsLiveInCalleeCB)) 1304 WriteChecked = true; 1305 } 1306 1307 // If we still might be affected by the write of the access but there are 1308 // dominating writes in the function of the instruction 1309 // (HasBeenWrittenTo), we can try to reason that the access is overwritten 1310 // by them. This would have happend above if they are all in the same 1311 // function, so we only check the inter-procedural case. Effectively, we 1312 // want to show that there is no call after the dominting write that might 1313 // reach the access, and when it returns reach the instruction with the 1314 // updated value. To this end, we iterate all call sites, check if they 1315 // might reach the instruction without going through another access 1316 // (ExclusionSet) and at the same time might reach the access. However, 1317 // that is all part of AAInterFnReachability. 1318 if (!WriteChecked && HasBeenWrittenTo && 1319 Acc.getRemoteInst()->getFunction() != &Scope) { 1320 1321 const auto *FnReachabilityAA = A.getAAFor<AAInterFnReachability>( 1322 QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL); 1323 if (FnReachabilityAA) { 1324 // Without going backwards in the call tree, can we reach the access 1325 // from the least dominating write. Do not allow to pass the 1326 // instruction itself either. 1327 bool Inserted = ExclusionSet.insert(&I).second; 1328 1329 if (!FnReachabilityAA->instructionCanReach( 1330 A, *LeastDominatingWriteInst, 1331 *Acc.getRemoteInst()->getFunction(), &ExclusionSet)) 1332 WriteChecked = true; 1333 1334 if (Inserted) 1335 ExclusionSet.erase(&I); 1336 } 1337 } 1338 1339 if (ReadChecked && WriteChecked) 1340 return true; 1341 1342 if (!DT || !UseDominanceReasoning) 1343 return false; 1344 if (!DominatingWrites.count(&Acc)) 1345 return false; 1346 return LeastDominatingWriteInst != Acc.getRemoteInst(); 1347 }; 1348 1349 // Run the user callback on all accesses we cannot skip and return if 1350 // that succeeded for all or not. 1351 for (auto &It : InterferingAccesses) { 1352 if ((!AllInSameNoSyncFn && !IsThreadLocalObj && !ExecDomainAA) || 1353 !CanSkipAccess(*It.first, It.second)) { 1354 if (!UserCB(*It.first, It.second)) 1355 return false; 1356 } 1357 } 1358 return true; 1359 } 1360 1361 ChangeStatus translateAndAddStateFromCallee(Attributor &A, 1362 const AAPointerInfo &OtherAA, 1363 CallBase &CB) { 1364 using namespace AA::PointerInfo; 1365 if (!OtherAA.getState().isValidState() || !isValidState()) 1366 return indicatePessimisticFixpoint(); 1367 1368 ChangeStatus Changed = ChangeStatus::UNCHANGED; 1369 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA); 1370 bool IsByval = OtherAAImpl.getAssociatedArgument()->hasByValAttr(); 1371 Changed |= setReachesReturn(OtherAAImpl.ReturnedOffsets); 1372 1373 // Combine the accesses bin by bin. 1374 const auto &State = OtherAAImpl.getState(); 1375 for (const auto &It : State) { 1376 for (auto Index : It.getSecond()) { 1377 const auto &RAcc = State.getAccess(Index); 1378 if (IsByval && !RAcc.isRead()) 1379 continue; 1380 bool UsedAssumedInformation = false; 1381 AccessKind AK = RAcc.getKind(); 1382 auto Content = A.translateArgumentToCallSiteContent( 1383 RAcc.getContent(), CB, *this, UsedAssumedInformation); 1384 AK = AccessKind(AK & (IsByval ? AccessKind::AK_R : AccessKind::AK_RW)); 1385 AK = AccessKind(AK | (RAcc.isMayAccess() ? AK_MAY : AK_MUST)); 1386 1387 Changed |= addAccess(A, RAcc.getRanges(), CB, Content, AK, 1388 RAcc.getType(), RAcc.getRemoteInst()); 1389 } 1390 } 1391 return Changed; 1392 } 1393 1394 ChangeStatus translateAndAddState(Attributor &A, const AAPointerInfo &OtherAA, 1395 const OffsetInfo &Offsets, CallBase &CB, 1396 bool IsMustAcc) { 1397 using namespace AA::PointerInfo; 1398 if (!OtherAA.getState().isValidState() || !isValidState()) 1399 return indicatePessimisticFixpoint(); 1400 1401 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA); 1402 1403 // Combine the accesses bin by bin. 1404 ChangeStatus Changed = ChangeStatus::UNCHANGED; 1405 const auto &State = OtherAAImpl.getState(); 1406 for (const auto &It : State) { 1407 for (auto Index : It.getSecond()) { 1408 const auto &RAcc = State.getAccess(Index); 1409 if (!IsMustAcc && RAcc.isAssumption()) 1410 continue; 1411 for (auto Offset : Offsets) { 1412 auto NewRanges = Offset == AA::RangeTy::Unknown 1413 ? AA::RangeTy::getUnknown() 1414 : RAcc.getRanges(); 1415 if (!NewRanges.isUnknown()) { 1416 NewRanges.addToAllOffsets(Offset); 1417 } 1418 AccessKind AK = RAcc.getKind(); 1419 if (!IsMustAcc) 1420 AK = AccessKind((AK & ~AK_MUST) | AK_MAY); 1421 Changed |= addAccess(A, NewRanges, CB, RAcc.getContent(), AK, 1422 RAcc.getType(), RAcc.getRemoteInst()); 1423 } 1424 } 1425 } 1426 return Changed; 1427 } 1428 1429 /// Statistic tracking for all AAPointerInfo implementations. 1430 /// See AbstractAttribute::trackStatistics(). 1431 void trackPointerInfoStatistics(const IRPosition &IRP) const {} 1432 1433 /// Dump the state into \p O. 1434 void dumpState(raw_ostream &O) { 1435 for (auto &It : OffsetBins) { 1436 O << "[" << It.first.Offset << "-" << It.first.Offset + It.first.Size 1437 << "] : " << It.getSecond().size() << "\n"; 1438 for (auto AccIndex : It.getSecond()) { 1439 auto &Acc = AccessList[AccIndex]; 1440 O << " - " << Acc.getKind() << " - " << *Acc.getLocalInst() << "\n"; 1441 if (Acc.getLocalInst() != Acc.getRemoteInst()) 1442 O << " --> " << *Acc.getRemoteInst() 1443 << "\n"; 1444 if (!Acc.isWrittenValueYetUndetermined()) { 1445 if (isa_and_nonnull<Function>(Acc.getWrittenValue())) 1446 O << " - c: func " << Acc.getWrittenValue()->getName() 1447 << "\n"; 1448 else if (Acc.getWrittenValue()) 1449 O << " - c: " << *Acc.getWrittenValue() << "\n"; 1450 else 1451 O << " - c: <unknown>\n"; 1452 } 1453 } 1454 } 1455 } 1456 }; 1457 1458 struct AAPointerInfoFloating : public AAPointerInfoImpl { 1459 using AccessKind = AAPointerInfo::AccessKind; 1460 AAPointerInfoFloating(const IRPosition &IRP, Attributor &A) 1461 : AAPointerInfoImpl(IRP, A) {} 1462 1463 /// Deal with an access and signal if it was handled successfully. 1464 bool handleAccess(Attributor &A, Instruction &I, 1465 std::optional<Value *> Content, AccessKind Kind, 1466 OffsetInfo::VecTy &Offsets, ChangeStatus &Changed, 1467 Type &Ty) { 1468 using namespace AA::PointerInfo; 1469 auto Size = AA::RangeTy::Unknown; 1470 const DataLayout &DL = A.getDataLayout(); 1471 TypeSize AccessSize = DL.getTypeStoreSize(&Ty); 1472 if (!AccessSize.isScalable()) 1473 Size = AccessSize.getFixedValue(); 1474 1475 // Make a strictly ascending list of offsets as required by addAccess() 1476 SmallVector<int64_t> OffsetsSorted(Offsets.begin(), Offsets.end()); 1477 llvm::sort(OffsetsSorted); 1478 1479 VectorType *VT = dyn_cast<VectorType>(&Ty); 1480 if (!VT || VT->getElementCount().isScalable() || 1481 !Content.value_or(nullptr) || !isa<Constant>(*Content) || 1482 (*Content)->getType() != VT || 1483 DL.getTypeStoreSize(VT->getElementType()).isScalable()) { 1484 Changed = 1485 Changed | addAccess(A, {OffsetsSorted, Size}, I, Content, Kind, &Ty); 1486 } else { 1487 // Handle vector stores with constant content element-wise. 1488 // TODO: We could look for the elements or create instructions 1489 // representing them. 1490 // TODO: We need to push the Content into the range abstraction 1491 // (AA::RangeTy) to allow different content values for different 1492 // ranges. ranges. Hence, support vectors storing different values. 1493 Type *ElementType = VT->getElementType(); 1494 int64_t ElementSize = DL.getTypeStoreSize(ElementType).getFixedValue(); 1495 auto *ConstContent = cast<Constant>(*Content); 1496 Type *Int32Ty = Type::getInt32Ty(ElementType->getContext()); 1497 SmallVector<int64_t> ElementOffsets(Offsets.begin(), Offsets.end()); 1498 1499 for (int i = 0, e = VT->getElementCount().getFixedValue(); i != e; ++i) { 1500 Value *ElementContent = ConstantExpr::getExtractElement( 1501 ConstContent, ConstantInt::get(Int32Ty, i)); 1502 1503 // Add the element access. 1504 Changed = Changed | addAccess(A, {ElementOffsets, ElementSize}, I, 1505 ElementContent, Kind, ElementType); 1506 1507 // Advance the offsets for the next element. 1508 for (auto &ElementOffset : ElementOffsets) 1509 ElementOffset += ElementSize; 1510 } 1511 } 1512 return true; 1513 }; 1514 1515 /// See AbstractAttribute::updateImpl(...). 1516 ChangeStatus updateImpl(Attributor &A) override; 1517 1518 /// If the indices to \p GEP can be traced to constants, incorporate all 1519 /// of these into \p UsrOI. 1520 /// 1521 /// \return true iff \p UsrOI is updated. 1522 bool collectConstantsForGEP(Attributor &A, const DataLayout &DL, 1523 OffsetInfo &UsrOI, const OffsetInfo &PtrOI, 1524 const GEPOperator *GEP); 1525 1526 /// See AbstractAttribute::trackStatistics() 1527 void trackStatistics() const override { 1528 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition()); 1529 } 1530 }; 1531 1532 bool AAPointerInfoFloating::collectConstantsForGEP(Attributor &A, 1533 const DataLayout &DL, 1534 OffsetInfo &UsrOI, 1535 const OffsetInfo &PtrOI, 1536 const GEPOperator *GEP) { 1537 unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType()); 1538 SmallMapVector<Value *, APInt, 4> VariableOffsets; 1539 APInt ConstantOffset(BitWidth, 0); 1540 1541 assert(!UsrOI.isUnknown() && !PtrOI.isUnknown() && 1542 "Don't look for constant values if the offset has already been " 1543 "determined to be unknown."); 1544 1545 if (!GEP->collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset)) { 1546 UsrOI.setUnknown(); 1547 return true; 1548 } 1549 1550 LLVM_DEBUG(dbgs() << "[AAPointerInfo] GEP offset is " 1551 << (VariableOffsets.empty() ? "" : "not") << " constant " 1552 << *GEP << "\n"); 1553 1554 auto Union = PtrOI; 1555 Union.addToAll(ConstantOffset.getSExtValue()); 1556 1557 // Each VI in VariableOffsets has a set of potential constant values. Every 1558 // combination of elements, picked one each from these sets, is separately 1559 // added to the original set of offsets, thus resulting in more offsets. 1560 for (const auto &VI : VariableOffsets) { 1561 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>( 1562 *this, IRPosition::value(*VI.first), DepClassTy::OPTIONAL); 1563 if (!PotentialConstantsAA || !PotentialConstantsAA->isValidState()) { 1564 UsrOI.setUnknown(); 1565 return true; 1566 } 1567 1568 // UndefValue is treated as a zero, which leaves Union as is. 1569 if (PotentialConstantsAA->undefIsContained()) 1570 continue; 1571 1572 // We need at least one constant in every set to compute an actual offset. 1573 // Otherwise, we end up pessimizing AAPointerInfo by respecting offsets that 1574 // don't actually exist. In other words, the absence of constant values 1575 // implies that the operation can be assumed dead for now. 1576 auto &AssumedSet = PotentialConstantsAA->getAssumedSet(); 1577 if (AssumedSet.empty()) 1578 return false; 1579 1580 OffsetInfo Product; 1581 for (const auto &ConstOffset : AssumedSet) { 1582 auto CopyPerOffset = Union; 1583 CopyPerOffset.addToAll(ConstOffset.getSExtValue() * 1584 VI.second.getZExtValue()); 1585 Product.merge(CopyPerOffset); 1586 } 1587 Union = Product; 1588 } 1589 1590 UsrOI = std::move(Union); 1591 return true; 1592 } 1593 1594 ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) { 1595 using namespace AA::PointerInfo; 1596 ChangeStatus Changed = ChangeStatus::UNCHANGED; 1597 const DataLayout &DL = A.getDataLayout(); 1598 Value &AssociatedValue = getAssociatedValue(); 1599 1600 DenseMap<Value *, OffsetInfo> OffsetInfoMap; 1601 OffsetInfoMap[&AssociatedValue].insert(0); 1602 1603 auto HandlePassthroughUser = [&](Value *Usr, Value *CurPtr, bool &Follow) { 1604 // One does not simply walk into a map and assign a reference to a possibly 1605 // new location. That can cause an invalidation before the assignment 1606 // happens, like so: 1607 // 1608 // OffsetInfoMap[Usr] = OffsetInfoMap[CurPtr]; /* bad idea! */ 1609 // 1610 // The RHS is a reference that may be invalidated by an insertion caused by 1611 // the LHS. So we ensure that the side-effect of the LHS happens first. 1612 1613 assert(OffsetInfoMap.contains(CurPtr) && 1614 "CurPtr does not exist in the map!"); 1615 1616 auto &UsrOI = OffsetInfoMap[Usr]; 1617 auto &PtrOI = OffsetInfoMap[CurPtr]; 1618 assert(!PtrOI.isUnassigned() && 1619 "Cannot pass through if the input Ptr was not visited!"); 1620 UsrOI.merge(PtrOI); 1621 Follow = true; 1622 return true; 1623 }; 1624 1625 auto UsePred = [&](const Use &U, bool &Follow) -> bool { 1626 Value *CurPtr = U.get(); 1627 User *Usr = U.getUser(); 1628 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Analyze " << *CurPtr << " in " << *Usr 1629 << "\n"); 1630 assert(OffsetInfoMap.count(CurPtr) && 1631 "The current pointer offset should have been seeded!"); 1632 assert(!OffsetInfoMap[CurPtr].isUnassigned() && 1633 "Current pointer should be assigned"); 1634 1635 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Usr)) { 1636 if (CE->isCast()) 1637 return HandlePassthroughUser(Usr, CurPtr, Follow); 1638 if (!isa<GEPOperator>(CE)) { 1639 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled constant user " << *CE 1640 << "\n"); 1641 return false; 1642 } 1643 } 1644 if (auto *GEP = dyn_cast<GEPOperator>(Usr)) { 1645 // Note the order here, the Usr access might change the map, CurPtr is 1646 // already in it though. 1647 auto &UsrOI = OffsetInfoMap[Usr]; 1648 auto &PtrOI = OffsetInfoMap[CurPtr]; 1649 1650 if (UsrOI.isUnknown()) 1651 return true; 1652 1653 if (PtrOI.isUnknown()) { 1654 Follow = true; 1655 UsrOI.setUnknown(); 1656 return true; 1657 } 1658 1659 Follow = collectConstantsForGEP(A, DL, UsrOI, PtrOI, GEP); 1660 return true; 1661 } 1662 if (isa<PtrToIntInst>(Usr)) 1663 return false; 1664 if (isa<CastInst>(Usr) || isa<SelectInst>(Usr)) 1665 return HandlePassthroughUser(Usr, CurPtr, Follow); 1666 // Returns are allowed if they are in the associated functions. Users can 1667 // then check the call site return. Returns from other functions can't be 1668 // tracked and are cause for invalidation. 1669 if (auto *RI = dyn_cast<ReturnInst>(Usr)) { 1670 if (RI->getFunction() == getAssociatedFunction()) { 1671 auto &PtrOI = OffsetInfoMap[CurPtr]; 1672 Changed |= setReachesReturn(PtrOI); 1673 return true; 1674 } 1675 return false; 1676 } 1677 1678 // For PHIs we need to take care of the recurrence explicitly as the value 1679 // might change while we iterate through a loop. For now, we give up if 1680 // the PHI is not invariant. 1681 if (auto *PHI = dyn_cast<PHINode>(Usr)) { 1682 // Note the order here, the Usr access might change the map, CurPtr is 1683 // already in it though. 1684 auto [PhiIt, IsFirstPHIUser] = OffsetInfoMap.try_emplace(PHI); 1685 auto &UsrOI = PhiIt->second; 1686 auto &PtrOI = OffsetInfoMap[CurPtr]; 1687 1688 // Check if the PHI operand has already an unknown offset as we can't 1689 // improve on that anymore. 1690 if (PtrOI.isUnknown()) { 1691 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand offset unknown " 1692 << *CurPtr << " in " << *PHI << "\n"); 1693 Follow = !UsrOI.isUnknown(); 1694 UsrOI.setUnknown(); 1695 return true; 1696 } 1697 1698 // Check if the PHI is invariant (so far). 1699 if (UsrOI == PtrOI) { 1700 assert(!PtrOI.isUnassigned() && 1701 "Cannot assign if the current Ptr was not visited!"); 1702 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant (so far)"); 1703 return true; 1704 } 1705 1706 // Check if the PHI operand can be traced back to AssociatedValue. 1707 APInt Offset( 1708 DL.getIndexSizeInBits(CurPtr->getType()->getPointerAddressSpace()), 1709 0); 1710 Value *CurPtrBase = CurPtr->stripAndAccumulateConstantOffsets( 1711 DL, Offset, /* AllowNonInbounds */ true); 1712 auto It = OffsetInfoMap.find(CurPtrBase); 1713 if (It == OffsetInfoMap.end()) { 1714 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand is too complex " 1715 << *CurPtr << " in " << *PHI 1716 << " (base: " << *CurPtrBase << ")\n"); 1717 UsrOI.setUnknown(); 1718 Follow = true; 1719 return true; 1720 } 1721 1722 // Check if the PHI operand is not dependent on the PHI itself. Every 1723 // recurrence is a cyclic net of PHIs in the data flow, and has an 1724 // equivalent Cycle in the control flow. One of those PHIs must be in the 1725 // header of that control flow Cycle. This is independent of the choice of 1726 // Cycles reported by CycleInfo. It is sufficient to check the PHIs in 1727 // every Cycle header; if such a node is marked unknown, this will 1728 // eventually propagate through the whole net of PHIs in the recurrence. 1729 const auto *CI = 1730 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>( 1731 *PHI->getFunction()); 1732 if (mayBeInCycle(CI, cast<Instruction>(Usr), /* HeaderOnly */ true)) { 1733 auto BaseOI = It->getSecond(); 1734 BaseOI.addToAll(Offset.getZExtValue()); 1735 if (IsFirstPHIUser || BaseOI == UsrOI) { 1736 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant " << *CurPtr 1737 << " in " << *Usr << "\n"); 1738 return HandlePassthroughUser(Usr, CurPtr, Follow); 1739 } 1740 1741 LLVM_DEBUG( 1742 dbgs() << "[AAPointerInfo] PHI operand pointer offset mismatch " 1743 << *CurPtr << " in " << *PHI << "\n"); 1744 UsrOI.setUnknown(); 1745 Follow = true; 1746 return true; 1747 } 1748 1749 UsrOI.merge(PtrOI); 1750 Follow = true; 1751 return true; 1752 } 1753 1754 if (auto *LoadI = dyn_cast<LoadInst>(Usr)) { 1755 // If the access is to a pointer that may or may not be the associated 1756 // value, e.g. due to a PHI, we cannot assume it will be read. 1757 AccessKind AK = AccessKind::AK_R; 1758 if (getUnderlyingObject(CurPtr) == &AssociatedValue) 1759 AK = AccessKind(AK | AccessKind::AK_MUST); 1760 else 1761 AK = AccessKind(AK | AccessKind::AK_MAY); 1762 if (!handleAccess(A, *LoadI, /* Content */ nullptr, AK, 1763 OffsetInfoMap[CurPtr].Offsets, Changed, 1764 *LoadI->getType())) 1765 return false; 1766 1767 auto IsAssumption = [](Instruction &I) { 1768 if (auto *II = dyn_cast<IntrinsicInst>(&I)) 1769 return II->isAssumeLikeIntrinsic(); 1770 return false; 1771 }; 1772 1773 auto IsImpactedInRange = [&](Instruction *FromI, Instruction *ToI) { 1774 // Check if the assumption and the load are executed together without 1775 // memory modification. 1776 do { 1777 if (FromI->mayWriteToMemory() && !IsAssumption(*FromI)) 1778 return true; 1779 FromI = FromI->getNextNonDebugInstruction(); 1780 } while (FromI && FromI != ToI); 1781 return false; 1782 }; 1783 1784 BasicBlock *BB = LoadI->getParent(); 1785 auto IsValidAssume = [&](IntrinsicInst &IntrI) { 1786 if (IntrI.getIntrinsicID() != Intrinsic::assume) 1787 return false; 1788 BasicBlock *IntrBB = IntrI.getParent(); 1789 if (IntrI.getParent() == BB) { 1790 if (IsImpactedInRange(LoadI->getNextNonDebugInstruction(), &IntrI)) 1791 return false; 1792 } else { 1793 auto PredIt = pred_begin(IntrBB); 1794 if (PredIt == pred_end(IntrBB)) 1795 return false; 1796 if ((*PredIt) != BB) 1797 return false; 1798 if (++PredIt != pred_end(IntrBB)) 1799 return false; 1800 for (auto *SuccBB : successors(BB)) { 1801 if (SuccBB == IntrBB) 1802 continue; 1803 if (isa<UnreachableInst>(SuccBB->getTerminator())) 1804 continue; 1805 return false; 1806 } 1807 if (IsImpactedInRange(LoadI->getNextNonDebugInstruction(), 1808 BB->getTerminator())) 1809 return false; 1810 if (IsImpactedInRange(&IntrBB->front(), &IntrI)) 1811 return false; 1812 } 1813 return true; 1814 }; 1815 1816 std::pair<Value *, IntrinsicInst *> Assumption; 1817 for (const Use &LoadU : LoadI->uses()) { 1818 if (auto *CmpI = dyn_cast<CmpInst>(LoadU.getUser())) { 1819 if (!CmpI->isEquality() || !CmpI->isTrueWhenEqual()) 1820 continue; 1821 for (const Use &CmpU : CmpI->uses()) { 1822 if (auto *IntrI = dyn_cast<IntrinsicInst>(CmpU.getUser())) { 1823 if (!IsValidAssume(*IntrI)) 1824 continue; 1825 int Idx = CmpI->getOperandUse(0) == LoadU; 1826 Assumption = {CmpI->getOperand(Idx), IntrI}; 1827 break; 1828 } 1829 } 1830 } 1831 if (Assumption.first) 1832 break; 1833 } 1834 1835 // Check if we found an assumption associated with this load. 1836 if (!Assumption.first || !Assumption.second) 1837 return true; 1838 1839 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Assumption found " 1840 << *Assumption.second << ": " << *LoadI 1841 << " == " << *Assumption.first << "\n"); 1842 bool UsedAssumedInformation = false; 1843 std::optional<Value *> Content = nullptr; 1844 if (Assumption.first) 1845 Content = 1846 A.getAssumedSimplified(*Assumption.first, *this, 1847 UsedAssumedInformation, AA::Interprocedural); 1848 return handleAccess( 1849 A, *Assumption.second, Content, AccessKind::AK_ASSUMPTION, 1850 OffsetInfoMap[CurPtr].Offsets, Changed, *LoadI->getType()); 1851 } 1852 1853 auto HandleStoreLike = [&](Instruction &I, Value *ValueOp, Type &ValueTy, 1854 ArrayRef<Value *> OtherOps, AccessKind AK) { 1855 for (auto *OtherOp : OtherOps) { 1856 if (OtherOp == CurPtr) { 1857 LLVM_DEBUG( 1858 dbgs() 1859 << "[AAPointerInfo] Escaping use in store like instruction " << I 1860 << "\n"); 1861 return false; 1862 } 1863 } 1864 1865 // If the access is to a pointer that may or may not be the associated 1866 // value, e.g. due to a PHI, we cannot assume it will be written. 1867 if (getUnderlyingObject(CurPtr) == &AssociatedValue) 1868 AK = AccessKind(AK | AccessKind::AK_MUST); 1869 else 1870 AK = AccessKind(AK | AccessKind::AK_MAY); 1871 bool UsedAssumedInformation = false; 1872 std::optional<Value *> Content = nullptr; 1873 if (ValueOp) 1874 Content = A.getAssumedSimplified( 1875 *ValueOp, *this, UsedAssumedInformation, AA::Interprocedural); 1876 return handleAccess(A, I, Content, AK, OffsetInfoMap[CurPtr].Offsets, 1877 Changed, ValueTy); 1878 }; 1879 1880 if (auto *StoreI = dyn_cast<StoreInst>(Usr)) 1881 return HandleStoreLike(*StoreI, StoreI->getValueOperand(), 1882 *StoreI->getValueOperand()->getType(), 1883 {StoreI->getValueOperand()}, AccessKind::AK_W); 1884 if (auto *RMWI = dyn_cast<AtomicRMWInst>(Usr)) 1885 return HandleStoreLike(*RMWI, nullptr, *RMWI->getValOperand()->getType(), 1886 {RMWI->getValOperand()}, AccessKind::AK_RW); 1887 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(Usr)) 1888 return HandleStoreLike( 1889 *CXI, nullptr, *CXI->getNewValOperand()->getType(), 1890 {CXI->getCompareOperand(), CXI->getNewValOperand()}, 1891 AccessKind::AK_RW); 1892 1893 if (auto *CB = dyn_cast<CallBase>(Usr)) { 1894 if (CB->isLifetimeStartOrEnd()) 1895 return true; 1896 const auto *TLI = 1897 A.getInfoCache().getTargetLibraryInfoForFunction(*CB->getFunction()); 1898 if (getFreedOperand(CB, TLI) == U) 1899 return true; 1900 if (CB->isArgOperand(&U)) { 1901 unsigned ArgNo = CB->getArgOperandNo(&U); 1902 const auto *CSArgPI = A.getAAFor<AAPointerInfo>( 1903 *this, IRPosition::callsite_argument(*CB, ArgNo), 1904 DepClassTy::REQUIRED); 1905 if (!CSArgPI) 1906 return false; 1907 bool IsArgMustAcc = (getUnderlyingObject(CurPtr) == &AssociatedValue); 1908 Changed = translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB, 1909 IsArgMustAcc) | 1910 Changed; 1911 if (!CSArgPI->reachesReturn()) 1912 return isValidState(); 1913 1914 Function *Callee = CB->getCalledFunction(); 1915 if (!Callee || Callee->arg_size() <= ArgNo) 1916 return false; 1917 bool UsedAssumedInformation = false; 1918 auto ReturnedValue = A.getAssumedSimplified( 1919 IRPosition::returned(*Callee), *this, UsedAssumedInformation, 1920 AA::ValueScope::Intraprocedural); 1921 auto *ReturnedArg = 1922 dyn_cast_or_null<Argument>(ReturnedValue.value_or(nullptr)); 1923 auto *Arg = Callee->getArg(ArgNo); 1924 if (ReturnedArg && Arg != ReturnedArg) 1925 return true; 1926 bool IsRetMustAcc = IsArgMustAcc && (ReturnedArg == Arg); 1927 const auto *CSRetPI = A.getAAFor<AAPointerInfo>( 1928 *this, IRPosition::callsite_returned(*CB), DepClassTy::REQUIRED); 1929 if (!CSRetPI) 1930 return false; 1931 OffsetInfo OI = OffsetInfoMap[CurPtr]; 1932 CSArgPI->addReturnedOffsetsTo(OI); 1933 Changed = 1934 translateAndAddState(A, *CSRetPI, OI, *CB, IsRetMustAcc) | Changed; 1935 return isValidState(); 1936 } 1937 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB 1938 << "\n"); 1939 return false; 1940 } 1941 1942 LLVM_DEBUG(dbgs() << "[AAPointerInfo] User not handled " << *Usr << "\n"); 1943 return false; 1944 }; 1945 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) { 1946 assert(OffsetInfoMap.count(OldU) && "Old use should be known already!"); 1947 assert(!OffsetInfoMap[OldU].isUnassigned() && "Old use should be assinged"); 1948 if (OffsetInfoMap.count(NewU)) { 1949 LLVM_DEBUG({ 1950 if (!(OffsetInfoMap[NewU] == OffsetInfoMap[OldU])) { 1951 dbgs() << "[AAPointerInfo] Equivalent use callback failed: " 1952 << OffsetInfoMap[NewU] << " vs " << OffsetInfoMap[OldU] 1953 << "\n"; 1954 } 1955 }); 1956 return OffsetInfoMap[NewU] == OffsetInfoMap[OldU]; 1957 } 1958 bool Unused; 1959 return HandlePassthroughUser(NewU.get(), OldU.get(), Unused); 1960 }; 1961 if (!A.checkForAllUses(UsePred, *this, AssociatedValue, 1962 /* CheckBBLivenessOnly */ true, DepClassTy::OPTIONAL, 1963 /* IgnoreDroppableUses */ true, EquivalentUseCB)) { 1964 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Check for all uses failed, abort!\n"); 1965 return indicatePessimisticFixpoint(); 1966 } 1967 1968 LLVM_DEBUG({ 1969 dbgs() << "Accesses by bin after update:\n"; 1970 dumpState(dbgs()); 1971 }); 1972 1973 return Changed; 1974 } 1975 1976 struct AAPointerInfoReturned final : AAPointerInfoImpl { 1977 AAPointerInfoReturned(const IRPosition &IRP, Attributor &A) 1978 : AAPointerInfoImpl(IRP, A) {} 1979 1980 /// See AbstractAttribute::updateImpl(...). 1981 ChangeStatus updateImpl(Attributor &A) override { 1982 return indicatePessimisticFixpoint(); 1983 } 1984 1985 /// See AbstractAttribute::trackStatistics() 1986 void trackStatistics() const override { 1987 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition()); 1988 } 1989 }; 1990 1991 struct AAPointerInfoArgument final : AAPointerInfoFloating { 1992 AAPointerInfoArgument(const IRPosition &IRP, Attributor &A) 1993 : AAPointerInfoFloating(IRP, A) {} 1994 1995 /// See AbstractAttribute::trackStatistics() 1996 void trackStatistics() const override { 1997 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition()); 1998 } 1999 }; 2000 2001 struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating { 2002 AAPointerInfoCallSiteArgument(const IRPosition &IRP, Attributor &A) 2003 : AAPointerInfoFloating(IRP, A) {} 2004 2005 /// See AbstractAttribute::updateImpl(...). 2006 ChangeStatus updateImpl(Attributor &A) override { 2007 using namespace AA::PointerInfo; 2008 // We handle memory intrinsics explicitly, at least the first (= 2009 // destination) and second (=source) arguments as we know how they are 2010 // accessed. 2011 if (auto *MI = dyn_cast_or_null<MemIntrinsic>(getCtxI())) { 2012 ConstantInt *Length = dyn_cast<ConstantInt>(MI->getLength()); 2013 int64_t LengthVal = AA::RangeTy::Unknown; 2014 if (Length) 2015 LengthVal = Length->getSExtValue(); 2016 unsigned ArgNo = getIRPosition().getCallSiteArgNo(); 2017 ChangeStatus Changed = ChangeStatus::UNCHANGED; 2018 if (ArgNo > 1) { 2019 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled memory intrinsic " 2020 << *MI << "\n"); 2021 return indicatePessimisticFixpoint(); 2022 } else { 2023 auto Kind = 2024 ArgNo == 0 ? AccessKind::AK_MUST_WRITE : AccessKind::AK_MUST_READ; 2025 Changed = 2026 Changed | addAccess(A, {0, LengthVal}, *MI, nullptr, Kind, nullptr); 2027 } 2028 LLVM_DEBUG({ 2029 dbgs() << "Accesses by bin after update:\n"; 2030 dumpState(dbgs()); 2031 }); 2032 2033 return Changed; 2034 } 2035 2036 // TODO: Once we have call site specific value information we can provide 2037 // call site specific liveness information and then it makes 2038 // sense to specialize attributes for call sites arguments instead of 2039 // redirecting requests to the callee argument. 2040 Argument *Arg = getAssociatedArgument(); 2041 if (Arg) { 2042 const IRPosition &ArgPos = IRPosition::argument(*Arg); 2043 auto *ArgAA = 2044 A.getAAFor<AAPointerInfo>(*this, ArgPos, DepClassTy::REQUIRED); 2045 if (ArgAA && ArgAA->getState().isValidState()) 2046 return translateAndAddStateFromCallee(A, *ArgAA, 2047 *cast<CallBase>(getCtxI())); 2048 if (!Arg->getParent()->isDeclaration()) 2049 return indicatePessimisticFixpoint(); 2050 } 2051 2052 bool IsKnownNoCapture; 2053 if (!AA::hasAssumedIRAttr<Attribute::Captures>( 2054 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoCapture)) 2055 return indicatePessimisticFixpoint(); 2056 2057 bool IsKnown = false; 2058 if (AA::isAssumedReadNone(A, getIRPosition(), *this, IsKnown)) 2059 return ChangeStatus::UNCHANGED; 2060 bool ReadOnly = AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown); 2061 auto Kind = 2062 ReadOnly ? AccessKind::AK_MAY_READ : AccessKind::AK_MAY_READ_WRITE; 2063 return addAccess(A, AA::RangeTy::getUnknown(), *getCtxI(), nullptr, Kind, 2064 nullptr); 2065 } 2066 2067 /// See AbstractAttribute::trackStatistics() 2068 void trackStatistics() const override { 2069 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition()); 2070 } 2071 }; 2072 2073 struct AAPointerInfoCallSiteReturned final : AAPointerInfoFloating { 2074 AAPointerInfoCallSiteReturned(const IRPosition &IRP, Attributor &A) 2075 : AAPointerInfoFloating(IRP, A) {} 2076 2077 /// See AbstractAttribute::trackStatistics() 2078 void trackStatistics() const override { 2079 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition()); 2080 } 2081 }; 2082 } // namespace 2083 2084 /// -----------------------NoUnwind Function Attribute-------------------------- 2085 2086 namespace { 2087 struct AANoUnwindImpl : AANoUnwind { 2088 AANoUnwindImpl(const IRPosition &IRP, Attributor &A) : AANoUnwind(IRP, A) {} 2089 2090 /// See AbstractAttribute::initialize(...). 2091 void initialize(Attributor &A) override { 2092 bool IsKnown; 2093 assert(!AA::hasAssumedIRAttr<Attribute::NoUnwind>( 2094 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown)); 2095 (void)IsKnown; 2096 } 2097 2098 const std::string getAsStr(Attributor *A) const override { 2099 return getAssumed() ? "nounwind" : "may-unwind"; 2100 } 2101 2102 /// See AbstractAttribute::updateImpl(...). 2103 ChangeStatus updateImpl(Attributor &A) override { 2104 auto Opcodes = { 2105 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr, 2106 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet, 2107 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume}; 2108 2109 auto CheckForNoUnwind = [&](Instruction &I) { 2110 if (!I.mayThrow(/* IncludePhaseOneUnwind */ true)) 2111 return true; 2112 2113 if (const auto *CB = dyn_cast<CallBase>(&I)) { 2114 bool IsKnownNoUnwind; 2115 return AA::hasAssumedIRAttr<Attribute::NoUnwind>( 2116 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED, 2117 IsKnownNoUnwind); 2118 } 2119 return false; 2120 }; 2121 2122 bool UsedAssumedInformation = false; 2123 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes, 2124 UsedAssumedInformation)) 2125 return indicatePessimisticFixpoint(); 2126 2127 return ChangeStatus::UNCHANGED; 2128 } 2129 }; 2130 2131 struct AANoUnwindFunction final : public AANoUnwindImpl { 2132 AANoUnwindFunction(const IRPosition &IRP, Attributor &A) 2133 : AANoUnwindImpl(IRP, A) {} 2134 2135 /// See AbstractAttribute::trackStatistics() 2136 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) } 2137 }; 2138 2139 /// NoUnwind attribute deduction for a call sites. 2140 struct AANoUnwindCallSite final 2141 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl> { 2142 AANoUnwindCallSite(const IRPosition &IRP, Attributor &A) 2143 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl>(IRP, A) {} 2144 2145 /// See AbstractAttribute::trackStatistics() 2146 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); } 2147 }; 2148 } // namespace 2149 2150 /// ------------------------ NoSync Function Attribute ------------------------- 2151 2152 bool AANoSync::isAlignedBarrier(const CallBase &CB, bool ExecutedAligned) { 2153 switch (CB.getIntrinsicID()) { 2154 case Intrinsic::nvvm_barrier_cta_sync_aligned_all: 2155 case Intrinsic::nvvm_barrier_cta_sync_aligned_count: 2156 case Intrinsic::nvvm_barrier0_and: 2157 case Intrinsic::nvvm_barrier0_or: 2158 case Intrinsic::nvvm_barrier0_popc: 2159 return true; 2160 case Intrinsic::amdgcn_s_barrier: 2161 if (ExecutedAligned) 2162 return true; 2163 break; 2164 default: 2165 break; 2166 } 2167 return hasAssumption(CB, KnownAssumptionString("ompx_aligned_barrier")); 2168 } 2169 2170 bool AANoSync::isNonRelaxedAtomic(const Instruction *I) { 2171 if (!I->isAtomic()) 2172 return false; 2173 2174 if (auto *FI = dyn_cast<FenceInst>(I)) 2175 // All legal orderings for fence are stronger than monotonic. 2176 return FI->getSyncScopeID() != SyncScope::SingleThread; 2177 if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) { 2178 // Unordered is not a legal ordering for cmpxchg. 2179 return (AI->getSuccessOrdering() != AtomicOrdering::Monotonic || 2180 AI->getFailureOrdering() != AtomicOrdering::Monotonic); 2181 } 2182 2183 AtomicOrdering Ordering; 2184 switch (I->getOpcode()) { 2185 case Instruction::AtomicRMW: 2186 Ordering = cast<AtomicRMWInst>(I)->getOrdering(); 2187 break; 2188 case Instruction::Store: 2189 Ordering = cast<StoreInst>(I)->getOrdering(); 2190 break; 2191 case Instruction::Load: 2192 Ordering = cast<LoadInst>(I)->getOrdering(); 2193 break; 2194 default: 2195 llvm_unreachable( 2196 "New atomic operations need to be known in the attributor."); 2197 } 2198 2199 return (Ordering != AtomicOrdering::Unordered && 2200 Ordering != AtomicOrdering::Monotonic); 2201 } 2202 2203 /// Return true if this intrinsic is nosync. This is only used for intrinsics 2204 /// which would be nosync except that they have a volatile flag. All other 2205 /// intrinsics are simply annotated with the nosync attribute in Intrinsics.td. 2206 bool AANoSync::isNoSyncIntrinsic(const Instruction *I) { 2207 if (auto *MI = dyn_cast<MemIntrinsic>(I)) 2208 return !MI->isVolatile(); 2209 return false; 2210 } 2211 2212 namespace { 2213 struct AANoSyncImpl : AANoSync { 2214 AANoSyncImpl(const IRPosition &IRP, Attributor &A) : AANoSync(IRP, A) {} 2215 2216 /// See AbstractAttribute::initialize(...). 2217 void initialize(Attributor &A) override { 2218 bool IsKnown; 2219 assert(!AA::hasAssumedIRAttr<Attribute::NoSync>(A, nullptr, getIRPosition(), 2220 DepClassTy::NONE, IsKnown)); 2221 (void)IsKnown; 2222 } 2223 2224 const std::string getAsStr(Attributor *A) const override { 2225 return getAssumed() ? "nosync" : "may-sync"; 2226 } 2227 2228 /// See AbstractAttribute::updateImpl(...). 2229 ChangeStatus updateImpl(Attributor &A) override; 2230 }; 2231 2232 ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) { 2233 2234 auto CheckRWInstForNoSync = [&](Instruction &I) { 2235 return AA::isNoSyncInst(A, I, *this); 2236 }; 2237 2238 auto CheckForNoSync = [&](Instruction &I) { 2239 // At this point we handled all read/write effects and they are all 2240 // nosync, so they can be skipped. 2241 if (I.mayReadOrWriteMemory()) 2242 return true; 2243 2244 bool IsKnown; 2245 CallBase &CB = cast<CallBase>(I); 2246 if (AA::hasAssumedIRAttr<Attribute::NoSync>( 2247 A, this, IRPosition::callsite_function(CB), DepClassTy::OPTIONAL, 2248 IsKnown)) 2249 return true; 2250 2251 // non-convergent and readnone imply nosync. 2252 return !CB.isConvergent(); 2253 }; 2254 2255 bool UsedAssumedInformation = false; 2256 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this, 2257 UsedAssumedInformation) || 2258 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this, 2259 UsedAssumedInformation)) 2260 return indicatePessimisticFixpoint(); 2261 2262 return ChangeStatus::UNCHANGED; 2263 } 2264 2265 struct AANoSyncFunction final : public AANoSyncImpl { 2266 AANoSyncFunction(const IRPosition &IRP, Attributor &A) 2267 : AANoSyncImpl(IRP, A) {} 2268 2269 /// See AbstractAttribute::trackStatistics() 2270 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) } 2271 }; 2272 2273 /// NoSync attribute deduction for a call sites. 2274 struct AANoSyncCallSite final : AACalleeToCallSite<AANoSync, AANoSyncImpl> { 2275 AANoSyncCallSite(const IRPosition &IRP, Attributor &A) 2276 : AACalleeToCallSite<AANoSync, AANoSyncImpl>(IRP, A) {} 2277 2278 /// See AbstractAttribute::trackStatistics() 2279 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); } 2280 }; 2281 } // namespace 2282 2283 /// ------------------------ No-Free Attributes ---------------------------- 2284 2285 namespace { 2286 struct AANoFreeImpl : public AANoFree { 2287 AANoFreeImpl(const IRPosition &IRP, Attributor &A) : AANoFree(IRP, A) {} 2288 2289 /// See AbstractAttribute::initialize(...). 2290 void initialize(Attributor &A) override { 2291 bool IsKnown; 2292 assert(!AA::hasAssumedIRAttr<Attribute::NoFree>(A, nullptr, getIRPosition(), 2293 DepClassTy::NONE, IsKnown)); 2294 (void)IsKnown; 2295 } 2296 2297 /// See AbstractAttribute::updateImpl(...). 2298 ChangeStatus updateImpl(Attributor &A) override { 2299 auto CheckForNoFree = [&](Instruction &I) { 2300 bool IsKnown; 2301 return AA::hasAssumedIRAttr<Attribute::NoFree>( 2302 A, this, IRPosition::callsite_function(cast<CallBase>(I)), 2303 DepClassTy::REQUIRED, IsKnown); 2304 }; 2305 2306 bool UsedAssumedInformation = false; 2307 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this, 2308 UsedAssumedInformation)) 2309 return indicatePessimisticFixpoint(); 2310 return ChangeStatus::UNCHANGED; 2311 } 2312 2313 /// See AbstractAttribute::getAsStr(). 2314 const std::string getAsStr(Attributor *A) const override { 2315 return getAssumed() ? "nofree" : "may-free"; 2316 } 2317 }; 2318 2319 struct AANoFreeFunction final : public AANoFreeImpl { 2320 AANoFreeFunction(const IRPosition &IRP, Attributor &A) 2321 : AANoFreeImpl(IRP, A) {} 2322 2323 /// See AbstractAttribute::trackStatistics() 2324 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) } 2325 }; 2326 2327 /// NoFree attribute deduction for a call sites. 2328 struct AANoFreeCallSite final : AACalleeToCallSite<AANoFree, AANoFreeImpl> { 2329 AANoFreeCallSite(const IRPosition &IRP, Attributor &A) 2330 : AACalleeToCallSite<AANoFree, AANoFreeImpl>(IRP, A) {} 2331 2332 /// See AbstractAttribute::trackStatistics() 2333 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); } 2334 }; 2335 2336 /// NoFree attribute for floating values. 2337 struct AANoFreeFloating : AANoFreeImpl { 2338 AANoFreeFloating(const IRPosition &IRP, Attributor &A) 2339 : AANoFreeImpl(IRP, A) {} 2340 2341 /// See AbstractAttribute::trackStatistics() 2342 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)} 2343 2344 /// See Abstract Attribute::updateImpl(...). 2345 ChangeStatus updateImpl(Attributor &A) override { 2346 const IRPosition &IRP = getIRPosition(); 2347 2348 bool IsKnown; 2349 if (AA::hasAssumedIRAttr<Attribute::NoFree>(A, this, 2350 IRPosition::function_scope(IRP), 2351 DepClassTy::OPTIONAL, IsKnown)) 2352 return ChangeStatus::UNCHANGED; 2353 2354 Value &AssociatedValue = getIRPosition().getAssociatedValue(); 2355 auto Pred = [&](const Use &U, bool &Follow) -> bool { 2356 Instruction *UserI = cast<Instruction>(U.getUser()); 2357 if (auto *CB = dyn_cast<CallBase>(UserI)) { 2358 if (CB->isBundleOperand(&U)) 2359 return false; 2360 if (!CB->isArgOperand(&U)) 2361 return true; 2362 unsigned ArgNo = CB->getArgOperandNo(&U); 2363 2364 bool IsKnown; 2365 return AA::hasAssumedIRAttr<Attribute::NoFree>( 2366 A, this, IRPosition::callsite_argument(*CB, ArgNo), 2367 DepClassTy::REQUIRED, IsKnown); 2368 } 2369 2370 if (isa<GetElementPtrInst>(UserI) || isa<PHINode>(UserI) || 2371 isa<SelectInst>(UserI)) { 2372 Follow = true; 2373 return true; 2374 } 2375 if (isa<StoreInst>(UserI) || isa<LoadInst>(UserI)) 2376 return true; 2377 2378 if (isa<ReturnInst>(UserI) && getIRPosition().isArgumentPosition()) 2379 return true; 2380 2381 // Unknown user. 2382 return false; 2383 }; 2384 if (!A.checkForAllUses(Pred, *this, AssociatedValue)) 2385 return indicatePessimisticFixpoint(); 2386 2387 return ChangeStatus::UNCHANGED; 2388 } 2389 }; 2390 2391 /// NoFree attribute for a call site argument. 2392 struct AANoFreeArgument final : AANoFreeFloating { 2393 AANoFreeArgument(const IRPosition &IRP, Attributor &A) 2394 : AANoFreeFloating(IRP, A) {} 2395 2396 /// See AbstractAttribute::trackStatistics() 2397 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) } 2398 }; 2399 2400 /// NoFree attribute for call site arguments. 2401 struct AANoFreeCallSiteArgument final : AANoFreeFloating { 2402 AANoFreeCallSiteArgument(const IRPosition &IRP, Attributor &A) 2403 : AANoFreeFloating(IRP, A) {} 2404 2405 /// See AbstractAttribute::updateImpl(...). 2406 ChangeStatus updateImpl(Attributor &A) override { 2407 // TODO: Once we have call site specific value information we can provide 2408 // call site specific liveness information and then it makes 2409 // sense to specialize attributes for call sites arguments instead of 2410 // redirecting requests to the callee argument. 2411 Argument *Arg = getAssociatedArgument(); 2412 if (!Arg) 2413 return indicatePessimisticFixpoint(); 2414 const IRPosition &ArgPos = IRPosition::argument(*Arg); 2415 bool IsKnown; 2416 if (AA::hasAssumedIRAttr<Attribute::NoFree>(A, this, ArgPos, 2417 DepClassTy::REQUIRED, IsKnown)) 2418 return ChangeStatus::UNCHANGED; 2419 return indicatePessimisticFixpoint(); 2420 } 2421 2422 /// See AbstractAttribute::trackStatistics() 2423 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nofree) }; 2424 }; 2425 2426 /// NoFree attribute for function return value. 2427 struct AANoFreeReturned final : AANoFreeFloating { 2428 AANoFreeReturned(const IRPosition &IRP, Attributor &A) 2429 : AANoFreeFloating(IRP, A) { 2430 llvm_unreachable("NoFree is not applicable to function returns!"); 2431 } 2432 2433 /// See AbstractAttribute::initialize(...). 2434 void initialize(Attributor &A) override { 2435 llvm_unreachable("NoFree is not applicable to function returns!"); 2436 } 2437 2438 /// See AbstractAttribute::updateImpl(...). 2439 ChangeStatus updateImpl(Attributor &A) override { 2440 llvm_unreachable("NoFree is not applicable to function returns!"); 2441 } 2442 2443 /// See AbstractAttribute::trackStatistics() 2444 void trackStatistics() const override {} 2445 }; 2446 2447 /// NoFree attribute deduction for a call site return value. 2448 struct AANoFreeCallSiteReturned final : AANoFreeFloating { 2449 AANoFreeCallSiteReturned(const IRPosition &IRP, Attributor &A) 2450 : AANoFreeFloating(IRP, A) {} 2451 2452 ChangeStatus manifest(Attributor &A) override { 2453 return ChangeStatus::UNCHANGED; 2454 } 2455 /// See AbstractAttribute::trackStatistics() 2456 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) } 2457 }; 2458 } // namespace 2459 2460 /// ------------------------ NonNull Argument Attribute ------------------------ 2461 2462 bool AANonNull::isImpliedByIR(Attributor &A, const IRPosition &IRP, 2463 Attribute::AttrKind ImpliedAttributeKind, 2464 bool IgnoreSubsumingPositions) { 2465 SmallVector<Attribute::AttrKind, 2> AttrKinds; 2466 AttrKinds.push_back(Attribute::NonNull); 2467 if (!NullPointerIsDefined(IRP.getAnchorScope(), 2468 IRP.getAssociatedType()->getPointerAddressSpace())) 2469 AttrKinds.push_back(Attribute::Dereferenceable); 2470 if (A.hasAttr(IRP, AttrKinds, IgnoreSubsumingPositions, Attribute::NonNull)) 2471 return true; 2472 2473 DominatorTree *DT = nullptr; 2474 AssumptionCache *AC = nullptr; 2475 InformationCache &InfoCache = A.getInfoCache(); 2476 if (const Function *Fn = IRP.getAnchorScope()) { 2477 if (!Fn->isDeclaration()) { 2478 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*Fn); 2479 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*Fn); 2480 } 2481 } 2482 2483 SmallVector<AA::ValueAndContext> Worklist; 2484 if (IRP.getPositionKind() != IRP_RETURNED) { 2485 Worklist.push_back({IRP.getAssociatedValue(), IRP.getCtxI()}); 2486 } else { 2487 bool UsedAssumedInformation = false; 2488 if (!A.checkForAllInstructions( 2489 [&](Instruction &I) { 2490 Worklist.push_back({*cast<ReturnInst>(I).getReturnValue(), &I}); 2491 return true; 2492 }, 2493 IRP.getAssociatedFunction(), nullptr, {Instruction::Ret}, 2494 UsedAssumedInformation, false, /*CheckPotentiallyDead=*/true)) 2495 return false; 2496 } 2497 2498 if (llvm::any_of(Worklist, [&](AA::ValueAndContext VAC) { 2499 return !isKnownNonZero( 2500 VAC.getValue(), 2501 SimplifyQuery(A.getDataLayout(), DT, AC, VAC.getCtxI())); 2502 })) 2503 return false; 2504 2505 A.manifestAttrs(IRP, {Attribute::get(IRP.getAnchorValue().getContext(), 2506 Attribute::NonNull)}); 2507 return true; 2508 } 2509 2510 namespace { 2511 static int64_t getKnownNonNullAndDerefBytesForUse( 2512 Attributor &A, const AbstractAttribute &QueryingAA, Value &AssociatedValue, 2513 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) { 2514 TrackUse = false; 2515 2516 const Value *UseV = U->get(); 2517 if (!UseV->getType()->isPointerTy()) 2518 return 0; 2519 2520 // We need to follow common pointer manipulation uses to the accesses they 2521 // feed into. We can try to be smart to avoid looking through things we do not 2522 // like for now, e.g., non-inbounds GEPs. 2523 if (isa<CastInst>(I)) { 2524 TrackUse = true; 2525 return 0; 2526 } 2527 2528 if (isa<GetElementPtrInst>(I)) { 2529 TrackUse = true; 2530 return 0; 2531 } 2532 2533 Type *PtrTy = UseV->getType(); 2534 const Function *F = I->getFunction(); 2535 bool NullPointerIsDefined = 2536 F ? llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace()) : true; 2537 const DataLayout &DL = A.getInfoCache().getDL(); 2538 if (const auto *CB = dyn_cast<CallBase>(I)) { 2539 if (CB->isBundleOperand(U)) { 2540 if (RetainedKnowledge RK = getKnowledgeFromUse( 2541 U, {Attribute::NonNull, Attribute::Dereferenceable})) { 2542 IsNonNull |= 2543 (RK.AttrKind == Attribute::NonNull || !NullPointerIsDefined); 2544 return RK.ArgValue; 2545 } 2546 return 0; 2547 } 2548 2549 if (CB->isCallee(U)) { 2550 IsNonNull |= !NullPointerIsDefined; 2551 return 0; 2552 } 2553 2554 unsigned ArgNo = CB->getArgOperandNo(U); 2555 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo); 2556 // As long as we only use known information there is no need to track 2557 // dependences here. 2558 bool IsKnownNonNull; 2559 AA::hasAssumedIRAttr<Attribute::NonNull>(A, &QueryingAA, IRP, 2560 DepClassTy::NONE, IsKnownNonNull); 2561 IsNonNull |= IsKnownNonNull; 2562 auto *DerefAA = 2563 A.getAAFor<AADereferenceable>(QueryingAA, IRP, DepClassTy::NONE); 2564 return DerefAA ? DerefAA->getKnownDereferenceableBytes() : 0; 2565 } 2566 2567 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I); 2568 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || 2569 Loc->Size.isScalable() || I->isVolatile()) 2570 return 0; 2571 2572 int64_t Offset; 2573 const Value *Base = 2574 getMinimalBaseOfPointer(A, QueryingAA, Loc->Ptr, Offset, DL); 2575 if (Base && Base == &AssociatedValue) { 2576 int64_t DerefBytes = Loc->Size.getValue() + Offset; 2577 IsNonNull |= !NullPointerIsDefined; 2578 return std::max(int64_t(0), DerefBytes); 2579 } 2580 2581 /// Corner case when an offset is 0. 2582 Base = GetPointerBaseWithConstantOffset(Loc->Ptr, Offset, DL, 2583 /*AllowNonInbounds*/ true); 2584 if (Base && Base == &AssociatedValue && Offset == 0) { 2585 int64_t DerefBytes = Loc->Size.getValue(); 2586 IsNonNull |= !NullPointerIsDefined; 2587 return std::max(int64_t(0), DerefBytes); 2588 } 2589 2590 return 0; 2591 } 2592 2593 struct AANonNullImpl : AANonNull { 2594 AANonNullImpl(const IRPosition &IRP, Attributor &A) : AANonNull(IRP, A) {} 2595 2596 /// See AbstractAttribute::initialize(...). 2597 void initialize(Attributor &A) override { 2598 Value &V = *getAssociatedValue().stripPointerCasts(); 2599 if (isa<ConstantPointerNull>(V)) { 2600 indicatePessimisticFixpoint(); 2601 return; 2602 } 2603 2604 if (Instruction *CtxI = getCtxI()) 2605 followUsesInMBEC(*this, A, getState(), *CtxI); 2606 } 2607 2608 /// See followUsesInMBEC 2609 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I, 2610 AANonNull::StateType &State) { 2611 bool IsNonNull = false; 2612 bool TrackUse = false; 2613 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I, 2614 IsNonNull, TrackUse); 2615 State.setKnown(IsNonNull); 2616 return TrackUse; 2617 } 2618 2619 /// See AbstractAttribute::getAsStr(). 2620 const std::string getAsStr(Attributor *A) const override { 2621 return getAssumed() ? "nonnull" : "may-null"; 2622 } 2623 }; 2624 2625 /// NonNull attribute for a floating value. 2626 struct AANonNullFloating : public AANonNullImpl { 2627 AANonNullFloating(const IRPosition &IRP, Attributor &A) 2628 : AANonNullImpl(IRP, A) {} 2629 2630 /// See AbstractAttribute::updateImpl(...). 2631 ChangeStatus updateImpl(Attributor &A) override { 2632 auto CheckIRP = [&](const IRPosition &IRP) { 2633 bool IsKnownNonNull; 2634 return AA::hasAssumedIRAttr<Attribute::NonNull>( 2635 A, *this, IRP, DepClassTy::OPTIONAL, IsKnownNonNull); 2636 }; 2637 2638 bool Stripped; 2639 bool UsedAssumedInformation = false; 2640 Value *AssociatedValue = &getAssociatedValue(); 2641 SmallVector<AA::ValueAndContext> Values; 2642 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values, 2643 AA::AnyScope, UsedAssumedInformation)) 2644 Stripped = false; 2645 else 2646 Stripped = 2647 Values.size() != 1 || Values.front().getValue() != AssociatedValue; 2648 2649 if (!Stripped) { 2650 bool IsKnown; 2651 if (auto *PHI = dyn_cast<PHINode>(AssociatedValue)) 2652 if (llvm::all_of(PHI->incoming_values(), [&](Value *Op) { 2653 return AA::hasAssumedIRAttr<Attribute::NonNull>( 2654 A, this, IRPosition::value(*Op), DepClassTy::OPTIONAL, 2655 IsKnown); 2656 })) 2657 return ChangeStatus::UNCHANGED; 2658 if (auto *Select = dyn_cast<SelectInst>(AssociatedValue)) 2659 if (AA::hasAssumedIRAttr<Attribute::NonNull>( 2660 A, this, IRPosition::value(*Select->getFalseValue()), 2661 DepClassTy::OPTIONAL, IsKnown) && 2662 AA::hasAssumedIRAttr<Attribute::NonNull>( 2663 A, this, IRPosition::value(*Select->getTrueValue()), 2664 DepClassTy::OPTIONAL, IsKnown)) 2665 return ChangeStatus::UNCHANGED; 2666 2667 // If we haven't stripped anything we might still be able to use a 2668 // different AA, but only if the IRP changes. Effectively when we 2669 // interpret this not as a call site value but as a floating/argument 2670 // value. 2671 const IRPosition AVIRP = IRPosition::value(*AssociatedValue); 2672 if (AVIRP == getIRPosition() || !CheckIRP(AVIRP)) 2673 return indicatePessimisticFixpoint(); 2674 return ChangeStatus::UNCHANGED; 2675 } 2676 2677 for (const auto &VAC : Values) 2678 if (!CheckIRP(IRPosition::value(*VAC.getValue()))) 2679 return indicatePessimisticFixpoint(); 2680 2681 return ChangeStatus::UNCHANGED; 2682 } 2683 2684 /// See AbstractAttribute::trackStatistics() 2685 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) } 2686 }; 2687 2688 /// NonNull attribute for function return value. 2689 struct AANonNullReturned final 2690 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType, 2691 false, AANonNull::IRAttributeKind, false> { 2692 AANonNullReturned(const IRPosition &IRP, Attributor &A) 2693 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType, 2694 false, Attribute::NonNull, false>(IRP, A) { 2695 } 2696 2697 /// See AbstractAttribute::getAsStr(). 2698 const std::string getAsStr(Attributor *A) const override { 2699 return getAssumed() ? "nonnull" : "may-null"; 2700 } 2701 2702 /// See AbstractAttribute::trackStatistics() 2703 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) } 2704 }; 2705 2706 /// NonNull attribute for function argument. 2707 struct AANonNullArgument final 2708 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl> { 2709 AANonNullArgument(const IRPosition &IRP, Attributor &A) 2710 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl>(IRP, A) {} 2711 2712 /// See AbstractAttribute::trackStatistics() 2713 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) } 2714 }; 2715 2716 struct AANonNullCallSiteArgument final : AANonNullFloating { 2717 AANonNullCallSiteArgument(const IRPosition &IRP, Attributor &A) 2718 : AANonNullFloating(IRP, A) {} 2719 2720 /// See AbstractAttribute::trackStatistics() 2721 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) } 2722 }; 2723 2724 /// NonNull attribute for a call site return position. 2725 struct AANonNullCallSiteReturned final 2726 : AACalleeToCallSite<AANonNull, AANonNullImpl> { 2727 AANonNullCallSiteReturned(const IRPosition &IRP, Attributor &A) 2728 : AACalleeToCallSite<AANonNull, AANonNullImpl>(IRP, A) {} 2729 2730 /// See AbstractAttribute::trackStatistics() 2731 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) } 2732 }; 2733 } // namespace 2734 2735 /// ------------------------ Must-Progress Attributes -------------------------- 2736 namespace { 2737 struct AAMustProgressImpl : public AAMustProgress { 2738 AAMustProgressImpl(const IRPosition &IRP, Attributor &A) 2739 : AAMustProgress(IRP, A) {} 2740 2741 /// See AbstractAttribute::initialize(...). 2742 void initialize(Attributor &A) override { 2743 bool IsKnown; 2744 assert(!AA::hasAssumedIRAttr<Attribute::MustProgress>( 2745 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown)); 2746 (void)IsKnown; 2747 } 2748 2749 /// See AbstractAttribute::getAsStr() 2750 const std::string getAsStr(Attributor *A) const override { 2751 return getAssumed() ? "mustprogress" : "may-not-progress"; 2752 } 2753 }; 2754 2755 struct AAMustProgressFunction final : AAMustProgressImpl { 2756 AAMustProgressFunction(const IRPosition &IRP, Attributor &A) 2757 : AAMustProgressImpl(IRP, A) {} 2758 2759 /// See AbstractAttribute::updateImpl(...). 2760 ChangeStatus updateImpl(Attributor &A) override { 2761 bool IsKnown; 2762 if (AA::hasAssumedIRAttr<Attribute::WillReturn>( 2763 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnown)) { 2764 if (IsKnown) 2765 return indicateOptimisticFixpoint(); 2766 return ChangeStatus::UNCHANGED; 2767 } 2768 2769 auto CheckForMustProgress = [&](AbstractCallSite ACS) { 2770 IRPosition IPos = IRPosition::callsite_function(*ACS.getInstruction()); 2771 bool IsKnownMustProgress; 2772 return AA::hasAssumedIRAttr<Attribute::MustProgress>( 2773 A, this, IPos, DepClassTy::REQUIRED, IsKnownMustProgress, 2774 /* IgnoreSubsumingPositions */ true); 2775 }; 2776 2777 bool AllCallSitesKnown = true; 2778 if (!A.checkForAllCallSites(CheckForMustProgress, *this, 2779 /* RequireAllCallSites */ true, 2780 AllCallSitesKnown)) 2781 return indicatePessimisticFixpoint(); 2782 2783 return ChangeStatus::UNCHANGED; 2784 } 2785 2786 /// See AbstractAttribute::trackStatistics() 2787 void trackStatistics() const override { 2788 STATS_DECLTRACK_FN_ATTR(mustprogress) 2789 } 2790 }; 2791 2792 /// MustProgress attribute deduction for a call sites. 2793 struct AAMustProgressCallSite final : AAMustProgressImpl { 2794 AAMustProgressCallSite(const IRPosition &IRP, Attributor &A) 2795 : AAMustProgressImpl(IRP, A) {} 2796 2797 /// See AbstractAttribute::updateImpl(...). 2798 ChangeStatus updateImpl(Attributor &A) override { 2799 // TODO: Once we have call site specific value information we can provide 2800 // call site specific liveness information and then it makes 2801 // sense to specialize attributes for call sites arguments instead of 2802 // redirecting requests to the callee argument. 2803 const IRPosition &FnPos = IRPosition::function(*getAnchorScope()); 2804 bool IsKnownMustProgress; 2805 if (!AA::hasAssumedIRAttr<Attribute::MustProgress>( 2806 A, this, FnPos, DepClassTy::REQUIRED, IsKnownMustProgress)) 2807 return indicatePessimisticFixpoint(); 2808 return ChangeStatus::UNCHANGED; 2809 } 2810 2811 /// See AbstractAttribute::trackStatistics() 2812 void trackStatistics() const override { 2813 STATS_DECLTRACK_CS_ATTR(mustprogress); 2814 } 2815 }; 2816 } // namespace 2817 2818 /// ------------------------ No-Recurse Attributes ---------------------------- 2819 2820 namespace { 2821 struct AANoRecurseImpl : public AANoRecurse { 2822 AANoRecurseImpl(const IRPosition &IRP, Attributor &A) : AANoRecurse(IRP, A) {} 2823 2824 /// See AbstractAttribute::initialize(...). 2825 void initialize(Attributor &A) override { 2826 bool IsKnown; 2827 assert(!AA::hasAssumedIRAttr<Attribute::NoRecurse>( 2828 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown)); 2829 (void)IsKnown; 2830 } 2831 2832 /// See AbstractAttribute::getAsStr() 2833 const std::string getAsStr(Attributor *A) const override { 2834 return getAssumed() ? "norecurse" : "may-recurse"; 2835 } 2836 }; 2837 2838 struct AANoRecurseFunction final : AANoRecurseImpl { 2839 AANoRecurseFunction(const IRPosition &IRP, Attributor &A) 2840 : AANoRecurseImpl(IRP, A) {} 2841 2842 /// See AbstractAttribute::updateImpl(...). 2843 ChangeStatus updateImpl(Attributor &A) override { 2844 2845 // If all live call sites are known to be no-recurse, we are as well. 2846 auto CallSitePred = [&](AbstractCallSite ACS) { 2847 bool IsKnownNoRecurse; 2848 if (!AA::hasAssumedIRAttr<Attribute::NoRecurse>( 2849 A, this, 2850 IRPosition::function(*ACS.getInstruction()->getFunction()), 2851 DepClassTy::NONE, IsKnownNoRecurse)) 2852 return false; 2853 return IsKnownNoRecurse; 2854 }; 2855 bool UsedAssumedInformation = false; 2856 if (A.checkForAllCallSites(CallSitePred, *this, true, 2857 UsedAssumedInformation)) { 2858 // If we know all call sites and all are known no-recurse, we are done. 2859 // If all known call sites, which might not be all that exist, are known 2860 // to be no-recurse, we are not done but we can continue to assume 2861 // no-recurse. If one of the call sites we have not visited will become 2862 // live, another update is triggered. 2863 if (!UsedAssumedInformation) 2864 indicateOptimisticFixpoint(); 2865 return ChangeStatus::UNCHANGED; 2866 } 2867 2868 const AAInterFnReachability *EdgeReachability = 2869 A.getAAFor<AAInterFnReachability>(*this, getIRPosition(), 2870 DepClassTy::REQUIRED); 2871 if (EdgeReachability && EdgeReachability->canReach(A, *getAnchorScope())) 2872 return indicatePessimisticFixpoint(); 2873 return ChangeStatus::UNCHANGED; 2874 } 2875 2876 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) } 2877 }; 2878 2879 /// NoRecurse attribute deduction for a call sites. 2880 struct AANoRecurseCallSite final 2881 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl> { 2882 AANoRecurseCallSite(const IRPosition &IRP, Attributor &A) 2883 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl>(IRP, A) {} 2884 2885 /// See AbstractAttribute::trackStatistics() 2886 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); } 2887 }; 2888 } // namespace 2889 2890 /// ------------------------ No-Convergent Attribute -------------------------- 2891 2892 namespace { 2893 struct AANonConvergentImpl : public AANonConvergent { 2894 AANonConvergentImpl(const IRPosition &IRP, Attributor &A) 2895 : AANonConvergent(IRP, A) {} 2896 2897 /// See AbstractAttribute::getAsStr() 2898 const std::string getAsStr(Attributor *A) const override { 2899 return getAssumed() ? "non-convergent" : "may-be-convergent"; 2900 } 2901 }; 2902 2903 struct AANonConvergentFunction final : AANonConvergentImpl { 2904 AANonConvergentFunction(const IRPosition &IRP, Attributor &A) 2905 : AANonConvergentImpl(IRP, A) {} 2906 2907 /// See AbstractAttribute::updateImpl(...). 2908 ChangeStatus updateImpl(Attributor &A) override { 2909 // If all function calls are known to not be convergent, we are not 2910 // convergent. 2911 auto CalleeIsNotConvergent = [&](Instruction &Inst) { 2912 CallBase &CB = cast<CallBase>(Inst); 2913 auto *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand()); 2914 if (!Callee || Callee->isIntrinsic()) { 2915 return false; 2916 } 2917 if (Callee->isDeclaration()) { 2918 return !Callee->hasFnAttribute(Attribute::Convergent); 2919 } 2920 const auto *ConvergentAA = A.getAAFor<AANonConvergent>( 2921 *this, IRPosition::function(*Callee), DepClassTy::REQUIRED); 2922 return ConvergentAA && ConvergentAA->isAssumedNotConvergent(); 2923 }; 2924 2925 bool UsedAssumedInformation = false; 2926 if (!A.checkForAllCallLikeInstructions(CalleeIsNotConvergent, *this, 2927 UsedAssumedInformation)) { 2928 return indicatePessimisticFixpoint(); 2929 } 2930 return ChangeStatus::UNCHANGED; 2931 } 2932 2933 ChangeStatus manifest(Attributor &A) override { 2934 if (isKnownNotConvergent() && 2935 A.hasAttr(getIRPosition(), Attribute::Convergent)) { 2936 A.removeAttrs(getIRPosition(), {Attribute::Convergent}); 2937 return ChangeStatus::CHANGED; 2938 } 2939 return ChangeStatus::UNCHANGED; 2940 } 2941 2942 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(convergent) } 2943 }; 2944 } // namespace 2945 2946 /// -------------------- Undefined-Behavior Attributes ------------------------ 2947 2948 namespace { 2949 struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { 2950 AAUndefinedBehaviorImpl(const IRPosition &IRP, Attributor &A) 2951 : AAUndefinedBehavior(IRP, A) {} 2952 2953 /// See AbstractAttribute::updateImpl(...). 2954 // through a pointer (i.e. also branches etc.) 2955 ChangeStatus updateImpl(Attributor &A) override { 2956 const size_t UBPrevSize = KnownUBInsts.size(); 2957 const size_t NoUBPrevSize = AssumedNoUBInsts.size(); 2958 2959 auto InspectMemAccessInstForUB = [&](Instruction &I) { 2960 // Lang ref now states volatile store is not UB, let's skip them. 2961 if (I.isVolatile() && I.mayWriteToMemory()) 2962 return true; 2963 2964 // Skip instructions that are already saved. 2965 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I)) 2966 return true; 2967 2968 // If we reach here, we know we have an instruction 2969 // that accesses memory through a pointer operand, 2970 // for which getPointerOperand() should give it to us. 2971 Value *PtrOp = 2972 const_cast<Value *>(getPointerOperand(&I, /* AllowVolatile */ true)); 2973 assert(PtrOp && 2974 "Expected pointer operand of memory accessing instruction"); 2975 2976 // Either we stopped and the appropriate action was taken, 2977 // or we got back a simplified value to continue. 2978 std::optional<Value *> SimplifiedPtrOp = 2979 stopOnUndefOrAssumed(A, PtrOp, &I); 2980 if (!SimplifiedPtrOp || !*SimplifiedPtrOp) 2981 return true; 2982 const Value *PtrOpVal = *SimplifiedPtrOp; 2983 2984 // A memory access through a pointer is considered UB 2985 // only if the pointer has constant null value. 2986 // TODO: Expand it to not only check constant values. 2987 if (!isa<ConstantPointerNull>(PtrOpVal)) { 2988 AssumedNoUBInsts.insert(&I); 2989 return true; 2990 } 2991 const Type *PtrTy = PtrOpVal->getType(); 2992 2993 // Because we only consider instructions inside functions, 2994 // assume that a parent function exists. 2995 const Function *F = I.getFunction(); 2996 2997 // A memory access using constant null pointer is only considered UB 2998 // if null pointer is _not_ defined for the target platform. 2999 if (llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace())) 3000 AssumedNoUBInsts.insert(&I); 3001 else 3002 KnownUBInsts.insert(&I); 3003 return true; 3004 }; 3005 3006 auto InspectBrInstForUB = [&](Instruction &I) { 3007 // A conditional branch instruction is considered UB if it has `undef` 3008 // condition. 3009 3010 // Skip instructions that are already saved. 3011 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I)) 3012 return true; 3013 3014 // We know we have a branch instruction. 3015 auto *BrInst = cast<BranchInst>(&I); 3016 3017 // Unconditional branches are never considered UB. 3018 if (BrInst->isUnconditional()) 3019 return true; 3020 3021 // Either we stopped and the appropriate action was taken, 3022 // or we got back a simplified value to continue. 3023 std::optional<Value *> SimplifiedCond = 3024 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst); 3025 if (!SimplifiedCond || !*SimplifiedCond) 3026 return true; 3027 AssumedNoUBInsts.insert(&I); 3028 return true; 3029 }; 3030 3031 auto InspectCallSiteForUB = [&](Instruction &I) { 3032 // Check whether a callsite always cause UB or not 3033 3034 // Skip instructions that are already saved. 3035 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I)) 3036 return true; 3037 3038 // Check nonnull and noundef argument attribute violation for each 3039 // callsite. 3040 CallBase &CB = cast<CallBase>(I); 3041 auto *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand()); 3042 if (!Callee) 3043 return true; 3044 for (unsigned idx = 0; idx < CB.arg_size(); idx++) { 3045 // If current argument is known to be simplified to null pointer and the 3046 // corresponding argument position is known to have nonnull attribute, 3047 // the argument is poison. Furthermore, if the argument is poison and 3048 // the position is known to have noundef attriubte, this callsite is 3049 // considered UB. 3050 if (idx >= Callee->arg_size()) 3051 break; 3052 Value *ArgVal = CB.getArgOperand(idx); 3053 if (!ArgVal) 3054 continue; 3055 // Here, we handle three cases. 3056 // (1) Not having a value means it is dead. (we can replace the value 3057 // with undef) 3058 // (2) Simplified to undef. The argument violate noundef attriubte. 3059 // (3) Simplified to null pointer where known to be nonnull. 3060 // The argument is a poison value and violate noundef attribute. 3061 IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx); 3062 bool IsKnownNoUndef; 3063 AA::hasAssumedIRAttr<Attribute::NoUndef>( 3064 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNoUndef); 3065 if (!IsKnownNoUndef) 3066 continue; 3067 bool UsedAssumedInformation = false; 3068 std::optional<Value *> SimplifiedVal = 3069 A.getAssumedSimplified(IRPosition::value(*ArgVal), *this, 3070 UsedAssumedInformation, AA::Interprocedural); 3071 if (UsedAssumedInformation) 3072 continue; 3073 if (SimplifiedVal && !*SimplifiedVal) 3074 return true; 3075 if (!SimplifiedVal || isa<UndefValue>(**SimplifiedVal)) { 3076 KnownUBInsts.insert(&I); 3077 continue; 3078 } 3079 if (!ArgVal->getType()->isPointerTy() || 3080 !isa<ConstantPointerNull>(**SimplifiedVal)) 3081 continue; 3082 bool IsKnownNonNull; 3083 AA::hasAssumedIRAttr<Attribute::NonNull>( 3084 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNonNull); 3085 if (IsKnownNonNull) 3086 KnownUBInsts.insert(&I); 3087 } 3088 return true; 3089 }; 3090 3091 auto InspectReturnInstForUB = [&](Instruction &I) { 3092 auto &RI = cast<ReturnInst>(I); 3093 // Either we stopped and the appropriate action was taken, 3094 // or we got back a simplified return value to continue. 3095 std::optional<Value *> SimplifiedRetValue = 3096 stopOnUndefOrAssumed(A, RI.getReturnValue(), &I); 3097 if (!SimplifiedRetValue || !*SimplifiedRetValue) 3098 return true; 3099 3100 // Check if a return instruction always cause UB or not 3101 // Note: It is guaranteed that the returned position of the anchor 3102 // scope has noundef attribute when this is called. 3103 // We also ensure the return position is not "assumed dead" 3104 // because the returned value was then potentially simplified to 3105 // `undef` in AAReturnedValues without removing the `noundef` 3106 // attribute yet. 3107 3108 // When the returned position has noundef attriubte, UB occurs in the 3109 // following cases. 3110 // (1) Returned value is known to be undef. 3111 // (2) The value is known to be a null pointer and the returned 3112 // position has nonnull attribute (because the returned value is 3113 // poison). 3114 if (isa<ConstantPointerNull>(*SimplifiedRetValue)) { 3115 bool IsKnownNonNull; 3116 AA::hasAssumedIRAttr<Attribute::NonNull>( 3117 A, this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE, 3118 IsKnownNonNull); 3119 if (IsKnownNonNull) 3120 KnownUBInsts.insert(&I); 3121 } 3122 3123 return true; 3124 }; 3125 3126 bool UsedAssumedInformation = false; 3127 A.checkForAllInstructions(InspectMemAccessInstForUB, *this, 3128 {Instruction::Load, Instruction::Store, 3129 Instruction::AtomicCmpXchg, 3130 Instruction::AtomicRMW}, 3131 UsedAssumedInformation, 3132 /* CheckBBLivenessOnly */ true); 3133 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::Br}, 3134 UsedAssumedInformation, 3135 /* CheckBBLivenessOnly */ true); 3136 A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this, 3137 UsedAssumedInformation); 3138 3139 // If the returned position of the anchor scope has noundef attriubte, check 3140 // all returned instructions. 3141 if (!getAnchorScope()->getReturnType()->isVoidTy()) { 3142 const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope()); 3143 if (!A.isAssumedDead(ReturnIRP, this, nullptr, UsedAssumedInformation)) { 3144 bool IsKnownNoUndef; 3145 AA::hasAssumedIRAttr<Attribute::NoUndef>( 3146 A, this, ReturnIRP, DepClassTy::NONE, IsKnownNoUndef); 3147 if (IsKnownNoUndef) 3148 A.checkForAllInstructions(InspectReturnInstForUB, *this, 3149 {Instruction::Ret}, UsedAssumedInformation, 3150 /* CheckBBLivenessOnly */ true); 3151 } 3152 } 3153 3154 if (NoUBPrevSize != AssumedNoUBInsts.size() || 3155 UBPrevSize != KnownUBInsts.size()) 3156 return ChangeStatus::CHANGED; 3157 return ChangeStatus::UNCHANGED; 3158 } 3159 3160 bool isKnownToCauseUB(Instruction *I) const override { 3161 return KnownUBInsts.count(I); 3162 } 3163 3164 bool isAssumedToCauseUB(Instruction *I) const override { 3165 // In simple words, if an instruction is not in the assumed to _not_ 3166 // cause UB, then it is assumed UB (that includes those 3167 // in the KnownUBInsts set). The rest is boilerplate 3168 // is to ensure that it is one of the instructions we test 3169 // for UB. 3170 3171 switch (I->getOpcode()) { 3172 case Instruction::Load: 3173 case Instruction::Store: 3174 case Instruction::AtomicCmpXchg: 3175 case Instruction::AtomicRMW: 3176 return !AssumedNoUBInsts.count(I); 3177 case Instruction::Br: { 3178 auto *BrInst = cast<BranchInst>(I); 3179 if (BrInst->isUnconditional()) 3180 return false; 3181 return !AssumedNoUBInsts.count(I); 3182 } break; 3183 default: 3184 return false; 3185 } 3186 return false; 3187 } 3188 3189 ChangeStatus manifest(Attributor &A) override { 3190 if (KnownUBInsts.empty()) 3191 return ChangeStatus::UNCHANGED; 3192 for (Instruction *I : KnownUBInsts) 3193 A.changeToUnreachableAfterManifest(I); 3194 return ChangeStatus::CHANGED; 3195 } 3196 3197 /// See AbstractAttribute::getAsStr() 3198 const std::string getAsStr(Attributor *A) const override { 3199 return getAssumed() ? "undefined-behavior" : "no-ub"; 3200 } 3201 3202 /// Note: The correctness of this analysis depends on the fact that the 3203 /// following 2 sets will stop changing after some point. 3204 /// "Change" here means that their size changes. 3205 /// The size of each set is monotonically increasing 3206 /// (we only add items to them) and it is upper bounded by the number of 3207 /// instructions in the processed function (we can never save more 3208 /// elements in either set than this number). Hence, at some point, 3209 /// they will stop increasing. 3210 /// Consequently, at some point, both sets will have stopped 3211 /// changing, effectively making the analysis reach a fixpoint. 3212 3213 /// Note: These 2 sets are disjoint and an instruction can be considered 3214 /// one of 3 things: 3215 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in 3216 /// the KnownUBInsts set. 3217 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior 3218 /// has a reason to assume it). 3219 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior 3220 /// could not find a reason to assume or prove that it can cause UB, 3221 /// hence it assumes it doesn't. We have a set for these instructions 3222 /// so that we don't reprocess them in every update. 3223 /// Note however that instructions in this set may cause UB. 3224 3225 protected: 3226 /// A set of all live instructions _known_ to cause UB. 3227 SmallPtrSet<Instruction *, 8> KnownUBInsts; 3228 3229 private: 3230 /// A set of all the (live) instructions that are assumed to _not_ cause UB. 3231 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts; 3232 3233 // Should be called on updates in which if we're processing an instruction 3234 // \p I that depends on a value \p V, one of the following has to happen: 3235 // - If the value is assumed, then stop. 3236 // - If the value is known but undef, then consider it UB. 3237 // - Otherwise, do specific processing with the simplified value. 3238 // We return std::nullopt in the first 2 cases to signify that an appropriate 3239 // action was taken and the caller should stop. 3240 // Otherwise, we return the simplified value that the caller should 3241 // use for specific processing. 3242 std::optional<Value *> stopOnUndefOrAssumed(Attributor &A, Value *V, 3243 Instruction *I) { 3244 bool UsedAssumedInformation = false; 3245 std::optional<Value *> SimplifiedV = 3246 A.getAssumedSimplified(IRPosition::value(*V), *this, 3247 UsedAssumedInformation, AA::Interprocedural); 3248 if (!UsedAssumedInformation) { 3249 // Don't depend on assumed values. 3250 if (!SimplifiedV) { 3251 // If it is known (which we tested above) but it doesn't have a value, 3252 // then we can assume `undef` and hence the instruction is UB. 3253 KnownUBInsts.insert(I); 3254 return std::nullopt; 3255 } 3256 if (!*SimplifiedV) 3257 return nullptr; 3258 V = *SimplifiedV; 3259 } 3260 if (isa<UndefValue>(V)) { 3261 KnownUBInsts.insert(I); 3262 return std::nullopt; 3263 } 3264 return V; 3265 } 3266 }; 3267 3268 struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl { 3269 AAUndefinedBehaviorFunction(const IRPosition &IRP, Attributor &A) 3270 : AAUndefinedBehaviorImpl(IRP, A) {} 3271 3272 /// See AbstractAttribute::trackStatistics() 3273 void trackStatistics() const override { 3274 STATS_DECL(UndefinedBehaviorInstruction, Instruction, 3275 "Number of instructions known to have UB"); 3276 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) += 3277 KnownUBInsts.size(); 3278 } 3279 }; 3280 } // namespace 3281 3282 /// ------------------------ Will-Return Attributes ---------------------------- 3283 3284 namespace { 3285 // Helper function that checks whether a function has any cycle which we don't 3286 // know if it is bounded or not. 3287 // Loops with maximum trip count are considered bounded, any other cycle not. 3288 static bool mayContainUnboundedCycle(Function &F, Attributor &A) { 3289 ScalarEvolution *SE = 3290 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(F); 3291 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(F); 3292 // If either SCEV or LoopInfo is not available for the function then we assume 3293 // any cycle to be unbounded cycle. 3294 // We use scc_iterator which uses Tarjan algorithm to find all the maximal 3295 // SCCs.To detect if there's a cycle, we only need to find the maximal ones. 3296 if (!SE || !LI) { 3297 for (scc_iterator<Function *> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI) 3298 if (SCCI.hasCycle()) 3299 return true; 3300 return false; 3301 } 3302 3303 // If there's irreducible control, the function may contain non-loop cycles. 3304 if (mayContainIrreducibleControl(F, LI)) 3305 return true; 3306 3307 // Any loop that does not have a max trip count is considered unbounded cycle. 3308 for (auto *L : LI->getLoopsInPreorder()) { 3309 if (!SE->getSmallConstantMaxTripCount(L)) 3310 return true; 3311 } 3312 return false; 3313 } 3314 3315 struct AAWillReturnImpl : public AAWillReturn { 3316 AAWillReturnImpl(const IRPosition &IRP, Attributor &A) 3317 : AAWillReturn(IRP, A) {} 3318 3319 /// See AbstractAttribute::initialize(...). 3320 void initialize(Attributor &A) override { 3321 bool IsKnown; 3322 assert(!AA::hasAssumedIRAttr<Attribute::WillReturn>( 3323 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown)); 3324 (void)IsKnown; 3325 } 3326 3327 /// Check for `mustprogress` and `readonly` as they imply `willreturn`. 3328 bool isImpliedByMustprogressAndReadonly(Attributor &A, bool KnownOnly) { 3329 if (!A.hasAttr(getIRPosition(), {Attribute::MustProgress})) 3330 return false; 3331 3332 bool IsKnown; 3333 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown)) 3334 return IsKnown || !KnownOnly; 3335 return false; 3336 } 3337 3338 /// See AbstractAttribute::updateImpl(...). 3339 ChangeStatus updateImpl(Attributor &A) override { 3340 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false)) 3341 return ChangeStatus::UNCHANGED; 3342 3343 auto CheckForWillReturn = [&](Instruction &I) { 3344 IRPosition IPos = IRPosition::callsite_function(cast<CallBase>(I)); 3345 bool IsKnown; 3346 if (AA::hasAssumedIRAttr<Attribute::WillReturn>( 3347 A, this, IPos, DepClassTy::REQUIRED, IsKnown)) { 3348 if (IsKnown) 3349 return true; 3350 } else { 3351 return false; 3352 } 3353 bool IsKnownNoRecurse; 3354 return AA::hasAssumedIRAttr<Attribute::NoRecurse>( 3355 A, this, IPos, DepClassTy::REQUIRED, IsKnownNoRecurse); 3356 }; 3357 3358 bool UsedAssumedInformation = false; 3359 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this, 3360 UsedAssumedInformation)) 3361 return indicatePessimisticFixpoint(); 3362 3363 return ChangeStatus::UNCHANGED; 3364 } 3365 3366 /// See AbstractAttribute::getAsStr() 3367 const std::string getAsStr(Attributor *A) const override { 3368 return getAssumed() ? "willreturn" : "may-noreturn"; 3369 } 3370 }; 3371 3372 struct AAWillReturnFunction final : AAWillReturnImpl { 3373 AAWillReturnFunction(const IRPosition &IRP, Attributor &A) 3374 : AAWillReturnImpl(IRP, A) {} 3375 3376 /// See AbstractAttribute::initialize(...). 3377 void initialize(Attributor &A) override { 3378 AAWillReturnImpl::initialize(A); 3379 3380 Function *F = getAnchorScope(); 3381 assert(F && "Did expect an anchor function"); 3382 if (F->isDeclaration() || mayContainUnboundedCycle(*F, A)) 3383 indicatePessimisticFixpoint(); 3384 } 3385 3386 /// See AbstractAttribute::trackStatistics() 3387 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) } 3388 }; 3389 3390 /// WillReturn attribute deduction for a call sites. 3391 struct AAWillReturnCallSite final 3392 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl> { 3393 AAWillReturnCallSite(const IRPosition &IRP, Attributor &A) 3394 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl>(IRP, A) {} 3395 3396 /// See AbstractAttribute::updateImpl(...). 3397 ChangeStatus updateImpl(Attributor &A) override { 3398 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false)) 3399 return ChangeStatus::UNCHANGED; 3400 3401 return AACalleeToCallSite::updateImpl(A); 3402 } 3403 3404 /// See AbstractAttribute::trackStatistics() 3405 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); } 3406 }; 3407 } // namespace 3408 3409 /// -------------------AAIntraFnReachability Attribute-------------------------- 3410 3411 /// All information associated with a reachability query. This boilerplate code 3412 /// is used by both AAIntraFnReachability and AAInterFnReachability, with 3413 /// different \p ToTy values. 3414 template <typename ToTy> struct ReachabilityQueryInfo { 3415 enum class Reachable { 3416 No, 3417 Yes, 3418 }; 3419 3420 /// Start here, 3421 const Instruction *From = nullptr; 3422 /// reach this place, 3423 const ToTy *To = nullptr; 3424 /// without going through any of these instructions, 3425 const AA::InstExclusionSetTy *ExclusionSet = nullptr; 3426 /// and remember if it worked: 3427 Reachable Result = Reachable::No; 3428 3429 /// Precomputed hash for this RQI. 3430 unsigned Hash = 0; 3431 3432 unsigned computeHashValue() const { 3433 assert(Hash == 0 && "Computed hash twice!"); 3434 using InstSetDMI = DenseMapInfo<const AA::InstExclusionSetTy *>; 3435 using PairDMI = DenseMapInfo<std::pair<const Instruction *, const ToTy *>>; 3436 return const_cast<ReachabilityQueryInfo<ToTy> *>(this)->Hash = 3437 detail::combineHashValue(PairDMI ::getHashValue({From, To}), 3438 InstSetDMI::getHashValue(ExclusionSet)); 3439 } 3440 3441 ReachabilityQueryInfo(const Instruction *From, const ToTy *To) 3442 : From(From), To(To) {} 3443 3444 /// Constructor replacement to ensure unique and stable sets are used for the 3445 /// cache. 3446 ReachabilityQueryInfo(Attributor &A, const Instruction &From, const ToTy &To, 3447 const AA::InstExclusionSetTy *ES, bool MakeUnique) 3448 : From(&From), To(&To), ExclusionSet(ES) { 3449 3450 if (!ES || ES->empty()) { 3451 ExclusionSet = nullptr; 3452 } else if (MakeUnique) { 3453 ExclusionSet = A.getInfoCache().getOrCreateUniqueBlockExecutionSet(ES); 3454 } 3455 } 3456 3457 ReachabilityQueryInfo(const ReachabilityQueryInfo &RQI) 3458 : From(RQI.From), To(RQI.To), ExclusionSet(RQI.ExclusionSet) {} 3459 }; 3460 3461 namespace llvm { 3462 template <typename ToTy> struct DenseMapInfo<ReachabilityQueryInfo<ToTy> *> { 3463 using InstSetDMI = DenseMapInfo<const AA::InstExclusionSetTy *>; 3464 using PairDMI = DenseMapInfo<std::pair<const Instruction *, const ToTy *>>; 3465 3466 static ReachabilityQueryInfo<ToTy> EmptyKey; 3467 static ReachabilityQueryInfo<ToTy> TombstoneKey; 3468 3469 static inline ReachabilityQueryInfo<ToTy> *getEmptyKey() { return &EmptyKey; } 3470 static inline ReachabilityQueryInfo<ToTy> *getTombstoneKey() { 3471 return &TombstoneKey; 3472 } 3473 static unsigned getHashValue(const ReachabilityQueryInfo<ToTy> *RQI) { 3474 return RQI->Hash ? RQI->Hash : RQI->computeHashValue(); 3475 } 3476 static bool isEqual(const ReachabilityQueryInfo<ToTy> *LHS, 3477 const ReachabilityQueryInfo<ToTy> *RHS) { 3478 if (!PairDMI::isEqual({LHS->From, LHS->To}, {RHS->From, RHS->To})) 3479 return false; 3480 return InstSetDMI::isEqual(LHS->ExclusionSet, RHS->ExclusionSet); 3481 } 3482 }; 3483 3484 #define DefineKeys(ToTy) \ 3485 template <> \ 3486 ReachabilityQueryInfo<ToTy> \ 3487 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::EmptyKey = \ 3488 ReachabilityQueryInfo<ToTy>( \ 3489 DenseMapInfo<const Instruction *>::getEmptyKey(), \ 3490 DenseMapInfo<const ToTy *>::getEmptyKey()); \ 3491 template <> \ 3492 ReachabilityQueryInfo<ToTy> \ 3493 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::TombstoneKey = \ 3494 ReachabilityQueryInfo<ToTy>( \ 3495 DenseMapInfo<const Instruction *>::getTombstoneKey(), \ 3496 DenseMapInfo<const ToTy *>::getTombstoneKey()); 3497 3498 DefineKeys(Instruction) DefineKeys(Function) 3499 #undef DefineKeys 3500 3501 } // namespace llvm 3502 3503 namespace { 3504 3505 template <typename BaseTy, typename ToTy> 3506 struct CachedReachabilityAA : public BaseTy { 3507 using RQITy = ReachabilityQueryInfo<ToTy>; 3508 3509 CachedReachabilityAA(const IRPosition &IRP, Attributor &A) : BaseTy(IRP, A) {} 3510 3511 /// See AbstractAttribute::isQueryAA. 3512 bool isQueryAA() const override { return true; } 3513 3514 /// See AbstractAttribute::updateImpl(...). 3515 ChangeStatus updateImpl(Attributor &A) override { 3516 ChangeStatus Changed = ChangeStatus::UNCHANGED; 3517 for (unsigned u = 0, e = QueryVector.size(); u < e; ++u) { 3518 RQITy *RQI = QueryVector[u]; 3519 if (RQI->Result == RQITy::Reachable::No && 3520 isReachableImpl(A, *RQI, /*IsTemporaryRQI=*/false)) 3521 Changed = ChangeStatus::CHANGED; 3522 } 3523 return Changed; 3524 } 3525 3526 virtual bool isReachableImpl(Attributor &A, RQITy &RQI, 3527 bool IsTemporaryRQI) = 0; 3528 3529 bool rememberResult(Attributor &A, typename RQITy::Reachable Result, 3530 RQITy &RQI, bool UsedExclusionSet, bool IsTemporaryRQI) { 3531 RQI.Result = Result; 3532 3533 // Remove the temporary RQI from the cache. 3534 if (IsTemporaryRQI) 3535 QueryCache.erase(&RQI); 3536 3537 // Insert a plain RQI (w/o exclusion set) if that makes sense. Two options: 3538 // 1) If it is reachable, it doesn't matter if we have an exclusion set for 3539 // this query. 2) We did not use the exclusion set, potentially because 3540 // there is none. 3541 if (Result == RQITy::Reachable::Yes || !UsedExclusionSet) { 3542 RQITy PlainRQI(RQI.From, RQI.To); 3543 if (!QueryCache.count(&PlainRQI)) { 3544 RQITy *RQIPtr = new (A.Allocator) RQITy(RQI.From, RQI.To); 3545 RQIPtr->Result = Result; 3546 QueryVector.push_back(RQIPtr); 3547 QueryCache.insert(RQIPtr); 3548 } 3549 } 3550 3551 // Check if we need to insert a new permanent RQI with the exclusion set. 3552 if (IsTemporaryRQI && Result != RQITy::Reachable::Yes && UsedExclusionSet) { 3553 assert((!RQI.ExclusionSet || !RQI.ExclusionSet->empty()) && 3554 "Did not expect empty set!"); 3555 RQITy *RQIPtr = new (A.Allocator) 3556 RQITy(A, *RQI.From, *RQI.To, RQI.ExclusionSet, true); 3557 assert(RQIPtr->Result == RQITy::Reachable::No && "Already reachable?"); 3558 RQIPtr->Result = Result; 3559 assert(!QueryCache.count(RQIPtr)); 3560 QueryVector.push_back(RQIPtr); 3561 QueryCache.insert(RQIPtr); 3562 } 3563 3564 if (Result == RQITy::Reachable::No && IsTemporaryRQI) 3565 A.registerForUpdate(*this); 3566 return Result == RQITy::Reachable::Yes; 3567 } 3568 3569 const std::string getAsStr(Attributor *A) const override { 3570 // TODO: Return the number of reachable queries. 3571 return "#queries(" + std::to_string(QueryVector.size()) + ")"; 3572 } 3573 3574 bool checkQueryCache(Attributor &A, RQITy &StackRQI, 3575 typename RQITy::Reachable &Result) { 3576 if (!this->getState().isValidState()) { 3577 Result = RQITy::Reachable::Yes; 3578 return true; 3579 } 3580 3581 // If we have an exclusion set we might be able to find our answer by 3582 // ignoring it first. 3583 if (StackRQI.ExclusionSet) { 3584 RQITy PlainRQI(StackRQI.From, StackRQI.To); 3585 auto It = QueryCache.find(&PlainRQI); 3586 if (It != QueryCache.end() && (*It)->Result == RQITy::Reachable::No) { 3587 Result = RQITy::Reachable::No; 3588 return true; 3589 } 3590 } 3591 3592 auto It = QueryCache.find(&StackRQI); 3593 if (It != QueryCache.end()) { 3594 Result = (*It)->Result; 3595 return true; 3596 } 3597 3598 // Insert a temporary for recursive queries. We will replace it with a 3599 // permanent entry later. 3600 QueryCache.insert(&StackRQI); 3601 return false; 3602 } 3603 3604 private: 3605 SmallVector<RQITy *> QueryVector; 3606 DenseSet<RQITy *> QueryCache; 3607 }; 3608 3609 struct AAIntraFnReachabilityFunction final 3610 : public CachedReachabilityAA<AAIntraFnReachability, Instruction> { 3611 using Base = CachedReachabilityAA<AAIntraFnReachability, Instruction>; 3612 AAIntraFnReachabilityFunction(const IRPosition &IRP, Attributor &A) 3613 : Base(IRP, A) { 3614 DT = A.getInfoCache().getAnalysisResultForFunction<DominatorTreeAnalysis>( 3615 *IRP.getAssociatedFunction()); 3616 } 3617 3618 bool isAssumedReachable( 3619 Attributor &A, const Instruction &From, const Instruction &To, 3620 const AA::InstExclusionSetTy *ExclusionSet) const override { 3621 auto *NonConstThis = const_cast<AAIntraFnReachabilityFunction *>(this); 3622 if (&From == &To) 3623 return true; 3624 3625 RQITy StackRQI(A, From, To, ExclusionSet, false); 3626 typename RQITy::Reachable Result; 3627 if (!NonConstThis->checkQueryCache(A, StackRQI, Result)) 3628 return NonConstThis->isReachableImpl(A, StackRQI, 3629 /*IsTemporaryRQI=*/true); 3630 return Result == RQITy::Reachable::Yes; 3631 } 3632 3633 ChangeStatus updateImpl(Attributor &A) override { 3634 // We only depend on liveness. DeadEdges is all we care about, check if any 3635 // of them changed. 3636 auto *LivenessAA = 3637 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL); 3638 if (LivenessAA && 3639 llvm::all_of(DeadEdges, 3640 [&](const auto &DeadEdge) { 3641 return LivenessAA->isEdgeDead(DeadEdge.first, 3642 DeadEdge.second); 3643 }) && 3644 llvm::all_of(DeadBlocks, [&](const BasicBlock *BB) { 3645 return LivenessAA->isAssumedDead(BB); 3646 })) { 3647 return ChangeStatus::UNCHANGED; 3648 } 3649 DeadEdges.clear(); 3650 DeadBlocks.clear(); 3651 return Base::updateImpl(A); 3652 } 3653 3654 bool isReachableImpl(Attributor &A, RQITy &RQI, 3655 bool IsTemporaryRQI) override { 3656 const Instruction *Origin = RQI.From; 3657 bool UsedExclusionSet = false; 3658 3659 auto WillReachInBlock = [&](const Instruction &From, const Instruction &To, 3660 const AA::InstExclusionSetTy *ExclusionSet) { 3661 const Instruction *IP = &From; 3662 while (IP && IP != &To) { 3663 if (ExclusionSet && IP != Origin && ExclusionSet->count(IP)) { 3664 UsedExclusionSet = true; 3665 break; 3666 } 3667 IP = IP->getNextNode(); 3668 } 3669 return IP == &To; 3670 }; 3671 3672 const BasicBlock *FromBB = RQI.From->getParent(); 3673 const BasicBlock *ToBB = RQI.To->getParent(); 3674 assert(FromBB->getParent() == ToBB->getParent() && 3675 "Not an intra-procedural query!"); 3676 3677 // Check intra-block reachability, however, other reaching paths are still 3678 // possible. 3679 if (FromBB == ToBB && 3680 WillReachInBlock(*RQI.From, *RQI.To, RQI.ExclusionSet)) 3681 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet, 3682 IsTemporaryRQI); 3683 3684 // Check if reaching the ToBB block is sufficient or if even that would not 3685 // ensure reaching the target. In the latter case we are done. 3686 if (!WillReachInBlock(ToBB->front(), *RQI.To, RQI.ExclusionSet)) 3687 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet, 3688 IsTemporaryRQI); 3689 3690 const Function *Fn = FromBB->getParent(); 3691 SmallPtrSet<const BasicBlock *, 16> ExclusionBlocks; 3692 if (RQI.ExclusionSet) 3693 for (auto *I : *RQI.ExclusionSet) 3694 if (I->getFunction() == Fn) 3695 ExclusionBlocks.insert(I->getParent()); 3696 3697 // Check if we make it out of the FromBB block at all. 3698 if (ExclusionBlocks.count(FromBB) && 3699 !WillReachInBlock(*RQI.From, *FromBB->getTerminator(), 3700 RQI.ExclusionSet)) 3701 return rememberResult(A, RQITy::Reachable::No, RQI, true, IsTemporaryRQI); 3702 3703 auto *LivenessAA = 3704 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL); 3705 if (LivenessAA && LivenessAA->isAssumedDead(ToBB)) { 3706 DeadBlocks.insert(ToBB); 3707 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet, 3708 IsTemporaryRQI); 3709 } 3710 3711 SmallPtrSet<const BasicBlock *, 16> Visited; 3712 SmallVector<const BasicBlock *, 16> Worklist; 3713 Worklist.push_back(FromBB); 3714 3715 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> LocalDeadEdges; 3716 while (!Worklist.empty()) { 3717 const BasicBlock *BB = Worklist.pop_back_val(); 3718 if (!Visited.insert(BB).second) 3719 continue; 3720 for (const BasicBlock *SuccBB : successors(BB)) { 3721 if (LivenessAA && LivenessAA->isEdgeDead(BB, SuccBB)) { 3722 LocalDeadEdges.insert({BB, SuccBB}); 3723 continue; 3724 } 3725 // We checked before if we just need to reach the ToBB block. 3726 if (SuccBB == ToBB) 3727 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet, 3728 IsTemporaryRQI); 3729 if (DT && ExclusionBlocks.empty() && DT->dominates(BB, ToBB)) 3730 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet, 3731 IsTemporaryRQI); 3732 3733 if (ExclusionBlocks.count(SuccBB)) { 3734 UsedExclusionSet = true; 3735 continue; 3736 } 3737 Worklist.push_back(SuccBB); 3738 } 3739 } 3740 3741 DeadEdges.insert_range(LocalDeadEdges); 3742 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet, 3743 IsTemporaryRQI); 3744 } 3745 3746 /// See AbstractAttribute::trackStatistics() 3747 void trackStatistics() const override {} 3748 3749 private: 3750 // Set of assumed dead blocks we used in the last query. If any changes we 3751 // update the state. 3752 DenseSet<const BasicBlock *> DeadBlocks; 3753 3754 // Set of assumed dead edges we used in the last query. If any changes we 3755 // update the state. 3756 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> DeadEdges; 3757 3758 /// The dominator tree of the function to short-circuit reasoning. 3759 const DominatorTree *DT = nullptr; 3760 }; 3761 } // namespace 3762 3763 /// ------------------------ NoAlias Argument Attribute ------------------------ 3764 3765 bool AANoAlias::isImpliedByIR(Attributor &A, const IRPosition &IRP, 3766 Attribute::AttrKind ImpliedAttributeKind, 3767 bool IgnoreSubsumingPositions) { 3768 assert(ImpliedAttributeKind == Attribute::NoAlias && 3769 "Unexpected attribute kind"); 3770 Value *Val = &IRP.getAssociatedValue(); 3771 if (IRP.getPositionKind() != IRP_CALL_SITE_ARGUMENT) { 3772 if (isa<AllocaInst>(Val)) 3773 return true; 3774 } else { 3775 IgnoreSubsumingPositions = true; 3776 } 3777 3778 if (isa<UndefValue>(Val)) 3779 return true; 3780 3781 if (isa<ConstantPointerNull>(Val) && 3782 !NullPointerIsDefined(IRP.getAnchorScope(), 3783 Val->getType()->getPointerAddressSpace())) 3784 return true; 3785 3786 if (A.hasAttr(IRP, {Attribute::ByVal, Attribute::NoAlias}, 3787 IgnoreSubsumingPositions, Attribute::NoAlias)) 3788 return true; 3789 3790 return false; 3791 } 3792 3793 namespace { 3794 struct AANoAliasImpl : AANoAlias { 3795 AANoAliasImpl(const IRPosition &IRP, Attributor &A) : AANoAlias(IRP, A) { 3796 assert(getAssociatedType()->isPointerTy() && 3797 "Noalias is a pointer attribute"); 3798 } 3799 3800 const std::string getAsStr(Attributor *A) const override { 3801 return getAssumed() ? "noalias" : "may-alias"; 3802 } 3803 }; 3804 3805 /// NoAlias attribute for a floating value. 3806 struct AANoAliasFloating final : AANoAliasImpl { 3807 AANoAliasFloating(const IRPosition &IRP, Attributor &A) 3808 : AANoAliasImpl(IRP, A) {} 3809 3810 /// See AbstractAttribute::updateImpl(...). 3811 ChangeStatus updateImpl(Attributor &A) override { 3812 // TODO: Implement this. 3813 return indicatePessimisticFixpoint(); 3814 } 3815 3816 /// See AbstractAttribute::trackStatistics() 3817 void trackStatistics() const override { 3818 STATS_DECLTRACK_FLOATING_ATTR(noalias) 3819 } 3820 }; 3821 3822 /// NoAlias attribute for an argument. 3823 struct AANoAliasArgument final 3824 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> { 3825 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>; 3826 AANoAliasArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {} 3827 3828 /// See AbstractAttribute::update(...). 3829 ChangeStatus updateImpl(Attributor &A) override { 3830 // We have to make sure no-alias on the argument does not break 3831 // synchronization when this is a callback argument, see also [1] below. 3832 // If synchronization cannot be affected, we delegate to the base updateImpl 3833 // function, otherwise we give up for now. 3834 3835 // If the function is no-sync, no-alias cannot break synchronization. 3836 bool IsKnownNoSycn; 3837 if (AA::hasAssumedIRAttr<Attribute::NoSync>( 3838 A, this, IRPosition::function_scope(getIRPosition()), 3839 DepClassTy::OPTIONAL, IsKnownNoSycn)) 3840 return Base::updateImpl(A); 3841 3842 // If the argument is read-only, no-alias cannot break synchronization. 3843 bool IsKnown; 3844 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown)) 3845 return Base::updateImpl(A); 3846 3847 // If the argument is never passed through callbacks, no-alias cannot break 3848 // synchronization. 3849 bool UsedAssumedInformation = false; 3850 if (A.checkForAllCallSites( 3851 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this, 3852 true, UsedAssumedInformation)) 3853 return Base::updateImpl(A); 3854 3855 // TODO: add no-alias but make sure it doesn't break synchronization by 3856 // introducing fake uses. See: 3857 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel, 3858 // International Workshop on OpenMP 2018, 3859 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf 3860 3861 return indicatePessimisticFixpoint(); 3862 } 3863 3864 /// See AbstractAttribute::trackStatistics() 3865 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) } 3866 }; 3867 3868 struct AANoAliasCallSiteArgument final : AANoAliasImpl { 3869 AANoAliasCallSiteArgument(const IRPosition &IRP, Attributor &A) 3870 : AANoAliasImpl(IRP, A) {} 3871 3872 /// Determine if the underlying value may alias with the call site argument 3873 /// \p OtherArgNo of \p ICS (= the underlying call site). 3874 bool mayAliasWithArgument(Attributor &A, AAResults *&AAR, 3875 const AAMemoryBehavior &MemBehaviorAA, 3876 const CallBase &CB, unsigned OtherArgNo) { 3877 // We do not need to worry about aliasing with the underlying IRP. 3878 if (this->getCalleeArgNo() == (int)OtherArgNo) 3879 return false; 3880 3881 // If it is not a pointer or pointer vector we do not alias. 3882 const Value *ArgOp = CB.getArgOperand(OtherArgNo); 3883 if (!ArgOp->getType()->isPtrOrPtrVectorTy()) 3884 return false; 3885 3886 auto *CBArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>( 3887 *this, IRPosition::callsite_argument(CB, OtherArgNo), DepClassTy::NONE); 3888 3889 // If the argument is readnone, there is no read-write aliasing. 3890 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadNone()) { 3891 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL); 3892 return false; 3893 } 3894 3895 // If the argument is readonly and the underlying value is readonly, there 3896 // is no read-write aliasing. 3897 bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly(); 3898 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadOnly() && 3899 IsReadOnly) { 3900 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL); 3901 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL); 3902 return false; 3903 } 3904 3905 // We have to utilize actual alias analysis queries so we need the object. 3906 if (!AAR) 3907 AAR = A.getInfoCache().getAnalysisResultForFunction<AAManager>( 3908 *getAnchorScope()); 3909 3910 // Try to rule it out at the call site. 3911 bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp); 3912 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between " 3913 "callsite arguments: " 3914 << getAssociatedValue() << " " << *ArgOp << " => " 3915 << (IsAliasing ? "" : "no-") << "alias \n"); 3916 3917 return IsAliasing; 3918 } 3919 3920 bool isKnownNoAliasDueToNoAliasPreservation( 3921 Attributor &A, AAResults *&AAR, const AAMemoryBehavior &MemBehaviorAA) { 3922 // We can deduce "noalias" if the following conditions hold. 3923 // (i) Associated value is assumed to be noalias in the definition. 3924 // (ii) Associated value is assumed to be no-capture in all the uses 3925 // possibly executed before this callsite. 3926 // (iii) There is no other pointer argument which could alias with the 3927 // value. 3928 3929 const IRPosition &VIRP = IRPosition::value(getAssociatedValue()); 3930 const Function *ScopeFn = VIRP.getAnchorScope(); 3931 // Check whether the value is captured in the scope using AANoCapture. 3932 // Look at CFG and check only uses possibly executed before this 3933 // callsite. 3934 auto UsePred = [&](const Use &U, bool &Follow) -> bool { 3935 Instruction *UserI = cast<Instruction>(U.getUser()); 3936 3937 // If UserI is the curr instruction and there is a single potential use of 3938 // the value in UserI we allow the use. 3939 // TODO: We should inspect the operands and allow those that cannot alias 3940 // with the value. 3941 if (UserI == getCtxI() && UserI->getNumOperands() == 1) 3942 return true; 3943 3944 if (ScopeFn) { 3945 if (auto *CB = dyn_cast<CallBase>(UserI)) { 3946 if (CB->isArgOperand(&U)) { 3947 3948 unsigned ArgNo = CB->getArgOperandNo(&U); 3949 3950 bool IsKnownNoCapture; 3951 if (AA::hasAssumedIRAttr<Attribute::Captures>( 3952 A, this, IRPosition::callsite_argument(*CB, ArgNo), 3953 DepClassTy::OPTIONAL, IsKnownNoCapture)) 3954 return true; 3955 } 3956 } 3957 3958 if (!AA::isPotentiallyReachable( 3959 A, *UserI, *getCtxI(), *this, /* ExclusionSet */ nullptr, 3960 [ScopeFn](const Function &Fn) { return &Fn != ScopeFn; })) 3961 return true; 3962 } 3963 3964 // TODO: We should track the capturing uses in AANoCapture but the problem 3965 // is CGSCC runs. For those we would need to "allow" AANoCapture for 3966 // a value in the module slice. 3967 // TODO(captures): Make this more precise. 3968 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr); 3969 if (capturesNothing(CI)) 3970 return true; 3971 if (CI.isPassthrough()) { 3972 Follow = true; 3973 return true; 3974 } 3975 LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *UserI << "\n"); 3976 return false; 3977 }; 3978 3979 bool IsKnownNoCapture; 3980 const AANoCapture *NoCaptureAA = nullptr; 3981 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>( 3982 A, this, VIRP, DepClassTy::NONE, IsKnownNoCapture, false, &NoCaptureAA); 3983 if (!IsAssumedNoCapture && 3984 (!NoCaptureAA || !NoCaptureAA->isAssumedNoCaptureMaybeReturned())) { 3985 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) { 3986 LLVM_DEBUG( 3987 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue() 3988 << " cannot be noalias as it is potentially captured\n"); 3989 return false; 3990 } 3991 } 3992 if (NoCaptureAA) 3993 A.recordDependence(*NoCaptureAA, *this, DepClassTy::OPTIONAL); 3994 3995 // Check there is no other pointer argument which could alias with the 3996 // value passed at this call site. 3997 // TODO: AbstractCallSite 3998 const auto &CB = cast<CallBase>(getAnchorValue()); 3999 for (unsigned OtherArgNo = 0; OtherArgNo < CB.arg_size(); OtherArgNo++) 4000 if (mayAliasWithArgument(A, AAR, MemBehaviorAA, CB, OtherArgNo)) 4001 return false; 4002 4003 return true; 4004 } 4005 4006 /// See AbstractAttribute::updateImpl(...). 4007 ChangeStatus updateImpl(Attributor &A) override { 4008 // If the argument is readnone we are done as there are no accesses via the 4009 // argument. 4010 auto *MemBehaviorAA = 4011 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE); 4012 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) { 4013 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL); 4014 return ChangeStatus::UNCHANGED; 4015 } 4016 4017 bool IsKnownNoAlias; 4018 const IRPosition &VIRP = IRPosition::value(getAssociatedValue()); 4019 if (!AA::hasAssumedIRAttr<Attribute::NoAlias>( 4020 A, this, VIRP, DepClassTy::REQUIRED, IsKnownNoAlias)) { 4021 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue() 4022 << " is not no-alias at the definition\n"); 4023 return indicatePessimisticFixpoint(); 4024 } 4025 4026 AAResults *AAR = nullptr; 4027 if (MemBehaviorAA && 4028 isKnownNoAliasDueToNoAliasPreservation(A, AAR, *MemBehaviorAA)) { 4029 LLVM_DEBUG( 4030 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n"); 4031 return ChangeStatus::UNCHANGED; 4032 } 4033 4034 return indicatePessimisticFixpoint(); 4035 } 4036 4037 /// See AbstractAttribute::trackStatistics() 4038 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) } 4039 }; 4040 4041 /// NoAlias attribute for function return value. 4042 struct AANoAliasReturned final : AANoAliasImpl { 4043 AANoAliasReturned(const IRPosition &IRP, Attributor &A) 4044 : AANoAliasImpl(IRP, A) {} 4045 4046 /// See AbstractAttribute::updateImpl(...). 4047 ChangeStatus updateImpl(Attributor &A) override { 4048 4049 auto CheckReturnValue = [&](Value &RV) -> bool { 4050 if (Constant *C = dyn_cast<Constant>(&RV)) 4051 if (C->isNullValue() || isa<UndefValue>(C)) 4052 return true; 4053 4054 /// For now, we can only deduce noalias if we have call sites. 4055 /// FIXME: add more support. 4056 if (!isa<CallBase>(&RV)) 4057 return false; 4058 4059 const IRPosition &RVPos = IRPosition::value(RV); 4060 bool IsKnownNoAlias; 4061 if (!AA::hasAssumedIRAttr<Attribute::NoAlias>( 4062 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoAlias)) 4063 return false; 4064 4065 bool IsKnownNoCapture; 4066 const AANoCapture *NoCaptureAA = nullptr; 4067 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>( 4068 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoCapture, false, 4069 &NoCaptureAA); 4070 return IsAssumedNoCapture || 4071 (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned()); 4072 }; 4073 4074 if (!A.checkForAllReturnedValues(CheckReturnValue, *this)) 4075 return indicatePessimisticFixpoint(); 4076 4077 return ChangeStatus::UNCHANGED; 4078 } 4079 4080 /// See AbstractAttribute::trackStatistics() 4081 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) } 4082 }; 4083 4084 /// NoAlias attribute deduction for a call site return value. 4085 struct AANoAliasCallSiteReturned final 4086 : AACalleeToCallSite<AANoAlias, AANoAliasImpl> { 4087 AANoAliasCallSiteReturned(const IRPosition &IRP, Attributor &A) 4088 : AACalleeToCallSite<AANoAlias, AANoAliasImpl>(IRP, A) {} 4089 4090 /// See AbstractAttribute::trackStatistics() 4091 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); } 4092 }; 4093 } // namespace 4094 4095 /// -------------------AAIsDead Function Attribute----------------------- 4096 4097 namespace { 4098 struct AAIsDeadValueImpl : public AAIsDead { 4099 AAIsDeadValueImpl(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {} 4100 4101 /// See AAIsDead::isAssumedDead(). 4102 bool isAssumedDead() const override { return isAssumed(IS_DEAD); } 4103 4104 /// See AAIsDead::isKnownDead(). 4105 bool isKnownDead() const override { return isKnown(IS_DEAD); } 4106 4107 /// See AAIsDead::isAssumedDead(BasicBlock *). 4108 bool isAssumedDead(const BasicBlock *BB) const override { return false; } 4109 4110 /// See AAIsDead::isKnownDead(BasicBlock *). 4111 bool isKnownDead(const BasicBlock *BB) const override { return false; } 4112 4113 /// See AAIsDead::isAssumedDead(Instruction *I). 4114 bool isAssumedDead(const Instruction *I) const override { 4115 return I == getCtxI() && isAssumedDead(); 4116 } 4117 4118 /// See AAIsDead::isKnownDead(Instruction *I). 4119 bool isKnownDead(const Instruction *I) const override { 4120 return isAssumedDead(I) && isKnownDead(); 4121 } 4122 4123 /// See AbstractAttribute::getAsStr(). 4124 const std::string getAsStr(Attributor *A) const override { 4125 return isAssumedDead() ? "assumed-dead" : "assumed-live"; 4126 } 4127 4128 /// Check if all uses are assumed dead. 4129 bool areAllUsesAssumedDead(Attributor &A, Value &V) { 4130 // Callers might not check the type, void has no uses. 4131 if (V.getType()->isVoidTy() || V.use_empty()) 4132 return true; 4133 4134 // If we replace a value with a constant there are no uses left afterwards. 4135 if (!isa<Constant>(V)) { 4136 if (auto *I = dyn_cast<Instruction>(&V)) 4137 if (!A.isRunOn(*I->getFunction())) 4138 return false; 4139 bool UsedAssumedInformation = false; 4140 std::optional<Constant *> C = 4141 A.getAssumedConstant(V, *this, UsedAssumedInformation); 4142 if (!C || *C) 4143 return true; 4144 } 4145 4146 auto UsePred = [&](const Use &U, bool &Follow) { return false; }; 4147 // Explicitly set the dependence class to required because we want a long 4148 // chain of N dependent instructions to be considered live as soon as one is 4149 // without going through N update cycles. This is not required for 4150 // correctness. 4151 return A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ false, 4152 DepClassTy::REQUIRED, 4153 /* IgnoreDroppableUses */ false); 4154 } 4155 4156 /// Determine if \p I is assumed to be side-effect free. 4157 bool isAssumedSideEffectFree(Attributor &A, Instruction *I) { 4158 if (!I || wouldInstructionBeTriviallyDead(I)) 4159 return true; 4160 4161 auto *CB = dyn_cast<CallBase>(I); 4162 if (!CB || isa<IntrinsicInst>(CB)) 4163 return false; 4164 4165 const IRPosition &CallIRP = IRPosition::callsite_function(*CB); 4166 4167 bool IsKnownNoUnwind; 4168 if (!AA::hasAssumedIRAttr<Attribute::NoUnwind>( 4169 A, this, CallIRP, DepClassTy::OPTIONAL, IsKnownNoUnwind)) 4170 return false; 4171 4172 bool IsKnown; 4173 return AA::isAssumedReadOnly(A, CallIRP, *this, IsKnown); 4174 } 4175 }; 4176 4177 struct AAIsDeadFloating : public AAIsDeadValueImpl { 4178 AAIsDeadFloating(const IRPosition &IRP, Attributor &A) 4179 : AAIsDeadValueImpl(IRP, A) {} 4180 4181 /// See AbstractAttribute::initialize(...). 4182 void initialize(Attributor &A) override { 4183 AAIsDeadValueImpl::initialize(A); 4184 4185 if (isa<UndefValue>(getAssociatedValue())) { 4186 indicatePessimisticFixpoint(); 4187 return; 4188 } 4189 4190 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()); 4191 if (!isAssumedSideEffectFree(A, I)) { 4192 if (!isa_and_nonnull<StoreInst>(I) && !isa_and_nonnull<FenceInst>(I)) 4193 indicatePessimisticFixpoint(); 4194 else 4195 removeAssumedBits(HAS_NO_EFFECT); 4196 } 4197 } 4198 4199 bool isDeadFence(Attributor &A, FenceInst &FI) { 4200 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>( 4201 IRPosition::function(*FI.getFunction()), *this, DepClassTy::NONE); 4202 if (!ExecDomainAA || !ExecDomainAA->isNoOpFence(FI)) 4203 return false; 4204 A.recordDependence(*ExecDomainAA, *this, DepClassTy::OPTIONAL); 4205 return true; 4206 } 4207 4208 bool isDeadStore(Attributor &A, StoreInst &SI, 4209 SmallSetVector<Instruction *, 8> *AssumeOnlyInst = nullptr) { 4210 // Lang ref now states volatile store is not UB/dead, let's skip them. 4211 if (SI.isVolatile()) 4212 return false; 4213 4214 // If we are collecting assumes to be deleted we are in the manifest stage. 4215 // It's problematic to collect the potential copies again now so we use the 4216 // cached ones. 4217 bool UsedAssumedInformation = false; 4218 if (!AssumeOnlyInst) { 4219 PotentialCopies.clear(); 4220 if (!AA::getPotentialCopiesOfStoredValue(A, SI, PotentialCopies, *this, 4221 UsedAssumedInformation)) { 4222 LLVM_DEBUG( 4223 dbgs() 4224 << "[AAIsDead] Could not determine potential copies of store!\n"); 4225 return false; 4226 } 4227 } 4228 LLVM_DEBUG(dbgs() << "[AAIsDead] Store has " << PotentialCopies.size() 4229 << " potential copies.\n"); 4230 4231 InformationCache &InfoCache = A.getInfoCache(); 4232 return llvm::all_of(PotentialCopies, [&](Value *V) { 4233 if (A.isAssumedDead(IRPosition::value(*V), this, nullptr, 4234 UsedAssumedInformation)) 4235 return true; 4236 if (auto *LI = dyn_cast<LoadInst>(V)) { 4237 if (llvm::all_of(LI->uses(), [&](const Use &U) { 4238 auto &UserI = cast<Instruction>(*U.getUser()); 4239 if (InfoCache.isOnlyUsedByAssume(UserI)) { 4240 if (AssumeOnlyInst) 4241 AssumeOnlyInst->insert(&UserI); 4242 return true; 4243 } 4244 return A.isAssumedDead(U, this, nullptr, UsedAssumedInformation); 4245 })) { 4246 return true; 4247 } 4248 } 4249 LLVM_DEBUG(dbgs() << "[AAIsDead] Potential copy " << *V 4250 << " is assumed live!\n"); 4251 return false; 4252 }); 4253 } 4254 4255 /// See AbstractAttribute::getAsStr(). 4256 const std::string getAsStr(Attributor *A) const override { 4257 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()); 4258 if (isa_and_nonnull<StoreInst>(I)) 4259 if (isValidState()) 4260 return "assumed-dead-store"; 4261 if (isa_and_nonnull<FenceInst>(I)) 4262 if (isValidState()) 4263 return "assumed-dead-fence"; 4264 return AAIsDeadValueImpl::getAsStr(A); 4265 } 4266 4267 /// See AbstractAttribute::updateImpl(...). 4268 ChangeStatus updateImpl(Attributor &A) override { 4269 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()); 4270 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) { 4271 if (!isDeadStore(A, *SI)) 4272 return indicatePessimisticFixpoint(); 4273 } else if (auto *FI = dyn_cast_or_null<FenceInst>(I)) { 4274 if (!isDeadFence(A, *FI)) 4275 return indicatePessimisticFixpoint(); 4276 } else { 4277 if (!isAssumedSideEffectFree(A, I)) 4278 return indicatePessimisticFixpoint(); 4279 if (!areAllUsesAssumedDead(A, getAssociatedValue())) 4280 return indicatePessimisticFixpoint(); 4281 } 4282 return ChangeStatus::UNCHANGED; 4283 } 4284 4285 bool isRemovableStore() const override { 4286 return isAssumed(IS_REMOVABLE) && isa<StoreInst>(&getAssociatedValue()); 4287 } 4288 4289 /// See AbstractAttribute::manifest(...). 4290 ChangeStatus manifest(Attributor &A) override { 4291 Value &V = getAssociatedValue(); 4292 if (auto *I = dyn_cast<Instruction>(&V)) { 4293 // If we get here we basically know the users are all dead. We check if 4294 // isAssumedSideEffectFree returns true here again because it might not be 4295 // the case and only the users are dead but the instruction (=call) is 4296 // still needed. 4297 if (auto *SI = dyn_cast<StoreInst>(I)) { 4298 SmallSetVector<Instruction *, 8> AssumeOnlyInst; 4299 bool IsDead = isDeadStore(A, *SI, &AssumeOnlyInst); 4300 (void)IsDead; 4301 assert(IsDead && "Store was assumed to be dead!"); 4302 A.deleteAfterManifest(*I); 4303 for (size_t i = 0; i < AssumeOnlyInst.size(); ++i) { 4304 Instruction *AOI = AssumeOnlyInst[i]; 4305 for (auto *Usr : AOI->users()) 4306 AssumeOnlyInst.insert(cast<Instruction>(Usr)); 4307 A.deleteAfterManifest(*AOI); 4308 } 4309 return ChangeStatus::CHANGED; 4310 } 4311 if (auto *FI = dyn_cast<FenceInst>(I)) { 4312 assert(isDeadFence(A, *FI)); 4313 A.deleteAfterManifest(*FI); 4314 return ChangeStatus::CHANGED; 4315 } 4316 if (isAssumedSideEffectFree(A, I) && !isa<InvokeInst>(I)) { 4317 A.deleteAfterManifest(*I); 4318 return ChangeStatus::CHANGED; 4319 } 4320 } 4321 return ChangeStatus::UNCHANGED; 4322 } 4323 4324 /// See AbstractAttribute::trackStatistics() 4325 void trackStatistics() const override { 4326 STATS_DECLTRACK_FLOATING_ATTR(IsDead) 4327 } 4328 4329 private: 4330 // The potential copies of a dead store, used for deletion during manifest. 4331 SmallSetVector<Value *, 4> PotentialCopies; 4332 }; 4333 4334 struct AAIsDeadArgument : public AAIsDeadFloating { 4335 AAIsDeadArgument(const IRPosition &IRP, Attributor &A) 4336 : AAIsDeadFloating(IRP, A) {} 4337 4338 /// See AbstractAttribute::manifest(...). 4339 ChangeStatus manifest(Attributor &A) override { 4340 Argument &Arg = *getAssociatedArgument(); 4341 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {})) 4342 if (A.registerFunctionSignatureRewrite( 4343 Arg, /* ReplacementTypes */ {}, 4344 Attributor::ArgumentReplacementInfo::CalleeRepairCBTy{}, 4345 Attributor::ArgumentReplacementInfo::ACSRepairCBTy{})) { 4346 return ChangeStatus::CHANGED; 4347 } 4348 return ChangeStatus::UNCHANGED; 4349 } 4350 4351 /// See AbstractAttribute::trackStatistics() 4352 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) } 4353 }; 4354 4355 struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl { 4356 AAIsDeadCallSiteArgument(const IRPosition &IRP, Attributor &A) 4357 : AAIsDeadValueImpl(IRP, A) {} 4358 4359 /// See AbstractAttribute::initialize(...). 4360 void initialize(Attributor &A) override { 4361 AAIsDeadValueImpl::initialize(A); 4362 if (isa<UndefValue>(getAssociatedValue())) 4363 indicatePessimisticFixpoint(); 4364 } 4365 4366 /// See AbstractAttribute::updateImpl(...). 4367 ChangeStatus updateImpl(Attributor &A) override { 4368 // TODO: Once we have call site specific value information we can provide 4369 // call site specific liveness information and then it makes 4370 // sense to specialize attributes for call sites arguments instead of 4371 // redirecting requests to the callee argument. 4372 Argument *Arg = getAssociatedArgument(); 4373 if (!Arg) 4374 return indicatePessimisticFixpoint(); 4375 const IRPosition &ArgPos = IRPosition::argument(*Arg); 4376 auto *ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos, DepClassTy::REQUIRED); 4377 if (!ArgAA) 4378 return indicatePessimisticFixpoint(); 4379 return clampStateAndIndicateChange(getState(), ArgAA->getState()); 4380 } 4381 4382 /// See AbstractAttribute::manifest(...). 4383 ChangeStatus manifest(Attributor &A) override { 4384 CallBase &CB = cast<CallBase>(getAnchorValue()); 4385 Use &U = CB.getArgOperandUse(getCallSiteArgNo()); 4386 assert(!isa<UndefValue>(U.get()) && 4387 "Expected undef values to be filtered out!"); 4388 UndefValue &UV = *UndefValue::get(U->getType()); 4389 if (A.changeUseAfterManifest(U, UV)) 4390 return ChangeStatus::CHANGED; 4391 return ChangeStatus::UNCHANGED; 4392 } 4393 4394 /// See AbstractAttribute::trackStatistics() 4395 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) } 4396 }; 4397 4398 struct AAIsDeadCallSiteReturned : public AAIsDeadFloating { 4399 AAIsDeadCallSiteReturned(const IRPosition &IRP, Attributor &A) 4400 : AAIsDeadFloating(IRP, A) {} 4401 4402 /// See AAIsDead::isAssumedDead(). 4403 bool isAssumedDead() const override { 4404 return AAIsDeadFloating::isAssumedDead() && IsAssumedSideEffectFree; 4405 } 4406 4407 /// See AbstractAttribute::initialize(...). 4408 void initialize(Attributor &A) override { 4409 AAIsDeadFloating::initialize(A); 4410 if (isa<UndefValue>(getAssociatedValue())) { 4411 indicatePessimisticFixpoint(); 4412 return; 4413 } 4414 4415 // We track this separately as a secondary state. 4416 IsAssumedSideEffectFree = isAssumedSideEffectFree(A, getCtxI()); 4417 } 4418 4419 /// See AbstractAttribute::updateImpl(...). 4420 ChangeStatus updateImpl(Attributor &A) override { 4421 ChangeStatus Changed = ChangeStatus::UNCHANGED; 4422 if (IsAssumedSideEffectFree && !isAssumedSideEffectFree(A, getCtxI())) { 4423 IsAssumedSideEffectFree = false; 4424 Changed = ChangeStatus::CHANGED; 4425 } 4426 if (!areAllUsesAssumedDead(A, getAssociatedValue())) 4427 return indicatePessimisticFixpoint(); 4428 return Changed; 4429 } 4430 4431 /// See AbstractAttribute::trackStatistics() 4432 void trackStatistics() const override { 4433 if (IsAssumedSideEffectFree) 4434 STATS_DECLTRACK_CSRET_ATTR(IsDead) 4435 else 4436 STATS_DECLTRACK_CSRET_ATTR(UnusedResult) 4437 } 4438 4439 /// See AbstractAttribute::getAsStr(). 4440 const std::string getAsStr(Attributor *A) const override { 4441 return isAssumedDead() 4442 ? "assumed-dead" 4443 : (getAssumed() ? "assumed-dead-users" : "assumed-live"); 4444 } 4445 4446 private: 4447 bool IsAssumedSideEffectFree = true; 4448 }; 4449 4450 struct AAIsDeadReturned : public AAIsDeadValueImpl { 4451 AAIsDeadReturned(const IRPosition &IRP, Attributor &A) 4452 : AAIsDeadValueImpl(IRP, A) {} 4453 4454 /// See AbstractAttribute::updateImpl(...). 4455 ChangeStatus updateImpl(Attributor &A) override { 4456 4457 bool UsedAssumedInformation = false; 4458 A.checkForAllInstructions([](Instruction &) { return true; }, *this, 4459 {Instruction::Ret}, UsedAssumedInformation); 4460 4461 auto PredForCallSite = [&](AbstractCallSite ACS) { 4462 if (ACS.isCallbackCall() || !ACS.getInstruction()) 4463 return false; 4464 return areAllUsesAssumedDead(A, *ACS.getInstruction()); 4465 }; 4466 4467 if (!A.checkForAllCallSites(PredForCallSite, *this, true, 4468 UsedAssumedInformation)) 4469 return indicatePessimisticFixpoint(); 4470 4471 return ChangeStatus::UNCHANGED; 4472 } 4473 4474 /// See AbstractAttribute::manifest(...). 4475 ChangeStatus manifest(Attributor &A) override { 4476 // TODO: Rewrite the signature to return void? 4477 bool AnyChange = false; 4478 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType()); 4479 auto RetInstPred = [&](Instruction &I) { 4480 ReturnInst &RI = cast<ReturnInst>(I); 4481 if (!isa<UndefValue>(RI.getReturnValue())) 4482 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV); 4483 return true; 4484 }; 4485 bool UsedAssumedInformation = false; 4486 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret}, 4487 UsedAssumedInformation); 4488 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 4489 } 4490 4491 /// See AbstractAttribute::trackStatistics() 4492 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) } 4493 }; 4494 4495 struct AAIsDeadFunction : public AAIsDead { 4496 AAIsDeadFunction(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {} 4497 4498 /// See AbstractAttribute::initialize(...). 4499 void initialize(Attributor &A) override { 4500 Function *F = getAnchorScope(); 4501 assert(F && "Did expect an anchor function"); 4502 if (!isAssumedDeadInternalFunction(A)) { 4503 ToBeExploredFrom.insert(&F->getEntryBlock().front()); 4504 assumeLive(A, F->getEntryBlock()); 4505 } 4506 } 4507 4508 bool isAssumedDeadInternalFunction(Attributor &A) { 4509 if (!getAnchorScope()->hasLocalLinkage()) 4510 return false; 4511 bool UsedAssumedInformation = false; 4512 return A.checkForAllCallSites([](AbstractCallSite) { return false; }, *this, 4513 true, UsedAssumedInformation); 4514 } 4515 4516 /// See AbstractAttribute::getAsStr(). 4517 const std::string getAsStr(Attributor *A) const override { 4518 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" + 4519 std::to_string(getAnchorScope()->size()) + "][#TBEP " + 4520 std::to_string(ToBeExploredFrom.size()) + "][#KDE " + 4521 std::to_string(KnownDeadEnds.size()) + "]"; 4522 } 4523 4524 /// See AbstractAttribute::manifest(...). 4525 ChangeStatus manifest(Attributor &A) override { 4526 assert(getState().isValidState() && 4527 "Attempted to manifest an invalid state!"); 4528 4529 ChangeStatus HasChanged = ChangeStatus::UNCHANGED; 4530 Function &F = *getAnchorScope(); 4531 4532 if (AssumedLiveBlocks.empty()) { 4533 A.deleteAfterManifest(F); 4534 return ChangeStatus::CHANGED; 4535 } 4536 4537 // Flag to determine if we can change an invoke to a call assuming the 4538 // callee is nounwind. This is not possible if the personality of the 4539 // function allows to catch asynchronous exceptions. 4540 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F); 4541 4542 KnownDeadEnds.set_union(ToBeExploredFrom); 4543 for (const Instruction *DeadEndI : KnownDeadEnds) { 4544 auto *CB = dyn_cast<CallBase>(DeadEndI); 4545 if (!CB) 4546 continue; 4547 bool IsKnownNoReturn; 4548 bool MayReturn = !AA::hasAssumedIRAttr<Attribute::NoReturn>( 4549 A, this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL, 4550 IsKnownNoReturn); 4551 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB))) 4552 continue; 4553 4554 if (auto *II = dyn_cast<InvokeInst>(DeadEndI)) 4555 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II)); 4556 else 4557 A.changeToUnreachableAfterManifest( 4558 const_cast<Instruction *>(DeadEndI->getNextNode())); 4559 HasChanged = ChangeStatus::CHANGED; 4560 } 4561 4562 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted."); 4563 for (BasicBlock &BB : F) 4564 if (!AssumedLiveBlocks.count(&BB)) { 4565 A.deleteAfterManifest(BB); 4566 ++BUILD_STAT_NAME(AAIsDead, BasicBlock); 4567 HasChanged = ChangeStatus::CHANGED; 4568 } 4569 4570 return HasChanged; 4571 } 4572 4573 /// See AbstractAttribute::updateImpl(...). 4574 ChangeStatus updateImpl(Attributor &A) override; 4575 4576 bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const override { 4577 assert(From->getParent() == getAnchorScope() && 4578 To->getParent() == getAnchorScope() && 4579 "Used AAIsDead of the wrong function"); 4580 return isValidState() && !AssumedLiveEdges.count(std::make_pair(From, To)); 4581 } 4582 4583 /// See AbstractAttribute::trackStatistics() 4584 void trackStatistics() const override {} 4585 4586 /// Returns true if the function is assumed dead. 4587 bool isAssumedDead() const override { return false; } 4588 4589 /// See AAIsDead::isKnownDead(). 4590 bool isKnownDead() const override { return false; } 4591 4592 /// See AAIsDead::isAssumedDead(BasicBlock *). 4593 bool isAssumedDead(const BasicBlock *BB) const override { 4594 assert(BB->getParent() == getAnchorScope() && 4595 "BB must be in the same anchor scope function."); 4596 4597 if (!getAssumed()) 4598 return false; 4599 return !AssumedLiveBlocks.count(BB); 4600 } 4601 4602 /// See AAIsDead::isKnownDead(BasicBlock *). 4603 bool isKnownDead(const BasicBlock *BB) const override { 4604 return getKnown() && isAssumedDead(BB); 4605 } 4606 4607 /// See AAIsDead::isAssumed(Instruction *I). 4608 bool isAssumedDead(const Instruction *I) const override { 4609 assert(I->getParent()->getParent() == getAnchorScope() && 4610 "Instruction must be in the same anchor scope function."); 4611 4612 if (!getAssumed()) 4613 return false; 4614 4615 // If it is not in AssumedLiveBlocks then it for sure dead. 4616 // Otherwise, it can still be after noreturn call in a live block. 4617 if (!AssumedLiveBlocks.count(I->getParent())) 4618 return true; 4619 4620 // If it is not after a liveness barrier it is live. 4621 const Instruction *PrevI = I->getPrevNode(); 4622 while (PrevI) { 4623 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI)) 4624 return true; 4625 PrevI = PrevI->getPrevNode(); 4626 } 4627 return false; 4628 } 4629 4630 /// See AAIsDead::isKnownDead(Instruction *I). 4631 bool isKnownDead(const Instruction *I) const override { 4632 return getKnown() && isAssumedDead(I); 4633 } 4634 4635 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A 4636 /// that internal function called from \p BB should now be looked at. 4637 bool assumeLive(Attributor &A, const BasicBlock &BB) { 4638 if (!AssumedLiveBlocks.insert(&BB).second) 4639 return false; 4640 4641 // We assume that all of BB is (probably) live now and if there are calls to 4642 // internal functions we will assume that those are now live as well. This 4643 // is a performance optimization for blocks with calls to a lot of internal 4644 // functions. It can however cause dead functions to be treated as live. 4645 for (const Instruction &I : BB) 4646 if (const auto *CB = dyn_cast<CallBase>(&I)) 4647 if (auto *F = dyn_cast_if_present<Function>(CB->getCalledOperand())) 4648 if (F->hasLocalLinkage()) 4649 A.markLiveInternalFunction(*F); 4650 return true; 4651 } 4652 4653 /// Collection of instructions that need to be explored again, e.g., we 4654 /// did assume they do not transfer control to (one of their) successors. 4655 SmallSetVector<const Instruction *, 8> ToBeExploredFrom; 4656 4657 /// Collection of instructions that are known to not transfer control. 4658 SmallSetVector<const Instruction *, 8> KnownDeadEnds; 4659 4660 /// Collection of all assumed live edges 4661 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> AssumedLiveEdges; 4662 4663 /// Collection of all assumed live BasicBlocks. 4664 DenseSet<const BasicBlock *> AssumedLiveBlocks; 4665 }; 4666 4667 static bool 4668 identifyAliveSuccessors(Attributor &A, const CallBase &CB, 4669 AbstractAttribute &AA, 4670 SmallVectorImpl<const Instruction *> &AliveSuccessors) { 4671 const IRPosition &IPos = IRPosition::callsite_function(CB); 4672 4673 bool IsKnownNoReturn; 4674 if (AA::hasAssumedIRAttr<Attribute::NoReturn>( 4675 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoReturn)) 4676 return !IsKnownNoReturn; 4677 if (CB.isTerminator()) 4678 AliveSuccessors.push_back(&CB.getSuccessor(0)->front()); 4679 else 4680 AliveSuccessors.push_back(CB.getNextNode()); 4681 return false; 4682 } 4683 4684 static bool 4685 identifyAliveSuccessors(Attributor &A, const InvokeInst &II, 4686 AbstractAttribute &AA, 4687 SmallVectorImpl<const Instruction *> &AliveSuccessors) { 4688 bool UsedAssumedInformation = 4689 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors); 4690 4691 // First, determine if we can change an invoke to a call assuming the 4692 // callee is nounwind. This is not possible if the personality of the 4693 // function allows to catch asynchronous exceptions. 4694 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) { 4695 AliveSuccessors.push_back(&II.getUnwindDest()->front()); 4696 } else { 4697 const IRPosition &IPos = IRPosition::callsite_function(II); 4698 4699 bool IsKnownNoUnwind; 4700 if (AA::hasAssumedIRAttr<Attribute::NoUnwind>( 4701 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) { 4702 UsedAssumedInformation |= !IsKnownNoUnwind; 4703 } else { 4704 AliveSuccessors.push_back(&II.getUnwindDest()->front()); 4705 } 4706 } 4707 return UsedAssumedInformation; 4708 } 4709 4710 static bool 4711 identifyAliveSuccessors(Attributor &A, const BranchInst &BI, 4712 AbstractAttribute &AA, 4713 SmallVectorImpl<const Instruction *> &AliveSuccessors) { 4714 bool UsedAssumedInformation = false; 4715 if (BI.getNumSuccessors() == 1) { 4716 AliveSuccessors.push_back(&BI.getSuccessor(0)->front()); 4717 } else { 4718 std::optional<Constant *> C = 4719 A.getAssumedConstant(*BI.getCondition(), AA, UsedAssumedInformation); 4720 if (!C || isa_and_nonnull<UndefValue>(*C)) { 4721 // No value yet, assume both edges are dead. 4722 } else if (isa_and_nonnull<ConstantInt>(*C)) { 4723 const BasicBlock *SuccBB = 4724 BI.getSuccessor(1 - cast<ConstantInt>(*C)->getValue().getZExtValue()); 4725 AliveSuccessors.push_back(&SuccBB->front()); 4726 } else { 4727 AliveSuccessors.push_back(&BI.getSuccessor(0)->front()); 4728 AliveSuccessors.push_back(&BI.getSuccessor(1)->front()); 4729 UsedAssumedInformation = false; 4730 } 4731 } 4732 return UsedAssumedInformation; 4733 } 4734 4735 static bool 4736 identifyAliveSuccessors(Attributor &A, const SwitchInst &SI, 4737 AbstractAttribute &AA, 4738 SmallVectorImpl<const Instruction *> &AliveSuccessors) { 4739 bool UsedAssumedInformation = false; 4740 SmallVector<AA::ValueAndContext> Values; 4741 if (!A.getAssumedSimplifiedValues(IRPosition::value(*SI.getCondition()), &AA, 4742 Values, AA::AnyScope, 4743 UsedAssumedInformation)) { 4744 // Something went wrong, assume all successors are live. 4745 for (const BasicBlock *SuccBB : successors(SI.getParent())) 4746 AliveSuccessors.push_back(&SuccBB->front()); 4747 return false; 4748 } 4749 4750 if (Values.empty() || 4751 (Values.size() == 1 && 4752 isa_and_nonnull<UndefValue>(Values.front().getValue()))) { 4753 // No valid value yet, assume all edges are dead. 4754 return UsedAssumedInformation; 4755 } 4756 4757 Type &Ty = *SI.getCondition()->getType(); 4758 SmallPtrSet<ConstantInt *, 8> Constants; 4759 auto CheckForConstantInt = [&](Value *V) { 4760 if (auto *CI = dyn_cast_if_present<ConstantInt>(AA::getWithType(*V, Ty))) { 4761 Constants.insert(CI); 4762 return true; 4763 } 4764 return false; 4765 }; 4766 4767 if (!all_of(Values, [&](AA::ValueAndContext &VAC) { 4768 return CheckForConstantInt(VAC.getValue()); 4769 })) { 4770 for (const BasicBlock *SuccBB : successors(SI.getParent())) 4771 AliveSuccessors.push_back(&SuccBB->front()); 4772 return UsedAssumedInformation; 4773 } 4774 4775 unsigned MatchedCases = 0; 4776 for (const auto &CaseIt : SI.cases()) { 4777 if (Constants.count(CaseIt.getCaseValue())) { 4778 ++MatchedCases; 4779 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front()); 4780 } 4781 } 4782 4783 // If all potential values have been matched, we will not visit the default 4784 // case. 4785 if (MatchedCases < Constants.size()) 4786 AliveSuccessors.push_back(&SI.getDefaultDest()->front()); 4787 return UsedAssumedInformation; 4788 } 4789 4790 ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) { 4791 ChangeStatus Change = ChangeStatus::UNCHANGED; 4792 4793 if (AssumedLiveBlocks.empty()) { 4794 if (isAssumedDeadInternalFunction(A)) 4795 return ChangeStatus::UNCHANGED; 4796 4797 Function *F = getAnchorScope(); 4798 ToBeExploredFrom.insert(&F->getEntryBlock().front()); 4799 assumeLive(A, F->getEntryBlock()); 4800 Change = ChangeStatus::CHANGED; 4801 } 4802 4803 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/" 4804 << getAnchorScope()->size() << "] BBs and " 4805 << ToBeExploredFrom.size() << " exploration points and " 4806 << KnownDeadEnds.size() << " known dead ends\n"); 4807 4808 // Copy and clear the list of instructions we need to explore from. It is 4809 // refilled with instructions the next update has to look at. 4810 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(), 4811 ToBeExploredFrom.end()); 4812 decltype(ToBeExploredFrom) NewToBeExploredFrom; 4813 4814 SmallVector<const Instruction *, 8> AliveSuccessors; 4815 while (!Worklist.empty()) { 4816 const Instruction *I = Worklist.pop_back_val(); 4817 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n"); 4818 4819 // Fast forward for uninteresting instructions. We could look for UB here 4820 // though. 4821 while (!I->isTerminator() && !isa<CallBase>(I)) 4822 I = I->getNextNode(); 4823 4824 AliveSuccessors.clear(); 4825 4826 bool UsedAssumedInformation = false; 4827 switch (I->getOpcode()) { 4828 // TODO: look for (assumed) UB to backwards propagate "deadness". 4829 default: 4830 assert(I->isTerminator() && 4831 "Expected non-terminators to be handled already!"); 4832 for (const BasicBlock *SuccBB : successors(I->getParent())) 4833 AliveSuccessors.push_back(&SuccBB->front()); 4834 break; 4835 case Instruction::Call: 4836 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I), 4837 *this, AliveSuccessors); 4838 break; 4839 case Instruction::Invoke: 4840 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I), 4841 *this, AliveSuccessors); 4842 break; 4843 case Instruction::Br: 4844 UsedAssumedInformation = identifyAliveSuccessors(A, cast<BranchInst>(*I), 4845 *this, AliveSuccessors); 4846 break; 4847 case Instruction::Switch: 4848 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I), 4849 *this, AliveSuccessors); 4850 break; 4851 } 4852 4853 if (UsedAssumedInformation) { 4854 NewToBeExploredFrom.insert(I); 4855 } else if (AliveSuccessors.empty() || 4856 (I->isTerminator() && 4857 AliveSuccessors.size() < I->getNumSuccessors())) { 4858 if (KnownDeadEnds.insert(I)) 4859 Change = ChangeStatus::CHANGED; 4860 } 4861 4862 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: " 4863 << AliveSuccessors.size() << " UsedAssumedInformation: " 4864 << UsedAssumedInformation << "\n"); 4865 4866 for (const Instruction *AliveSuccessor : AliveSuccessors) { 4867 if (!I->isTerminator()) { 4868 assert(AliveSuccessors.size() == 1 && 4869 "Non-terminator expected to have a single successor!"); 4870 Worklist.push_back(AliveSuccessor); 4871 } else { 4872 // record the assumed live edge 4873 auto Edge = std::make_pair(I->getParent(), AliveSuccessor->getParent()); 4874 if (AssumedLiveEdges.insert(Edge).second) 4875 Change = ChangeStatus::CHANGED; 4876 if (assumeLive(A, *AliveSuccessor->getParent())) 4877 Worklist.push_back(AliveSuccessor); 4878 } 4879 } 4880 } 4881 4882 // Check if the content of ToBeExploredFrom changed, ignore the order. 4883 if (NewToBeExploredFrom.size() != ToBeExploredFrom.size() || 4884 llvm::any_of(NewToBeExploredFrom, [&](const Instruction *I) { 4885 return !ToBeExploredFrom.count(I); 4886 })) { 4887 Change = ChangeStatus::CHANGED; 4888 ToBeExploredFrom = std::move(NewToBeExploredFrom); 4889 } 4890 4891 // If we know everything is live there is no need to query for liveness. 4892 // Instead, indicating a pessimistic fixpoint will cause the state to be 4893 // "invalid" and all queries to be answered conservatively without lookups. 4894 // To be in this state we have to (1) finished the exploration and (3) not 4895 // discovered any non-trivial dead end and (2) not ruled unreachable code 4896 // dead. 4897 if (ToBeExploredFrom.empty() && 4898 getAnchorScope()->size() == AssumedLiveBlocks.size() && 4899 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) { 4900 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0; 4901 })) 4902 return indicatePessimisticFixpoint(); 4903 return Change; 4904 } 4905 4906 /// Liveness information for a call sites. 4907 struct AAIsDeadCallSite final : AAIsDeadFunction { 4908 AAIsDeadCallSite(const IRPosition &IRP, Attributor &A) 4909 : AAIsDeadFunction(IRP, A) {} 4910 4911 /// See AbstractAttribute::initialize(...). 4912 void initialize(Attributor &A) override { 4913 // TODO: Once we have call site specific value information we can provide 4914 // call site specific liveness information and then it makes 4915 // sense to specialize attributes for call sites instead of 4916 // redirecting requests to the callee. 4917 llvm_unreachable("Abstract attributes for liveness are not " 4918 "supported for call sites yet!"); 4919 } 4920 4921 /// See AbstractAttribute::updateImpl(...). 4922 ChangeStatus updateImpl(Attributor &A) override { 4923 return indicatePessimisticFixpoint(); 4924 } 4925 4926 /// See AbstractAttribute::trackStatistics() 4927 void trackStatistics() const override {} 4928 }; 4929 } // namespace 4930 4931 /// -------------------- Dereferenceable Argument Attribute -------------------- 4932 4933 namespace { 4934 struct AADereferenceableImpl : AADereferenceable { 4935 AADereferenceableImpl(const IRPosition &IRP, Attributor &A) 4936 : AADereferenceable(IRP, A) {} 4937 using StateType = DerefState; 4938 4939 /// See AbstractAttribute::initialize(...). 4940 void initialize(Attributor &A) override { 4941 Value &V = *getAssociatedValue().stripPointerCasts(); 4942 SmallVector<Attribute, 4> Attrs; 4943 A.getAttrs(getIRPosition(), 4944 {Attribute::Dereferenceable, Attribute::DereferenceableOrNull}, 4945 Attrs, /* IgnoreSubsumingPositions */ false); 4946 for (const Attribute &Attr : Attrs) 4947 takeKnownDerefBytesMaximum(Attr.getValueAsInt()); 4948 4949 // Ensure we initialize the non-null AA (if necessary). 4950 bool IsKnownNonNull; 4951 AA::hasAssumedIRAttr<Attribute::NonNull>( 4952 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNonNull); 4953 4954 bool CanBeNull, CanBeFreed; 4955 takeKnownDerefBytesMaximum(V.getPointerDereferenceableBytes( 4956 A.getDataLayout(), CanBeNull, CanBeFreed)); 4957 4958 if (Instruction *CtxI = getCtxI()) 4959 followUsesInMBEC(*this, A, getState(), *CtxI); 4960 } 4961 4962 /// See AbstractAttribute::getState() 4963 /// { 4964 StateType &getState() override { return *this; } 4965 const StateType &getState() const override { return *this; } 4966 /// } 4967 4968 /// Helper function for collecting accessed bytes in must-be-executed-context 4969 void addAccessedBytesForUse(Attributor &A, const Use *U, const Instruction *I, 4970 DerefState &State) { 4971 const Value *UseV = U->get(); 4972 if (!UseV->getType()->isPointerTy()) 4973 return; 4974 4975 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I); 4976 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile()) 4977 return; 4978 4979 int64_t Offset; 4980 const Value *Base = GetPointerBaseWithConstantOffset( 4981 Loc->Ptr, Offset, A.getDataLayout(), /*AllowNonInbounds*/ true); 4982 if (Base && Base == &getAssociatedValue()) 4983 State.addAccessedBytes(Offset, Loc->Size.getValue()); 4984 } 4985 4986 /// See followUsesInMBEC 4987 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I, 4988 AADereferenceable::StateType &State) { 4989 bool IsNonNull = false; 4990 bool TrackUse = false; 4991 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse( 4992 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse); 4993 LLVM_DEBUG(dbgs() << "[AADereferenceable] Deref bytes: " << DerefBytes 4994 << " for instruction " << *I << "\n"); 4995 4996 addAccessedBytesForUse(A, U, I, State); 4997 State.takeKnownDerefBytesMaximum(DerefBytes); 4998 return TrackUse; 4999 } 5000 5001 /// See AbstractAttribute::manifest(...). 5002 ChangeStatus manifest(Attributor &A) override { 5003 ChangeStatus Change = AADereferenceable::manifest(A); 5004 bool IsKnownNonNull; 5005 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>( 5006 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull); 5007 if (IsAssumedNonNull && 5008 A.hasAttr(getIRPosition(), Attribute::DereferenceableOrNull)) { 5009 A.removeAttrs(getIRPosition(), {Attribute::DereferenceableOrNull}); 5010 return ChangeStatus::CHANGED; 5011 } 5012 return Change; 5013 } 5014 5015 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, 5016 SmallVectorImpl<Attribute> &Attrs) const override { 5017 // TODO: Add *_globally support 5018 bool IsKnownNonNull; 5019 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>( 5020 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull); 5021 if (IsAssumedNonNull) 5022 Attrs.emplace_back(Attribute::getWithDereferenceableBytes( 5023 Ctx, getAssumedDereferenceableBytes())); 5024 else 5025 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes( 5026 Ctx, getAssumedDereferenceableBytes())); 5027 } 5028 5029 /// See AbstractAttribute::getAsStr(). 5030 const std::string getAsStr(Attributor *A) const override { 5031 if (!getAssumedDereferenceableBytes()) 5032 return "unknown-dereferenceable"; 5033 bool IsKnownNonNull; 5034 bool IsAssumedNonNull = false; 5035 if (A) 5036 IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>( 5037 *A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull); 5038 return std::string("dereferenceable") + 5039 (IsAssumedNonNull ? "" : "_or_null") + 5040 (isAssumedGlobal() ? "_globally" : "") + "<" + 5041 std::to_string(getKnownDereferenceableBytes()) + "-" + 5042 std::to_string(getAssumedDereferenceableBytes()) + ">" + 5043 (!A ? " [non-null is unknown]" : ""); 5044 } 5045 }; 5046 5047 /// Dereferenceable attribute for a floating value. 5048 struct AADereferenceableFloating : AADereferenceableImpl { 5049 AADereferenceableFloating(const IRPosition &IRP, Attributor &A) 5050 : AADereferenceableImpl(IRP, A) {} 5051 5052 /// See AbstractAttribute::updateImpl(...). 5053 ChangeStatus updateImpl(Attributor &A) override { 5054 bool Stripped; 5055 bool UsedAssumedInformation = false; 5056 SmallVector<AA::ValueAndContext> Values; 5057 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values, 5058 AA::AnyScope, UsedAssumedInformation)) { 5059 Values.push_back({getAssociatedValue(), getCtxI()}); 5060 Stripped = false; 5061 } else { 5062 Stripped = Values.size() != 1 || 5063 Values.front().getValue() != &getAssociatedValue(); 5064 } 5065 5066 const DataLayout &DL = A.getDataLayout(); 5067 DerefState T; 5068 5069 auto VisitValueCB = [&](const Value &V) -> bool { 5070 unsigned IdxWidth = 5071 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace()); 5072 APInt Offset(IdxWidth, 0); 5073 const Value *Base = stripAndAccumulateOffsets( 5074 A, *this, &V, DL, Offset, /* GetMinOffset */ false, 5075 /* AllowNonInbounds */ true); 5076 5077 const auto *AA = A.getAAFor<AADereferenceable>( 5078 *this, IRPosition::value(*Base), DepClassTy::REQUIRED); 5079 int64_t DerefBytes = 0; 5080 if (!AA || (!Stripped && this == AA)) { 5081 // Use IR information if we did not strip anything. 5082 // TODO: track globally. 5083 bool CanBeNull, CanBeFreed; 5084 DerefBytes = 5085 Base->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed); 5086 T.GlobalState.indicatePessimisticFixpoint(); 5087 } else { 5088 const DerefState &DS = AA->getState(); 5089 DerefBytes = DS.DerefBytesState.getAssumed(); 5090 T.GlobalState &= DS.GlobalState; 5091 } 5092 5093 // For now we do not try to "increase" dereferenceability due to negative 5094 // indices as we first have to come up with code to deal with loops and 5095 // for overflows of the dereferenceable bytes. 5096 int64_t OffsetSExt = Offset.getSExtValue(); 5097 if (OffsetSExt < 0) 5098 OffsetSExt = 0; 5099 5100 T.takeAssumedDerefBytesMinimum( 5101 std::max(int64_t(0), DerefBytes - OffsetSExt)); 5102 5103 if (this == AA) { 5104 if (!Stripped) { 5105 // If nothing was stripped IR information is all we got. 5106 T.takeKnownDerefBytesMaximum( 5107 std::max(int64_t(0), DerefBytes - OffsetSExt)); 5108 T.indicatePessimisticFixpoint(); 5109 } else if (OffsetSExt > 0) { 5110 // If something was stripped but there is circular reasoning we look 5111 // for the offset. If it is positive we basically decrease the 5112 // dereferenceable bytes in a circular loop now, which will simply 5113 // drive them down to the known value in a very slow way which we 5114 // can accelerate. 5115 T.indicatePessimisticFixpoint(); 5116 } 5117 } 5118 5119 return T.isValidState(); 5120 }; 5121 5122 for (const auto &VAC : Values) 5123 if (!VisitValueCB(*VAC.getValue())) 5124 return indicatePessimisticFixpoint(); 5125 5126 return clampStateAndIndicateChange(getState(), T); 5127 } 5128 5129 /// See AbstractAttribute::trackStatistics() 5130 void trackStatistics() const override { 5131 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable) 5132 } 5133 }; 5134 5135 /// Dereferenceable attribute for a return value. 5136 struct AADereferenceableReturned final 5137 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> { 5138 using Base = 5139 AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>; 5140 AADereferenceableReturned(const IRPosition &IRP, Attributor &A) 5141 : Base(IRP, A) {} 5142 5143 /// See AbstractAttribute::trackStatistics() 5144 void trackStatistics() const override { 5145 STATS_DECLTRACK_FNRET_ATTR(dereferenceable) 5146 } 5147 }; 5148 5149 /// Dereferenceable attribute for an argument 5150 struct AADereferenceableArgument final 5151 : AAArgumentFromCallSiteArguments<AADereferenceable, 5152 AADereferenceableImpl> { 5153 using Base = 5154 AAArgumentFromCallSiteArguments<AADereferenceable, AADereferenceableImpl>; 5155 AADereferenceableArgument(const IRPosition &IRP, Attributor &A) 5156 : Base(IRP, A) {} 5157 5158 /// See AbstractAttribute::trackStatistics() 5159 void trackStatistics() const override { 5160 STATS_DECLTRACK_ARG_ATTR(dereferenceable) 5161 } 5162 }; 5163 5164 /// Dereferenceable attribute for a call site argument. 5165 struct AADereferenceableCallSiteArgument final : AADereferenceableFloating { 5166 AADereferenceableCallSiteArgument(const IRPosition &IRP, Attributor &A) 5167 : AADereferenceableFloating(IRP, A) {} 5168 5169 /// See AbstractAttribute::trackStatistics() 5170 void trackStatistics() const override { 5171 STATS_DECLTRACK_CSARG_ATTR(dereferenceable) 5172 } 5173 }; 5174 5175 /// Dereferenceable attribute deduction for a call site return value. 5176 struct AADereferenceableCallSiteReturned final 5177 : AACalleeToCallSite<AADereferenceable, AADereferenceableImpl> { 5178 using Base = AACalleeToCallSite<AADereferenceable, AADereferenceableImpl>; 5179 AADereferenceableCallSiteReturned(const IRPosition &IRP, Attributor &A) 5180 : Base(IRP, A) {} 5181 5182 /// See AbstractAttribute::trackStatistics() 5183 void trackStatistics() const override { 5184 STATS_DECLTRACK_CS_ATTR(dereferenceable); 5185 } 5186 }; 5187 } // namespace 5188 5189 // ------------------------ Align Argument Attribute ------------------------ 5190 5191 namespace { 5192 static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA, 5193 Value &AssociatedValue, const Use *U, 5194 const Instruction *I, bool &TrackUse) { 5195 // We need to follow common pointer manipulation uses to the accesses they 5196 // feed into. 5197 if (isa<CastInst>(I)) { 5198 // Follow all but ptr2int casts. 5199 TrackUse = !isa<PtrToIntInst>(I); 5200 return 0; 5201 } 5202 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) { 5203 if (GEP->hasAllConstantIndices()) 5204 TrackUse = true; 5205 return 0; 5206 } 5207 5208 MaybeAlign MA; 5209 if (const auto *CB = dyn_cast<CallBase>(I)) { 5210 if (CB->isBundleOperand(U) || CB->isCallee(U)) 5211 return 0; 5212 5213 unsigned ArgNo = CB->getArgOperandNo(U); 5214 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo); 5215 // As long as we only use known information there is no need to track 5216 // dependences here. 5217 auto *AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP, DepClassTy::NONE); 5218 if (AlignAA) 5219 MA = MaybeAlign(AlignAA->getKnownAlign()); 5220 } 5221 5222 const DataLayout &DL = A.getDataLayout(); 5223 const Value *UseV = U->get(); 5224 if (auto *SI = dyn_cast<StoreInst>(I)) { 5225 if (SI->getPointerOperand() == UseV) 5226 MA = SI->getAlign(); 5227 } else if (auto *LI = dyn_cast<LoadInst>(I)) { 5228 if (LI->getPointerOperand() == UseV) 5229 MA = LI->getAlign(); 5230 } else if (auto *AI = dyn_cast<AtomicRMWInst>(I)) { 5231 if (AI->getPointerOperand() == UseV) 5232 MA = AI->getAlign(); 5233 } else if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) { 5234 if (AI->getPointerOperand() == UseV) 5235 MA = AI->getAlign(); 5236 } 5237 5238 if (!MA || *MA <= QueryingAA.getKnownAlign()) 5239 return 0; 5240 5241 unsigned Alignment = MA->value(); 5242 int64_t Offset; 5243 5244 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) { 5245 if (Base == &AssociatedValue) { 5246 // BasePointerAddr + Offset = Alignment * Q for some integer Q. 5247 // So we can say that the maximum power of two which is a divisor of 5248 // gcd(Offset, Alignment) is an alignment. 5249 5250 uint32_t gcd = std::gcd(uint32_t(abs((int32_t)Offset)), Alignment); 5251 Alignment = llvm::bit_floor(gcd); 5252 } 5253 } 5254 5255 return Alignment; 5256 } 5257 5258 struct AAAlignImpl : AAAlign { 5259 AAAlignImpl(const IRPosition &IRP, Attributor &A) : AAAlign(IRP, A) {} 5260 5261 /// See AbstractAttribute::initialize(...). 5262 void initialize(Attributor &A) override { 5263 SmallVector<Attribute, 4> Attrs; 5264 A.getAttrs(getIRPosition(), {Attribute::Alignment}, Attrs); 5265 for (const Attribute &Attr : Attrs) 5266 takeKnownMaximum(Attr.getValueAsInt()); 5267 5268 Value &V = *getAssociatedValue().stripPointerCasts(); 5269 takeKnownMaximum(V.getPointerAlignment(A.getDataLayout()).value()); 5270 5271 if (Instruction *CtxI = getCtxI()) 5272 followUsesInMBEC(*this, A, getState(), *CtxI); 5273 } 5274 5275 /// See AbstractAttribute::manifest(...). 5276 ChangeStatus manifest(Attributor &A) override { 5277 ChangeStatus InstrChanged = ChangeStatus::UNCHANGED; 5278 5279 // Check for users that allow alignment annotations. 5280 Value &AssociatedValue = getAssociatedValue(); 5281 if (isa<ConstantData>(AssociatedValue)) 5282 return ChangeStatus::UNCHANGED; 5283 5284 for (const Use &U : AssociatedValue.uses()) { 5285 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) { 5286 if (SI->getPointerOperand() == &AssociatedValue) 5287 if (SI->getAlign() < getAssumedAlign()) { 5288 STATS_DECLTRACK(AAAlign, Store, 5289 "Number of times alignment added to a store"); 5290 SI->setAlignment(getAssumedAlign()); 5291 InstrChanged = ChangeStatus::CHANGED; 5292 } 5293 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) { 5294 if (LI->getPointerOperand() == &AssociatedValue) 5295 if (LI->getAlign() < getAssumedAlign()) { 5296 LI->setAlignment(getAssumedAlign()); 5297 STATS_DECLTRACK(AAAlign, Load, 5298 "Number of times alignment added to a load"); 5299 InstrChanged = ChangeStatus::CHANGED; 5300 } 5301 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(U.getUser())) { 5302 if (RMW->getPointerOperand() == &AssociatedValue) { 5303 if (RMW->getAlign() < getAssumedAlign()) { 5304 STATS_DECLTRACK(AAAlign, AtomicRMW, 5305 "Number of times alignment added to atomicrmw"); 5306 5307 RMW->setAlignment(getAssumedAlign()); 5308 InstrChanged = ChangeStatus::CHANGED; 5309 } 5310 } 5311 } else if (auto *CAS = dyn_cast<AtomicCmpXchgInst>(U.getUser())) { 5312 if (CAS->getPointerOperand() == &AssociatedValue) { 5313 if (CAS->getAlign() < getAssumedAlign()) { 5314 STATS_DECLTRACK(AAAlign, AtomicCmpXchg, 5315 "Number of times alignment added to cmpxchg"); 5316 CAS->setAlignment(getAssumedAlign()); 5317 InstrChanged = ChangeStatus::CHANGED; 5318 } 5319 } 5320 } 5321 } 5322 5323 ChangeStatus Changed = AAAlign::manifest(A); 5324 5325 Align InheritAlign = 5326 getAssociatedValue().getPointerAlignment(A.getDataLayout()); 5327 if (InheritAlign >= getAssumedAlign()) 5328 return InstrChanged; 5329 return Changed | InstrChanged; 5330 } 5331 5332 // TODO: Provide a helper to determine the implied ABI alignment and check in 5333 // the existing manifest method and a new one for AAAlignImpl that value 5334 // to avoid making the alignment explicit if it did not improve. 5335 5336 /// See AbstractAttribute::getDeducedAttributes 5337 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, 5338 SmallVectorImpl<Attribute> &Attrs) const override { 5339 if (getAssumedAlign() > 1) 5340 Attrs.emplace_back( 5341 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign()))); 5342 } 5343 5344 /// See followUsesInMBEC 5345 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I, 5346 AAAlign::StateType &State) { 5347 bool TrackUse = false; 5348 5349 unsigned int KnownAlign = 5350 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse); 5351 State.takeKnownMaximum(KnownAlign); 5352 5353 return TrackUse; 5354 } 5355 5356 /// See AbstractAttribute::getAsStr(). 5357 const std::string getAsStr(Attributor *A) const override { 5358 return "align<" + std::to_string(getKnownAlign().value()) + "-" + 5359 std::to_string(getAssumedAlign().value()) + ">"; 5360 } 5361 }; 5362 5363 /// Align attribute for a floating value. 5364 struct AAAlignFloating : AAAlignImpl { 5365 AAAlignFloating(const IRPosition &IRP, Attributor &A) : AAAlignImpl(IRP, A) {} 5366 5367 /// See AbstractAttribute::updateImpl(...). 5368 ChangeStatus updateImpl(Attributor &A) override { 5369 const DataLayout &DL = A.getDataLayout(); 5370 5371 bool Stripped; 5372 bool UsedAssumedInformation = false; 5373 SmallVector<AA::ValueAndContext> Values; 5374 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values, 5375 AA::AnyScope, UsedAssumedInformation)) { 5376 Values.push_back({getAssociatedValue(), getCtxI()}); 5377 Stripped = false; 5378 } else { 5379 Stripped = Values.size() != 1 || 5380 Values.front().getValue() != &getAssociatedValue(); 5381 } 5382 5383 StateType T; 5384 auto VisitValueCB = [&](Value &V) -> bool { 5385 if (isa<UndefValue>(V) || isa<ConstantPointerNull>(V)) 5386 return true; 5387 const auto *AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V), 5388 DepClassTy::REQUIRED); 5389 if (!AA || (!Stripped && this == AA)) { 5390 int64_t Offset; 5391 unsigned Alignment = 1; 5392 if (const Value *Base = 5393 GetPointerBaseWithConstantOffset(&V, Offset, DL)) { 5394 // TODO: Use AAAlign for the base too. 5395 Align PA = Base->getPointerAlignment(DL); 5396 // BasePointerAddr + Offset = Alignment * Q for some integer Q. 5397 // So we can say that the maximum power of two which is a divisor of 5398 // gcd(Offset, Alignment) is an alignment. 5399 5400 uint32_t gcd = 5401 std::gcd(uint32_t(abs((int32_t)Offset)), uint32_t(PA.value())); 5402 Alignment = llvm::bit_floor(gcd); 5403 } else { 5404 Alignment = V.getPointerAlignment(DL).value(); 5405 } 5406 // Use only IR information if we did not strip anything. 5407 T.takeKnownMaximum(Alignment); 5408 T.indicatePessimisticFixpoint(); 5409 } else { 5410 // Use abstract attribute information. 5411 const AAAlign::StateType &DS = AA->getState(); 5412 T ^= DS; 5413 } 5414 return T.isValidState(); 5415 }; 5416 5417 for (const auto &VAC : Values) { 5418 if (!VisitValueCB(*VAC.getValue())) 5419 return indicatePessimisticFixpoint(); 5420 } 5421 5422 // TODO: If we know we visited all incoming values, thus no are assumed 5423 // dead, we can take the known information from the state T. 5424 return clampStateAndIndicateChange(getState(), T); 5425 } 5426 5427 /// See AbstractAttribute::trackStatistics() 5428 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) } 5429 }; 5430 5431 /// Align attribute for function return value. 5432 struct AAAlignReturned final 5433 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> { 5434 using Base = AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>; 5435 AAAlignReturned(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {} 5436 5437 /// See AbstractAttribute::trackStatistics() 5438 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) } 5439 }; 5440 5441 /// Align attribute for function argument. 5442 struct AAAlignArgument final 5443 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> { 5444 using Base = AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>; 5445 AAAlignArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {} 5446 5447 /// See AbstractAttribute::manifest(...). 5448 ChangeStatus manifest(Attributor &A) override { 5449 // If the associated argument is involved in a must-tail call we give up 5450 // because we would need to keep the argument alignments of caller and 5451 // callee in-sync. Just does not seem worth the trouble right now. 5452 if (A.getInfoCache().isInvolvedInMustTailCall(*getAssociatedArgument())) 5453 return ChangeStatus::UNCHANGED; 5454 return Base::manifest(A); 5455 } 5456 5457 /// See AbstractAttribute::trackStatistics() 5458 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) } 5459 }; 5460 5461 struct AAAlignCallSiteArgument final : AAAlignFloating { 5462 AAAlignCallSiteArgument(const IRPosition &IRP, Attributor &A) 5463 : AAAlignFloating(IRP, A) {} 5464 5465 /// See AbstractAttribute::manifest(...). 5466 ChangeStatus manifest(Attributor &A) override { 5467 // If the associated argument is involved in a must-tail call we give up 5468 // because we would need to keep the argument alignments of caller and 5469 // callee in-sync. Just does not seem worth the trouble right now. 5470 if (Argument *Arg = getAssociatedArgument()) 5471 if (A.getInfoCache().isInvolvedInMustTailCall(*Arg)) 5472 return ChangeStatus::UNCHANGED; 5473 ChangeStatus Changed = AAAlignImpl::manifest(A); 5474 Align InheritAlign = 5475 getAssociatedValue().getPointerAlignment(A.getDataLayout()); 5476 if (InheritAlign >= getAssumedAlign()) 5477 Changed = ChangeStatus::UNCHANGED; 5478 return Changed; 5479 } 5480 5481 /// See AbstractAttribute::updateImpl(Attributor &A). 5482 ChangeStatus updateImpl(Attributor &A) override { 5483 ChangeStatus Changed = AAAlignFloating::updateImpl(A); 5484 if (Argument *Arg = getAssociatedArgument()) { 5485 // We only take known information from the argument 5486 // so we do not need to track a dependence. 5487 const auto *ArgAlignAA = A.getAAFor<AAAlign>( 5488 *this, IRPosition::argument(*Arg), DepClassTy::NONE); 5489 if (ArgAlignAA) 5490 takeKnownMaximum(ArgAlignAA->getKnownAlign().value()); 5491 } 5492 return Changed; 5493 } 5494 5495 /// See AbstractAttribute::trackStatistics() 5496 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) } 5497 }; 5498 5499 /// Align attribute deduction for a call site return value. 5500 struct AAAlignCallSiteReturned final 5501 : AACalleeToCallSite<AAAlign, AAAlignImpl> { 5502 using Base = AACalleeToCallSite<AAAlign, AAAlignImpl>; 5503 AAAlignCallSiteReturned(const IRPosition &IRP, Attributor &A) 5504 : Base(IRP, A) {} 5505 5506 /// See AbstractAttribute::trackStatistics() 5507 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); } 5508 }; 5509 } // namespace 5510 5511 /// ------------------ Function No-Return Attribute ---------------------------- 5512 namespace { 5513 struct AANoReturnImpl : public AANoReturn { 5514 AANoReturnImpl(const IRPosition &IRP, Attributor &A) : AANoReturn(IRP, A) {} 5515 5516 /// See AbstractAttribute::initialize(...). 5517 void initialize(Attributor &A) override { 5518 bool IsKnown; 5519 assert(!AA::hasAssumedIRAttr<Attribute::NoReturn>( 5520 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown)); 5521 (void)IsKnown; 5522 } 5523 5524 /// See AbstractAttribute::getAsStr(). 5525 const std::string getAsStr(Attributor *A) const override { 5526 return getAssumed() ? "noreturn" : "may-return"; 5527 } 5528 5529 /// See AbstractAttribute::updateImpl(Attributor &A). 5530 ChangeStatus updateImpl(Attributor &A) override { 5531 auto CheckForNoReturn = [](Instruction &) { return false; }; 5532 bool UsedAssumedInformation = false; 5533 if (!A.checkForAllInstructions(CheckForNoReturn, *this, 5534 {(unsigned)Instruction::Ret}, 5535 UsedAssumedInformation)) 5536 return indicatePessimisticFixpoint(); 5537 return ChangeStatus::UNCHANGED; 5538 } 5539 }; 5540 5541 struct AANoReturnFunction final : AANoReturnImpl { 5542 AANoReturnFunction(const IRPosition &IRP, Attributor &A) 5543 : AANoReturnImpl(IRP, A) {} 5544 5545 /// See AbstractAttribute::trackStatistics() 5546 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) } 5547 }; 5548 5549 /// NoReturn attribute deduction for a call sites. 5550 struct AANoReturnCallSite final 5551 : AACalleeToCallSite<AANoReturn, AANoReturnImpl> { 5552 AANoReturnCallSite(const IRPosition &IRP, Attributor &A) 5553 : AACalleeToCallSite<AANoReturn, AANoReturnImpl>(IRP, A) {} 5554 5555 /// See AbstractAttribute::trackStatistics() 5556 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); } 5557 }; 5558 } // namespace 5559 5560 /// ----------------------- Instance Info --------------------------------- 5561 5562 namespace { 5563 /// A class to hold the state of for no-capture attributes. 5564 struct AAInstanceInfoImpl : public AAInstanceInfo { 5565 AAInstanceInfoImpl(const IRPosition &IRP, Attributor &A) 5566 : AAInstanceInfo(IRP, A) {} 5567 5568 /// See AbstractAttribute::initialize(...). 5569 void initialize(Attributor &A) override { 5570 Value &V = getAssociatedValue(); 5571 if (auto *C = dyn_cast<Constant>(&V)) { 5572 if (C->isThreadDependent()) 5573 indicatePessimisticFixpoint(); 5574 else 5575 indicateOptimisticFixpoint(); 5576 return; 5577 } 5578 if (auto *CB = dyn_cast<CallBase>(&V)) 5579 if (CB->arg_size() == 0 && !CB->mayHaveSideEffects() && 5580 !CB->mayReadFromMemory()) { 5581 indicateOptimisticFixpoint(); 5582 return; 5583 } 5584 if (auto *I = dyn_cast<Instruction>(&V)) { 5585 const auto *CI = 5586 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>( 5587 *I->getFunction()); 5588 if (mayBeInCycle(CI, I, /* HeaderOnly */ false)) { 5589 indicatePessimisticFixpoint(); 5590 return; 5591 } 5592 } 5593 } 5594 5595 /// See AbstractAttribute::updateImpl(...). 5596 ChangeStatus updateImpl(Attributor &A) override { 5597 ChangeStatus Changed = ChangeStatus::UNCHANGED; 5598 5599 Value &V = getAssociatedValue(); 5600 const Function *Scope = nullptr; 5601 if (auto *I = dyn_cast<Instruction>(&V)) 5602 Scope = I->getFunction(); 5603 if (auto *A = dyn_cast<Argument>(&V)) { 5604 Scope = A->getParent(); 5605 if (!Scope->hasLocalLinkage()) 5606 return Changed; 5607 } 5608 if (!Scope) 5609 return indicateOptimisticFixpoint(); 5610 5611 bool IsKnownNoRecurse; 5612 if (AA::hasAssumedIRAttr<Attribute::NoRecurse>( 5613 A, this, IRPosition::function(*Scope), DepClassTy::OPTIONAL, 5614 IsKnownNoRecurse)) 5615 return Changed; 5616 5617 auto UsePred = [&](const Use &U, bool &Follow) { 5618 const Instruction *UserI = dyn_cast<Instruction>(U.getUser()); 5619 if (!UserI || isa<GetElementPtrInst>(UserI) || isa<CastInst>(UserI) || 5620 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) { 5621 Follow = true; 5622 return true; 5623 } 5624 if (isa<LoadInst>(UserI) || isa<CmpInst>(UserI) || 5625 (isa<StoreInst>(UserI) && 5626 cast<StoreInst>(UserI)->getValueOperand() != U.get())) 5627 return true; 5628 if (auto *CB = dyn_cast<CallBase>(UserI)) { 5629 // This check is not guaranteeing uniqueness but for now that we cannot 5630 // end up with two versions of \p U thinking it was one. 5631 auto *Callee = dyn_cast_if_present<Function>(CB->getCalledOperand()); 5632 if (!Callee || !Callee->hasLocalLinkage()) 5633 return true; 5634 if (!CB->isArgOperand(&U)) 5635 return false; 5636 const auto *ArgInstanceInfoAA = A.getAAFor<AAInstanceInfo>( 5637 *this, IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U)), 5638 DepClassTy::OPTIONAL); 5639 if (!ArgInstanceInfoAA || 5640 !ArgInstanceInfoAA->isAssumedUniqueForAnalysis()) 5641 return false; 5642 // If this call base might reach the scope again we might forward the 5643 // argument back here. This is very conservative. 5644 if (AA::isPotentiallyReachable( 5645 A, *CB, *Scope, *this, /* ExclusionSet */ nullptr, 5646 [Scope](const Function &Fn) { return &Fn != Scope; })) 5647 return false; 5648 return true; 5649 } 5650 return false; 5651 }; 5652 5653 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) { 5654 if (auto *SI = dyn_cast<StoreInst>(OldU.getUser())) { 5655 auto *Ptr = SI->getPointerOperand()->stripPointerCasts(); 5656 if ((isa<AllocaInst>(Ptr) || isNoAliasCall(Ptr)) && 5657 AA::isDynamicallyUnique(A, *this, *Ptr)) 5658 return true; 5659 } 5660 return false; 5661 }; 5662 5663 if (!A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ true, 5664 DepClassTy::OPTIONAL, 5665 /* IgnoreDroppableUses */ true, EquivalentUseCB)) 5666 return indicatePessimisticFixpoint(); 5667 5668 return Changed; 5669 } 5670 5671 /// See AbstractState::getAsStr(). 5672 const std::string getAsStr(Attributor *A) const override { 5673 return isAssumedUniqueForAnalysis() ? "<unique [fAa]>" : "<unknown>"; 5674 } 5675 5676 /// See AbstractAttribute::trackStatistics() 5677 void trackStatistics() const override {} 5678 }; 5679 5680 /// InstanceInfo attribute for floating values. 5681 struct AAInstanceInfoFloating : AAInstanceInfoImpl { 5682 AAInstanceInfoFloating(const IRPosition &IRP, Attributor &A) 5683 : AAInstanceInfoImpl(IRP, A) {} 5684 }; 5685 5686 /// NoCapture attribute for function arguments. 5687 struct AAInstanceInfoArgument final : AAInstanceInfoFloating { 5688 AAInstanceInfoArgument(const IRPosition &IRP, Attributor &A) 5689 : AAInstanceInfoFloating(IRP, A) {} 5690 }; 5691 5692 /// InstanceInfo attribute for call site arguments. 5693 struct AAInstanceInfoCallSiteArgument final : AAInstanceInfoImpl { 5694 AAInstanceInfoCallSiteArgument(const IRPosition &IRP, Attributor &A) 5695 : AAInstanceInfoImpl(IRP, A) {} 5696 5697 /// See AbstractAttribute::updateImpl(...). 5698 ChangeStatus updateImpl(Attributor &A) override { 5699 // TODO: Once we have call site specific value information we can provide 5700 // call site specific liveness information and then it makes 5701 // sense to specialize attributes for call sites arguments instead of 5702 // redirecting requests to the callee argument. 5703 Argument *Arg = getAssociatedArgument(); 5704 if (!Arg) 5705 return indicatePessimisticFixpoint(); 5706 const IRPosition &ArgPos = IRPosition::argument(*Arg); 5707 auto *ArgAA = 5708 A.getAAFor<AAInstanceInfo>(*this, ArgPos, DepClassTy::REQUIRED); 5709 if (!ArgAA) 5710 return indicatePessimisticFixpoint(); 5711 return clampStateAndIndicateChange(getState(), ArgAA->getState()); 5712 } 5713 }; 5714 5715 /// InstanceInfo attribute for function return value. 5716 struct AAInstanceInfoReturned final : AAInstanceInfoImpl { 5717 AAInstanceInfoReturned(const IRPosition &IRP, Attributor &A) 5718 : AAInstanceInfoImpl(IRP, A) { 5719 llvm_unreachable("InstanceInfo is not applicable to function returns!"); 5720 } 5721 5722 /// See AbstractAttribute::initialize(...). 5723 void initialize(Attributor &A) override { 5724 llvm_unreachable("InstanceInfo is not applicable to function returns!"); 5725 } 5726 5727 /// See AbstractAttribute::updateImpl(...). 5728 ChangeStatus updateImpl(Attributor &A) override { 5729 llvm_unreachable("InstanceInfo is not applicable to function returns!"); 5730 } 5731 }; 5732 5733 /// InstanceInfo attribute deduction for a call site return value. 5734 struct AAInstanceInfoCallSiteReturned final : AAInstanceInfoFloating { 5735 AAInstanceInfoCallSiteReturned(const IRPosition &IRP, Attributor &A) 5736 : AAInstanceInfoFloating(IRP, A) {} 5737 }; 5738 } // namespace 5739 5740 /// ----------------------- Variable Capturing --------------------------------- 5741 bool AANoCapture::isImpliedByIR(Attributor &A, const IRPosition &IRP, 5742 Attribute::AttrKind ImpliedAttributeKind, 5743 bool IgnoreSubsumingPositions) { 5744 assert(ImpliedAttributeKind == Attribute::Captures && 5745 "Unexpected attribute kind"); 5746 Value &V = IRP.getAssociatedValue(); 5747 if (!isa<Constant>(V) && !IRP.isArgumentPosition()) 5748 return V.use_empty(); 5749 5750 // You cannot "capture" null in the default address space. 5751 // 5752 // FIXME: This should use NullPointerIsDefined to account for the function 5753 // attribute. 5754 if (isa<UndefValue>(V) || (isa<ConstantPointerNull>(V) && 5755 V.getType()->getPointerAddressSpace() == 0)) { 5756 return true; 5757 } 5758 5759 SmallVector<Attribute, 1> Attrs; 5760 A.getAttrs(IRP, {Attribute::Captures}, Attrs, 5761 /* IgnoreSubsumingPositions */ true); 5762 for (const Attribute &Attr : Attrs) 5763 if (capturesNothing(Attr.getCaptureInfo())) 5764 return true; 5765 5766 if (IRP.getPositionKind() == IRP_CALL_SITE_ARGUMENT) 5767 if (Argument *Arg = IRP.getAssociatedArgument()) { 5768 SmallVector<Attribute, 1> Attrs; 5769 A.getAttrs(IRPosition::argument(*Arg), 5770 {Attribute::Captures, Attribute::ByVal}, Attrs, 5771 /* IgnoreSubsumingPositions */ true); 5772 bool ArgNoCapture = any_of(Attrs, [](Attribute Attr) { 5773 return Attr.getKindAsEnum() == Attribute::ByVal || 5774 capturesNothing(Attr.getCaptureInfo()); 5775 }); 5776 if (ArgNoCapture) { 5777 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo( 5778 V.getContext(), CaptureInfo::none())); 5779 return true; 5780 } 5781 } 5782 5783 if (const Function *F = IRP.getAssociatedFunction()) { 5784 // Check what state the associated function can actually capture. 5785 AANoCapture::StateType State; 5786 determineFunctionCaptureCapabilities(IRP, *F, State); 5787 if (State.isKnown(NO_CAPTURE)) { 5788 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(V.getContext(), 5789 CaptureInfo::none())); 5790 return true; 5791 } 5792 } 5793 5794 return false; 5795 } 5796 5797 /// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known 5798 /// depending on the ability of the function associated with \p IRP to capture 5799 /// state in memory and through "returning/throwing", respectively. 5800 void AANoCapture::determineFunctionCaptureCapabilities(const IRPosition &IRP, 5801 const Function &F, 5802 BitIntegerState &State) { 5803 // TODO: Once we have memory behavior attributes we should use them here. 5804 5805 // If we know we cannot communicate or write to memory, we do not care about 5806 // ptr2int anymore. 5807 bool ReadOnly = F.onlyReadsMemory(); 5808 bool NoThrow = F.doesNotThrow(); 5809 bool IsVoidReturn = F.getReturnType()->isVoidTy(); 5810 if (ReadOnly && NoThrow && IsVoidReturn) { 5811 State.addKnownBits(NO_CAPTURE); 5812 return; 5813 } 5814 5815 // A function cannot capture state in memory if it only reads memory, it can 5816 // however return/throw state and the state might be influenced by the 5817 // pointer value, e.g., loading from a returned pointer might reveal a bit. 5818 if (ReadOnly) 5819 State.addKnownBits(NOT_CAPTURED_IN_MEM); 5820 5821 // A function cannot communicate state back if it does not through 5822 // exceptions and doesn not return values. 5823 if (NoThrow && IsVoidReturn) 5824 State.addKnownBits(NOT_CAPTURED_IN_RET); 5825 5826 // Check existing "returned" attributes. 5827 int ArgNo = IRP.getCalleeArgNo(); 5828 if (!NoThrow || ArgNo < 0 || 5829 !F.getAttributes().hasAttrSomewhere(Attribute::Returned)) 5830 return; 5831 5832 for (unsigned U = 0, E = F.arg_size(); U < E; ++U) 5833 if (F.hasParamAttribute(U, Attribute::Returned)) { 5834 if (U == unsigned(ArgNo)) 5835 State.removeAssumedBits(NOT_CAPTURED_IN_RET); 5836 else if (ReadOnly) 5837 State.addKnownBits(NO_CAPTURE); 5838 else 5839 State.addKnownBits(NOT_CAPTURED_IN_RET); 5840 break; 5841 } 5842 } 5843 5844 namespace { 5845 /// A class to hold the state of for no-capture attributes. 5846 struct AANoCaptureImpl : public AANoCapture { 5847 AANoCaptureImpl(const IRPosition &IRP, Attributor &A) : AANoCapture(IRP, A) {} 5848 5849 /// See AbstractAttribute::initialize(...). 5850 void initialize(Attributor &A) override { 5851 bool IsKnown; 5852 assert(!AA::hasAssumedIRAttr<Attribute::Captures>( 5853 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown)); 5854 (void)IsKnown; 5855 } 5856 5857 /// See AbstractAttribute::updateImpl(...). 5858 ChangeStatus updateImpl(Attributor &A) override; 5859 5860 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...). 5861 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, 5862 SmallVectorImpl<Attribute> &Attrs) const override { 5863 if (!isAssumedNoCaptureMaybeReturned()) 5864 return; 5865 5866 if (isArgumentPosition()) { 5867 if (isAssumedNoCapture()) 5868 Attrs.emplace_back(Attribute::get(Ctx, Attribute::Captures)); 5869 else if (ManifestInternal) 5870 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned")); 5871 } 5872 } 5873 5874 /// See AbstractState::getAsStr(). 5875 const std::string getAsStr(Attributor *A) const override { 5876 if (isKnownNoCapture()) 5877 return "known not-captured"; 5878 if (isAssumedNoCapture()) 5879 return "assumed not-captured"; 5880 if (isKnownNoCaptureMaybeReturned()) 5881 return "known not-captured-maybe-returned"; 5882 if (isAssumedNoCaptureMaybeReturned()) 5883 return "assumed not-captured-maybe-returned"; 5884 return "assumed-captured"; 5885 } 5886 5887 /// Check the use \p U and update \p State accordingly. Return true if we 5888 /// should continue to update the state. 5889 bool checkUse(Attributor &A, AANoCapture::StateType &State, const Use &U, 5890 bool &Follow) { 5891 Instruction *UInst = cast<Instruction>(U.getUser()); 5892 LLVM_DEBUG(dbgs() << "[AANoCapture] Check use: " << *U.get() << " in " 5893 << *UInst << "\n"); 5894 5895 // Deal with ptr2int by following uses. 5896 if (isa<PtrToIntInst>(UInst)) { 5897 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n"); 5898 return isCapturedIn(State, /* Memory */ true, /* Integer */ true, 5899 /* Return */ true); 5900 } 5901 5902 // For stores we already checked if we can follow them, if they make it 5903 // here we give up. 5904 if (isa<StoreInst>(UInst)) 5905 return isCapturedIn(State, /* Memory */ true, /* Integer */ true, 5906 /* Return */ true); 5907 5908 // Explicitly catch return instructions. 5909 if (isa<ReturnInst>(UInst)) { 5910 if (UInst->getFunction() == getAnchorScope()) 5911 return isCapturedIn(State, /* Memory */ false, /* Integer */ false, 5912 /* Return */ true); 5913 return isCapturedIn(State, /* Memory */ true, /* Integer */ true, 5914 /* Return */ true); 5915 } 5916 5917 // For now we only use special logic for call sites. However, the tracker 5918 // itself knows about a lot of other non-capturing cases already. 5919 auto *CB = dyn_cast<CallBase>(UInst); 5920 if (!CB || !CB->isArgOperand(&U)) 5921 return isCapturedIn(State, /* Memory */ true, /* Integer */ true, 5922 /* Return */ true); 5923 5924 unsigned ArgNo = CB->getArgOperandNo(&U); 5925 const IRPosition &CSArgPos = IRPosition::callsite_argument(*CB, ArgNo); 5926 // If we have a abstract no-capture attribute for the argument we can use 5927 // it to justify a non-capture attribute here. This allows recursion! 5928 bool IsKnownNoCapture; 5929 const AANoCapture *ArgNoCaptureAA = nullptr; 5930 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>( 5931 A, this, CSArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false, 5932 &ArgNoCaptureAA); 5933 if (IsAssumedNoCapture) 5934 return isCapturedIn(State, /* Memory */ false, /* Integer */ false, 5935 /* Return */ false); 5936 if (ArgNoCaptureAA && ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned()) { 5937 Follow = true; 5938 return isCapturedIn(State, /* Memory */ false, /* Integer */ false, 5939 /* Return */ false); 5940 } 5941 5942 // Lastly, we could not find a reason no-capture can be assumed so we don't. 5943 return isCapturedIn(State, /* Memory */ true, /* Integer */ true, 5944 /* Return */ true); 5945 } 5946 5947 /// Update \p State according to \p CapturedInMem, \p CapturedInInt, and 5948 /// \p CapturedInRet, then return true if we should continue updating the 5949 /// state. 5950 static bool isCapturedIn(AANoCapture::StateType &State, bool CapturedInMem, 5951 bool CapturedInInt, bool CapturedInRet) { 5952 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int " 5953 << CapturedInInt << "|Ret " << CapturedInRet << "]\n"); 5954 if (CapturedInMem) 5955 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM); 5956 if (CapturedInInt) 5957 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT); 5958 if (CapturedInRet) 5959 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET); 5960 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED); 5961 } 5962 }; 5963 5964 ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) { 5965 const IRPosition &IRP = getIRPosition(); 5966 Value *V = isArgumentPosition() ? IRP.getAssociatedArgument() 5967 : &IRP.getAssociatedValue(); 5968 if (!V) 5969 return indicatePessimisticFixpoint(); 5970 5971 const Function *F = 5972 isArgumentPosition() ? IRP.getAssociatedFunction() : IRP.getAnchorScope(); 5973 5974 // TODO: Is the checkForAllUses below useful for constants? 5975 if (!F) 5976 return indicatePessimisticFixpoint(); 5977 5978 AANoCapture::StateType T; 5979 const IRPosition &FnPos = IRPosition::function(*F); 5980 5981 // Readonly means we cannot capture through memory. 5982 bool IsKnown; 5983 if (AA::isAssumedReadOnly(A, FnPos, *this, IsKnown)) { 5984 T.addKnownBits(NOT_CAPTURED_IN_MEM); 5985 if (IsKnown) 5986 addKnownBits(NOT_CAPTURED_IN_MEM); 5987 } 5988 5989 // Make sure all returned values are different than the underlying value. 5990 // TODO: we could do this in a more sophisticated way inside 5991 // AAReturnedValues, e.g., track all values that escape through returns 5992 // directly somehow. 5993 auto CheckReturnedArgs = [&](bool &UsedAssumedInformation) { 5994 SmallVector<AA::ValueAndContext> Values; 5995 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*F), this, Values, 5996 AA::ValueScope::Intraprocedural, 5997 UsedAssumedInformation)) 5998 return false; 5999 bool SeenConstant = false; 6000 for (const AA::ValueAndContext &VAC : Values) { 6001 if (isa<Constant>(VAC.getValue())) { 6002 if (SeenConstant) 6003 return false; 6004 SeenConstant = true; 6005 } else if (!isa<Argument>(VAC.getValue()) || 6006 VAC.getValue() == getAssociatedArgument()) 6007 return false; 6008 } 6009 return true; 6010 }; 6011 6012 bool IsKnownNoUnwind; 6013 if (AA::hasAssumedIRAttr<Attribute::NoUnwind>( 6014 A, this, FnPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) { 6015 bool IsVoidTy = F->getReturnType()->isVoidTy(); 6016 bool UsedAssumedInformation = false; 6017 if (IsVoidTy || CheckReturnedArgs(UsedAssumedInformation)) { 6018 T.addKnownBits(NOT_CAPTURED_IN_RET); 6019 if (T.isKnown(NOT_CAPTURED_IN_MEM)) 6020 return ChangeStatus::UNCHANGED; 6021 if (IsKnownNoUnwind && (IsVoidTy || !UsedAssumedInformation)) { 6022 addKnownBits(NOT_CAPTURED_IN_RET); 6023 if (isKnown(NOT_CAPTURED_IN_MEM)) 6024 return indicateOptimisticFixpoint(); 6025 } 6026 } 6027 } 6028 6029 auto UseCheck = [&](const Use &U, bool &Follow) -> bool { 6030 // TODO(captures): Make this more precise. 6031 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr); 6032 if (capturesNothing(CI)) 6033 return true; 6034 if (CI.isPassthrough()) { 6035 Follow = true; 6036 return true; 6037 } 6038 return checkUse(A, T, U, Follow); 6039 }; 6040 6041 if (!A.checkForAllUses(UseCheck, *this, *V)) 6042 return indicatePessimisticFixpoint(); 6043 6044 AANoCapture::StateType &S = getState(); 6045 auto Assumed = S.getAssumed(); 6046 S.intersectAssumedBits(T.getAssumed()); 6047 if (!isAssumedNoCaptureMaybeReturned()) 6048 return indicatePessimisticFixpoint(); 6049 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED 6050 : ChangeStatus::CHANGED; 6051 } 6052 6053 /// NoCapture attribute for function arguments. 6054 struct AANoCaptureArgument final : AANoCaptureImpl { 6055 AANoCaptureArgument(const IRPosition &IRP, Attributor &A) 6056 : AANoCaptureImpl(IRP, A) {} 6057 6058 /// See AbstractAttribute::trackStatistics() 6059 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) } 6060 }; 6061 6062 /// NoCapture attribute for call site arguments. 6063 struct AANoCaptureCallSiteArgument final : AANoCaptureImpl { 6064 AANoCaptureCallSiteArgument(const IRPosition &IRP, Attributor &A) 6065 : AANoCaptureImpl(IRP, A) {} 6066 6067 /// See AbstractAttribute::updateImpl(...). 6068 ChangeStatus updateImpl(Attributor &A) override { 6069 // TODO: Once we have call site specific value information we can provide 6070 // call site specific liveness information and then it makes 6071 // sense to specialize attributes for call sites arguments instead of 6072 // redirecting requests to the callee argument. 6073 Argument *Arg = getAssociatedArgument(); 6074 if (!Arg) 6075 return indicatePessimisticFixpoint(); 6076 const IRPosition &ArgPos = IRPosition::argument(*Arg); 6077 bool IsKnownNoCapture; 6078 const AANoCapture *ArgAA = nullptr; 6079 if (AA::hasAssumedIRAttr<Attribute::Captures>( 6080 A, this, ArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false, 6081 &ArgAA)) 6082 return ChangeStatus::UNCHANGED; 6083 if (!ArgAA || !ArgAA->isAssumedNoCaptureMaybeReturned()) 6084 return indicatePessimisticFixpoint(); 6085 return clampStateAndIndicateChange(getState(), ArgAA->getState()); 6086 } 6087 6088 /// See AbstractAttribute::trackStatistics() 6089 void trackStatistics() const override { 6090 STATS_DECLTRACK_CSARG_ATTR(nocapture) 6091 }; 6092 }; 6093 6094 /// NoCapture attribute for floating values. 6095 struct AANoCaptureFloating final : AANoCaptureImpl { 6096 AANoCaptureFloating(const IRPosition &IRP, Attributor &A) 6097 : AANoCaptureImpl(IRP, A) {} 6098 6099 /// See AbstractAttribute::trackStatistics() 6100 void trackStatistics() const override { 6101 STATS_DECLTRACK_FLOATING_ATTR(nocapture) 6102 } 6103 }; 6104 6105 /// NoCapture attribute for function return value. 6106 struct AANoCaptureReturned final : AANoCaptureImpl { 6107 AANoCaptureReturned(const IRPosition &IRP, Attributor &A) 6108 : AANoCaptureImpl(IRP, A) { 6109 llvm_unreachable("NoCapture is not applicable to function returns!"); 6110 } 6111 6112 /// See AbstractAttribute::initialize(...). 6113 void initialize(Attributor &A) override { 6114 llvm_unreachable("NoCapture is not applicable to function returns!"); 6115 } 6116 6117 /// See AbstractAttribute::updateImpl(...). 6118 ChangeStatus updateImpl(Attributor &A) override { 6119 llvm_unreachable("NoCapture is not applicable to function returns!"); 6120 } 6121 6122 /// See AbstractAttribute::trackStatistics() 6123 void trackStatistics() const override {} 6124 }; 6125 6126 /// NoCapture attribute deduction for a call site return value. 6127 struct AANoCaptureCallSiteReturned final : AANoCaptureImpl { 6128 AANoCaptureCallSiteReturned(const IRPosition &IRP, Attributor &A) 6129 : AANoCaptureImpl(IRP, A) {} 6130 6131 /// See AbstractAttribute::initialize(...). 6132 void initialize(Attributor &A) override { 6133 const Function *F = getAnchorScope(); 6134 // Check what state the associated function can actually capture. 6135 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this); 6136 } 6137 6138 /// See AbstractAttribute::trackStatistics() 6139 void trackStatistics() const override { 6140 STATS_DECLTRACK_CSRET_ATTR(nocapture) 6141 } 6142 }; 6143 } // namespace 6144 6145 /// ------------------ Value Simplify Attribute ---------------------------- 6146 6147 bool ValueSimplifyStateType::unionAssumed(std::optional<Value *> Other) { 6148 // FIXME: Add a typecast support. 6149 SimplifiedAssociatedValue = AA::combineOptionalValuesInAAValueLatice( 6150 SimplifiedAssociatedValue, Other, Ty); 6151 if (SimplifiedAssociatedValue == std::optional<Value *>(nullptr)) 6152 return false; 6153 6154 LLVM_DEBUG({ 6155 if (SimplifiedAssociatedValue) 6156 dbgs() << "[ValueSimplify] is assumed to be " 6157 << **SimplifiedAssociatedValue << "\n"; 6158 else 6159 dbgs() << "[ValueSimplify] is assumed to be <none>\n"; 6160 }); 6161 return true; 6162 } 6163 6164 namespace { 6165 struct AAValueSimplifyImpl : AAValueSimplify { 6166 AAValueSimplifyImpl(const IRPosition &IRP, Attributor &A) 6167 : AAValueSimplify(IRP, A) {} 6168 6169 /// See AbstractAttribute::initialize(...). 6170 void initialize(Attributor &A) override { 6171 if (getAssociatedValue().getType()->isVoidTy()) 6172 indicatePessimisticFixpoint(); 6173 if (A.hasSimplificationCallback(getIRPosition())) 6174 indicatePessimisticFixpoint(); 6175 } 6176 6177 /// See AbstractAttribute::getAsStr(). 6178 const std::string getAsStr(Attributor *A) const override { 6179 LLVM_DEBUG({ 6180 dbgs() << "SAV: " << (bool)SimplifiedAssociatedValue << " "; 6181 if (SimplifiedAssociatedValue && *SimplifiedAssociatedValue) 6182 dbgs() << "SAV: " << **SimplifiedAssociatedValue << " "; 6183 }); 6184 return isValidState() ? (isAtFixpoint() ? "simplified" : "maybe-simple") 6185 : "not-simple"; 6186 } 6187 6188 /// See AbstractAttribute::trackStatistics() 6189 void trackStatistics() const override {} 6190 6191 /// See AAValueSimplify::getAssumedSimplifiedValue() 6192 std::optional<Value *> 6193 getAssumedSimplifiedValue(Attributor &A) const override { 6194 return SimplifiedAssociatedValue; 6195 } 6196 6197 /// Ensure the return value is \p V with type \p Ty, if not possible return 6198 /// nullptr. If \p Check is true we will only verify such an operation would 6199 /// suceed and return a non-nullptr value if that is the case. No IR is 6200 /// generated or modified. 6201 static Value *ensureType(Attributor &A, Value &V, Type &Ty, Instruction *CtxI, 6202 bool Check) { 6203 if (auto *TypedV = AA::getWithType(V, Ty)) 6204 return TypedV; 6205 if (CtxI && V.getType()->canLosslesslyBitCastTo(&Ty)) 6206 return Check ? &V 6207 : BitCastInst::CreatePointerBitCastOrAddrSpaceCast( 6208 &V, &Ty, "", CtxI->getIterator()); 6209 return nullptr; 6210 } 6211 6212 /// Reproduce \p I with type \p Ty or return nullptr if that is not posisble. 6213 /// If \p Check is true we will only verify such an operation would suceed and 6214 /// return a non-nullptr value if that is the case. No IR is generated or 6215 /// modified. 6216 static Value *reproduceInst(Attributor &A, 6217 const AbstractAttribute &QueryingAA, 6218 Instruction &I, Type &Ty, Instruction *CtxI, 6219 bool Check, ValueToValueMapTy &VMap) { 6220 assert(CtxI && "Cannot reproduce an instruction without context!"); 6221 if (Check && (I.mayReadFromMemory() || 6222 !isSafeToSpeculativelyExecute(&I, CtxI, /* DT */ nullptr, 6223 /* TLI */ nullptr))) 6224 return nullptr; 6225 for (Value *Op : I.operands()) { 6226 Value *NewOp = reproduceValue(A, QueryingAA, *Op, Ty, CtxI, Check, VMap); 6227 if (!NewOp) { 6228 assert(Check && "Manifest of new value unexpectedly failed!"); 6229 return nullptr; 6230 } 6231 if (!Check) 6232 VMap[Op] = NewOp; 6233 } 6234 if (Check) 6235 return &I; 6236 6237 Instruction *CloneI = I.clone(); 6238 // TODO: Try to salvage debug information here. 6239 CloneI->setDebugLoc(DebugLoc()); 6240 VMap[&I] = CloneI; 6241 CloneI->insertBefore(CtxI->getIterator()); 6242 RemapInstruction(CloneI, VMap); 6243 return CloneI; 6244 } 6245 6246 /// Reproduce \p V with type \p Ty or return nullptr if that is not posisble. 6247 /// If \p Check is true we will only verify such an operation would suceed and 6248 /// return a non-nullptr value if that is the case. No IR is generated or 6249 /// modified. 6250 static Value *reproduceValue(Attributor &A, 6251 const AbstractAttribute &QueryingAA, Value &V, 6252 Type &Ty, Instruction *CtxI, bool Check, 6253 ValueToValueMapTy &VMap) { 6254 if (const auto &NewV = VMap.lookup(&V)) 6255 return NewV; 6256 bool UsedAssumedInformation = false; 6257 std::optional<Value *> SimpleV = A.getAssumedSimplified( 6258 V, QueryingAA, UsedAssumedInformation, AA::Interprocedural); 6259 if (!SimpleV.has_value()) 6260 return PoisonValue::get(&Ty); 6261 Value *EffectiveV = &V; 6262 if (*SimpleV) 6263 EffectiveV = *SimpleV; 6264 if (auto *C = dyn_cast<Constant>(EffectiveV)) 6265 return C; 6266 if (CtxI && AA::isValidAtPosition(AA::ValueAndContext(*EffectiveV, *CtxI), 6267 A.getInfoCache())) 6268 return ensureType(A, *EffectiveV, Ty, CtxI, Check); 6269 if (auto *I = dyn_cast<Instruction>(EffectiveV)) 6270 if (Value *NewV = reproduceInst(A, QueryingAA, *I, Ty, CtxI, Check, VMap)) 6271 return ensureType(A, *NewV, Ty, CtxI, Check); 6272 return nullptr; 6273 } 6274 6275 /// Return a value we can use as replacement for the associated one, or 6276 /// nullptr if we don't have one that makes sense. 6277 Value *manifestReplacementValue(Attributor &A, Instruction *CtxI) const { 6278 Value *NewV = SimplifiedAssociatedValue 6279 ? *SimplifiedAssociatedValue 6280 : UndefValue::get(getAssociatedType()); 6281 if (NewV && NewV != &getAssociatedValue()) { 6282 ValueToValueMapTy VMap; 6283 // First verify we can reprduce the value with the required type at the 6284 // context location before we actually start modifying the IR. 6285 if (reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI, 6286 /* CheckOnly */ true, VMap)) 6287 return reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI, 6288 /* CheckOnly */ false, VMap); 6289 } 6290 return nullptr; 6291 } 6292 6293 /// Helper function for querying AAValueSimplify and updating candidate. 6294 /// \param IRP The value position we are trying to unify with SimplifiedValue 6295 bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA, 6296 const IRPosition &IRP, bool Simplify = true) { 6297 bool UsedAssumedInformation = false; 6298 std::optional<Value *> QueryingValueSimplified = &IRP.getAssociatedValue(); 6299 if (Simplify) 6300 QueryingValueSimplified = A.getAssumedSimplified( 6301 IRP, QueryingAA, UsedAssumedInformation, AA::Interprocedural); 6302 return unionAssumed(QueryingValueSimplified); 6303 } 6304 6305 /// Returns a candidate is found or not 6306 template <typename AAType> bool askSimplifiedValueFor(Attributor &A) { 6307 if (!getAssociatedValue().getType()->isIntegerTy()) 6308 return false; 6309 6310 // This will also pass the call base context. 6311 const auto *AA = 6312 A.getAAFor<AAType>(*this, getIRPosition(), DepClassTy::NONE); 6313 if (!AA) 6314 return false; 6315 6316 std::optional<Constant *> COpt = AA->getAssumedConstant(A); 6317 6318 if (!COpt) { 6319 SimplifiedAssociatedValue = std::nullopt; 6320 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL); 6321 return true; 6322 } 6323 if (auto *C = *COpt) { 6324 SimplifiedAssociatedValue = C; 6325 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL); 6326 return true; 6327 } 6328 return false; 6329 } 6330 6331 bool askSimplifiedValueForOtherAAs(Attributor &A) { 6332 if (askSimplifiedValueFor<AAValueConstantRange>(A)) 6333 return true; 6334 if (askSimplifiedValueFor<AAPotentialConstantValues>(A)) 6335 return true; 6336 return false; 6337 } 6338 6339 /// See AbstractAttribute::manifest(...). 6340 ChangeStatus manifest(Attributor &A) override { 6341 ChangeStatus Changed = ChangeStatus::UNCHANGED; 6342 for (auto &U : getAssociatedValue().uses()) { 6343 // Check if we need to adjust the insertion point to make sure the IR is 6344 // valid. 6345 Instruction *IP = dyn_cast<Instruction>(U.getUser()); 6346 if (auto *PHI = dyn_cast_or_null<PHINode>(IP)) 6347 IP = PHI->getIncomingBlock(U)->getTerminator(); 6348 if (auto *NewV = manifestReplacementValue(A, IP)) { 6349 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << getAssociatedValue() 6350 << " -> " << *NewV << " :: " << *this << "\n"); 6351 if (A.changeUseAfterManifest(U, *NewV)) 6352 Changed = ChangeStatus::CHANGED; 6353 } 6354 } 6355 6356 return Changed | AAValueSimplify::manifest(A); 6357 } 6358 6359 /// See AbstractState::indicatePessimisticFixpoint(...). 6360 ChangeStatus indicatePessimisticFixpoint() override { 6361 SimplifiedAssociatedValue = &getAssociatedValue(); 6362 return AAValueSimplify::indicatePessimisticFixpoint(); 6363 } 6364 }; 6365 6366 struct AAValueSimplifyArgument final : AAValueSimplifyImpl { 6367 AAValueSimplifyArgument(const IRPosition &IRP, Attributor &A) 6368 : AAValueSimplifyImpl(IRP, A) {} 6369 6370 void initialize(Attributor &A) override { 6371 AAValueSimplifyImpl::initialize(A); 6372 if (A.hasAttr(getIRPosition(), 6373 {Attribute::InAlloca, Attribute::Preallocated, 6374 Attribute::StructRet, Attribute::Nest, Attribute::ByVal}, 6375 /* IgnoreSubsumingPositions */ true)) 6376 indicatePessimisticFixpoint(); 6377 } 6378 6379 /// See AbstractAttribute::updateImpl(...). 6380 ChangeStatus updateImpl(Attributor &A) override { 6381 // Byval is only replacable if it is readonly otherwise we would write into 6382 // the replaced value and not the copy that byval creates implicitly. 6383 Argument *Arg = getAssociatedArgument(); 6384 if (Arg->hasByValAttr()) { 6385 // TODO: We probably need to verify synchronization is not an issue, e.g., 6386 // there is no race by not copying a constant byval. 6387 bool IsKnown; 6388 if (!AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown)) 6389 return indicatePessimisticFixpoint(); 6390 } 6391 6392 auto Before = SimplifiedAssociatedValue; 6393 6394 auto PredForCallSite = [&](AbstractCallSite ACS) { 6395 const IRPosition &ACSArgPos = 6396 IRPosition::callsite_argument(ACS, getCallSiteArgNo()); 6397 // Check if a coresponding argument was found or if it is on not 6398 // associated (which can happen for callback calls). 6399 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID) 6400 return false; 6401 6402 // Simplify the argument operand explicitly and check if the result is 6403 // valid in the current scope. This avoids refering to simplified values 6404 // in other functions, e.g., we don't want to say a an argument in a 6405 // static function is actually an argument in a different function. 6406 bool UsedAssumedInformation = false; 6407 std::optional<Constant *> SimpleArgOp = 6408 A.getAssumedConstant(ACSArgPos, *this, UsedAssumedInformation); 6409 if (!SimpleArgOp) 6410 return true; 6411 if (!*SimpleArgOp) 6412 return false; 6413 if (!AA::isDynamicallyUnique(A, *this, **SimpleArgOp)) 6414 return false; 6415 return unionAssumed(*SimpleArgOp); 6416 }; 6417 6418 // Generate a answer specific to a call site context. 6419 bool Success; 6420 bool UsedAssumedInformation = false; 6421 if (hasCallBaseContext() && 6422 getCallBaseContext()->getCalledOperand() == Arg->getParent()) 6423 Success = PredForCallSite( 6424 AbstractCallSite(&getCallBaseContext()->getCalledOperandUse())); 6425 else 6426 Success = A.checkForAllCallSites(PredForCallSite, *this, true, 6427 UsedAssumedInformation); 6428 6429 if (!Success) 6430 if (!askSimplifiedValueForOtherAAs(A)) 6431 return indicatePessimisticFixpoint(); 6432 6433 // If a candidate was found in this update, return CHANGED. 6434 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED 6435 : ChangeStatus ::CHANGED; 6436 } 6437 6438 /// See AbstractAttribute::trackStatistics() 6439 void trackStatistics() const override { 6440 STATS_DECLTRACK_ARG_ATTR(value_simplify) 6441 } 6442 }; 6443 6444 struct AAValueSimplifyReturned : AAValueSimplifyImpl { 6445 AAValueSimplifyReturned(const IRPosition &IRP, Attributor &A) 6446 : AAValueSimplifyImpl(IRP, A) {} 6447 6448 /// See AAValueSimplify::getAssumedSimplifiedValue() 6449 std::optional<Value *> 6450 getAssumedSimplifiedValue(Attributor &A) const override { 6451 if (!isValidState()) 6452 return nullptr; 6453 return SimplifiedAssociatedValue; 6454 } 6455 6456 /// See AbstractAttribute::updateImpl(...). 6457 ChangeStatus updateImpl(Attributor &A) override { 6458 auto Before = SimplifiedAssociatedValue; 6459 6460 auto ReturnInstCB = [&](Instruction &I) { 6461 auto &RI = cast<ReturnInst>(I); 6462 return checkAndUpdate( 6463 A, *this, 6464 IRPosition::value(*RI.getReturnValue(), getCallBaseContext())); 6465 }; 6466 6467 bool UsedAssumedInformation = false; 6468 if (!A.checkForAllInstructions(ReturnInstCB, *this, {Instruction::Ret}, 6469 UsedAssumedInformation)) 6470 if (!askSimplifiedValueForOtherAAs(A)) 6471 return indicatePessimisticFixpoint(); 6472 6473 // If a candidate was found in this update, return CHANGED. 6474 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED 6475 : ChangeStatus ::CHANGED; 6476 } 6477 6478 ChangeStatus manifest(Attributor &A) override { 6479 // We queried AAValueSimplify for the returned values so they will be 6480 // replaced if a simplified form was found. Nothing to do here. 6481 return ChangeStatus::UNCHANGED; 6482 } 6483 6484 /// See AbstractAttribute::trackStatistics() 6485 void trackStatistics() const override { 6486 STATS_DECLTRACK_FNRET_ATTR(value_simplify) 6487 } 6488 }; 6489 6490 struct AAValueSimplifyFloating : AAValueSimplifyImpl { 6491 AAValueSimplifyFloating(const IRPosition &IRP, Attributor &A) 6492 : AAValueSimplifyImpl(IRP, A) {} 6493 6494 /// See AbstractAttribute::initialize(...). 6495 void initialize(Attributor &A) override { 6496 AAValueSimplifyImpl::initialize(A); 6497 Value &V = getAnchorValue(); 6498 6499 // TODO: add other stuffs 6500 if (isa<Constant>(V)) 6501 indicatePessimisticFixpoint(); 6502 } 6503 6504 /// See AbstractAttribute::updateImpl(...). 6505 ChangeStatus updateImpl(Attributor &A) override { 6506 auto Before = SimplifiedAssociatedValue; 6507 if (!askSimplifiedValueForOtherAAs(A)) 6508 return indicatePessimisticFixpoint(); 6509 6510 // If a candidate was found in this update, return CHANGED. 6511 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED 6512 : ChangeStatus ::CHANGED; 6513 } 6514 6515 /// See AbstractAttribute::trackStatistics() 6516 void trackStatistics() const override { 6517 STATS_DECLTRACK_FLOATING_ATTR(value_simplify) 6518 } 6519 }; 6520 6521 struct AAValueSimplifyFunction : AAValueSimplifyImpl { 6522 AAValueSimplifyFunction(const IRPosition &IRP, Attributor &A) 6523 : AAValueSimplifyImpl(IRP, A) {} 6524 6525 /// See AbstractAttribute::initialize(...). 6526 void initialize(Attributor &A) override { 6527 SimplifiedAssociatedValue = nullptr; 6528 indicateOptimisticFixpoint(); 6529 } 6530 /// See AbstractAttribute::initialize(...). 6531 ChangeStatus updateImpl(Attributor &A) override { 6532 llvm_unreachable( 6533 "AAValueSimplify(Function|CallSite)::updateImpl will not be called"); 6534 } 6535 /// See AbstractAttribute::trackStatistics() 6536 void trackStatistics() const override { 6537 STATS_DECLTRACK_FN_ATTR(value_simplify) 6538 } 6539 }; 6540 6541 struct AAValueSimplifyCallSite : AAValueSimplifyFunction { 6542 AAValueSimplifyCallSite(const IRPosition &IRP, Attributor &A) 6543 : AAValueSimplifyFunction(IRP, A) {} 6544 /// See AbstractAttribute::trackStatistics() 6545 void trackStatistics() const override { 6546 STATS_DECLTRACK_CS_ATTR(value_simplify) 6547 } 6548 }; 6549 6550 struct AAValueSimplifyCallSiteReturned : AAValueSimplifyImpl { 6551 AAValueSimplifyCallSiteReturned(const IRPosition &IRP, Attributor &A) 6552 : AAValueSimplifyImpl(IRP, A) {} 6553 6554 void initialize(Attributor &A) override { 6555 AAValueSimplifyImpl::initialize(A); 6556 Function *Fn = getAssociatedFunction(); 6557 assert(Fn && "Did expect an associted function"); 6558 for (Argument &Arg : Fn->args()) { 6559 if (Arg.hasReturnedAttr()) { 6560 auto IRP = IRPosition::callsite_argument(*cast<CallBase>(getCtxI()), 6561 Arg.getArgNo()); 6562 if (IRP.getPositionKind() == IRPosition::IRP_CALL_SITE_ARGUMENT && 6563 checkAndUpdate(A, *this, IRP)) 6564 indicateOptimisticFixpoint(); 6565 else 6566 indicatePessimisticFixpoint(); 6567 return; 6568 } 6569 } 6570 } 6571 6572 /// See AbstractAttribute::updateImpl(...). 6573 ChangeStatus updateImpl(Attributor &A) override { 6574 return indicatePessimisticFixpoint(); 6575 } 6576 6577 void trackStatistics() const override { 6578 STATS_DECLTRACK_CSRET_ATTR(value_simplify) 6579 } 6580 }; 6581 6582 struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating { 6583 AAValueSimplifyCallSiteArgument(const IRPosition &IRP, Attributor &A) 6584 : AAValueSimplifyFloating(IRP, A) {} 6585 6586 /// See AbstractAttribute::manifest(...). 6587 ChangeStatus manifest(Attributor &A) override { 6588 ChangeStatus Changed = ChangeStatus::UNCHANGED; 6589 // TODO: We should avoid simplification duplication to begin with. 6590 auto *FloatAA = A.lookupAAFor<AAValueSimplify>( 6591 IRPosition::value(getAssociatedValue()), this, DepClassTy::NONE); 6592 if (FloatAA && FloatAA->getState().isValidState()) 6593 return Changed; 6594 6595 if (auto *NewV = manifestReplacementValue(A, getCtxI())) { 6596 Use &U = cast<CallBase>(&getAnchorValue()) 6597 ->getArgOperandUse(getCallSiteArgNo()); 6598 if (A.changeUseAfterManifest(U, *NewV)) 6599 Changed = ChangeStatus::CHANGED; 6600 } 6601 6602 return Changed | AAValueSimplify::manifest(A); 6603 } 6604 6605 void trackStatistics() const override { 6606 STATS_DECLTRACK_CSARG_ATTR(value_simplify) 6607 } 6608 }; 6609 } // namespace 6610 6611 /// ----------------------- Heap-To-Stack Conversion --------------------------- 6612 namespace { 6613 struct AAHeapToStackFunction final : public AAHeapToStack { 6614 6615 struct AllocationInfo { 6616 /// The call that allocates the memory. 6617 CallBase *const CB; 6618 6619 /// The library function id for the allocation. 6620 LibFunc LibraryFunctionId = NotLibFunc; 6621 6622 /// The status wrt. a rewrite. 6623 enum { 6624 STACK_DUE_TO_USE, 6625 STACK_DUE_TO_FREE, 6626 INVALID, 6627 } Status = STACK_DUE_TO_USE; 6628 6629 /// Flag to indicate if we encountered a use that might free this allocation 6630 /// but which is not in the deallocation infos. 6631 bool HasPotentiallyFreeingUnknownUses = false; 6632 6633 /// Flag to indicate that we should place the new alloca in the function 6634 /// entry block rather than where the call site (CB) is. 6635 bool MoveAllocaIntoEntry = true; 6636 6637 /// The set of free calls that use this allocation. 6638 SmallSetVector<CallBase *, 1> PotentialFreeCalls{}; 6639 }; 6640 6641 struct DeallocationInfo { 6642 /// The call that deallocates the memory. 6643 CallBase *const CB; 6644 /// The value freed by the call. 6645 Value *FreedOp; 6646 6647 /// Flag to indicate if we don't know all objects this deallocation might 6648 /// free. 6649 bool MightFreeUnknownObjects = false; 6650 6651 /// The set of allocation calls that are potentially freed. 6652 SmallSetVector<CallBase *, 1> PotentialAllocationCalls{}; 6653 }; 6654 6655 AAHeapToStackFunction(const IRPosition &IRP, Attributor &A) 6656 : AAHeapToStack(IRP, A) {} 6657 6658 ~AAHeapToStackFunction() { 6659 // Ensure we call the destructor so we release any memory allocated in the 6660 // sets. 6661 for (auto &It : AllocationInfos) 6662 It.second->~AllocationInfo(); 6663 for (auto &It : DeallocationInfos) 6664 It.second->~DeallocationInfo(); 6665 } 6666 6667 void initialize(Attributor &A) override { 6668 AAHeapToStack::initialize(A); 6669 6670 const Function *F = getAnchorScope(); 6671 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F); 6672 6673 auto AllocationIdentifierCB = [&](Instruction &I) { 6674 CallBase *CB = dyn_cast<CallBase>(&I); 6675 if (!CB) 6676 return true; 6677 if (Value *FreedOp = getFreedOperand(CB, TLI)) { 6678 DeallocationInfos[CB] = new (A.Allocator) DeallocationInfo{CB, FreedOp}; 6679 return true; 6680 } 6681 // To do heap to stack, we need to know that the allocation itself is 6682 // removable once uses are rewritten, and that we can initialize the 6683 // alloca to the same pattern as the original allocation result. 6684 if (isRemovableAlloc(CB, TLI)) { 6685 auto *I8Ty = Type::getInt8Ty(CB->getParent()->getContext()); 6686 if (nullptr != getInitialValueOfAllocation(CB, TLI, I8Ty)) { 6687 AllocationInfo *AI = new (A.Allocator) AllocationInfo{CB}; 6688 AllocationInfos[CB] = AI; 6689 if (TLI) 6690 TLI->getLibFunc(*CB, AI->LibraryFunctionId); 6691 } 6692 } 6693 return true; 6694 }; 6695 6696 bool UsedAssumedInformation = false; 6697 bool Success = A.checkForAllCallLikeInstructions( 6698 AllocationIdentifierCB, *this, UsedAssumedInformation, 6699 /* CheckBBLivenessOnly */ false, 6700 /* CheckPotentiallyDead */ true); 6701 (void)Success; 6702 assert(Success && "Did not expect the call base visit callback to fail!"); 6703 6704 Attributor::SimplifictionCallbackTy SCB = 6705 [](const IRPosition &, const AbstractAttribute *, 6706 bool &) -> std::optional<Value *> { return nullptr; }; 6707 for (const auto &It : AllocationInfos) 6708 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first), 6709 SCB); 6710 for (const auto &It : DeallocationInfos) 6711 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first), 6712 SCB); 6713 } 6714 6715 const std::string getAsStr(Attributor *A) const override { 6716 unsigned NumH2SMallocs = 0, NumInvalidMallocs = 0; 6717 for (const auto &It : AllocationInfos) { 6718 if (It.second->Status == AllocationInfo::INVALID) 6719 ++NumInvalidMallocs; 6720 else 6721 ++NumH2SMallocs; 6722 } 6723 return "[H2S] Mallocs Good/Bad: " + std::to_string(NumH2SMallocs) + "/" + 6724 std::to_string(NumInvalidMallocs); 6725 } 6726 6727 /// See AbstractAttribute::trackStatistics(). 6728 void trackStatistics() const override { 6729 STATS_DECL( 6730 MallocCalls, Function, 6731 "Number of malloc/calloc/aligned_alloc calls converted to allocas"); 6732 for (const auto &It : AllocationInfos) 6733 if (It.second->Status != AllocationInfo::INVALID) 6734 ++BUILD_STAT_NAME(MallocCalls, Function); 6735 } 6736 6737 bool isAssumedHeapToStack(const CallBase &CB) const override { 6738 if (isValidState()) 6739 if (AllocationInfo *AI = 6740 AllocationInfos.lookup(const_cast<CallBase *>(&CB))) 6741 return AI->Status != AllocationInfo::INVALID; 6742 return false; 6743 } 6744 6745 bool isAssumedHeapToStackRemovedFree(CallBase &CB) const override { 6746 if (!isValidState()) 6747 return false; 6748 6749 for (const auto &It : AllocationInfos) { 6750 AllocationInfo &AI = *It.second; 6751 if (AI.Status == AllocationInfo::INVALID) 6752 continue; 6753 6754 if (AI.PotentialFreeCalls.count(&CB)) 6755 return true; 6756 } 6757 6758 return false; 6759 } 6760 6761 ChangeStatus manifest(Attributor &A) override { 6762 assert(getState().isValidState() && 6763 "Attempted to manifest an invalid state!"); 6764 6765 ChangeStatus HasChanged = ChangeStatus::UNCHANGED; 6766 Function *F = getAnchorScope(); 6767 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F); 6768 6769 for (auto &It : AllocationInfos) { 6770 AllocationInfo &AI = *It.second; 6771 if (AI.Status == AllocationInfo::INVALID) 6772 continue; 6773 6774 for (CallBase *FreeCall : AI.PotentialFreeCalls) { 6775 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n"); 6776 A.deleteAfterManifest(*FreeCall); 6777 HasChanged = ChangeStatus::CHANGED; 6778 } 6779 6780 LLVM_DEBUG(dbgs() << "H2S: Removing malloc-like call: " << *AI.CB 6781 << "\n"); 6782 6783 auto Remark = [&](OptimizationRemark OR) { 6784 LibFunc IsAllocShared; 6785 if (TLI->getLibFunc(*AI.CB, IsAllocShared)) 6786 if (IsAllocShared == LibFunc___kmpc_alloc_shared) 6787 return OR << "Moving globalized variable to the stack."; 6788 return OR << "Moving memory allocation from the heap to the stack."; 6789 }; 6790 if (AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared) 6791 A.emitRemark<OptimizationRemark>(AI.CB, "OMP110", Remark); 6792 else 6793 A.emitRemark<OptimizationRemark>(AI.CB, "HeapToStack", Remark); 6794 6795 const DataLayout &DL = A.getInfoCache().getDL(); 6796 Value *Size; 6797 std::optional<APInt> SizeAPI = getSize(A, *this, AI); 6798 if (SizeAPI) { 6799 Size = ConstantInt::get(AI.CB->getContext(), *SizeAPI); 6800 } else { 6801 LLVMContext &Ctx = AI.CB->getContext(); 6802 ObjectSizeOpts Opts; 6803 ObjectSizeOffsetEvaluator Eval(DL, TLI, Ctx, Opts); 6804 SizeOffsetValue SizeOffsetPair = Eval.compute(AI.CB); 6805 assert(SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown() && 6806 cast<ConstantInt>(SizeOffsetPair.Offset)->isZero()); 6807 Size = SizeOffsetPair.Size; 6808 } 6809 6810 BasicBlock::iterator IP = AI.MoveAllocaIntoEntry 6811 ? F->getEntryBlock().begin() 6812 : AI.CB->getIterator(); 6813 6814 Align Alignment(1); 6815 if (MaybeAlign RetAlign = AI.CB->getRetAlign()) 6816 Alignment = std::max(Alignment, *RetAlign); 6817 if (Value *Align = getAllocAlignment(AI.CB, TLI)) { 6818 std::optional<APInt> AlignmentAPI = getAPInt(A, *this, *Align); 6819 assert(AlignmentAPI && AlignmentAPI->getZExtValue() > 0 && 6820 "Expected an alignment during manifest!"); 6821 Alignment = 6822 std::max(Alignment, assumeAligned(AlignmentAPI->getZExtValue())); 6823 } 6824 6825 // TODO: Hoist the alloca towards the function entry. 6826 unsigned AS = DL.getAllocaAddrSpace(); 6827 Instruction *Alloca = 6828 new AllocaInst(Type::getInt8Ty(F->getContext()), AS, Size, Alignment, 6829 AI.CB->getName() + ".h2s", IP); 6830 6831 if (Alloca->getType() != AI.CB->getType()) 6832 Alloca = BitCastInst::CreatePointerBitCastOrAddrSpaceCast( 6833 Alloca, AI.CB->getType(), "malloc_cast", AI.CB->getIterator()); 6834 6835 auto *I8Ty = Type::getInt8Ty(F->getContext()); 6836 auto *InitVal = getInitialValueOfAllocation(AI.CB, TLI, I8Ty); 6837 assert(InitVal && 6838 "Must be able to materialize initial memory state of allocation"); 6839 6840 A.changeAfterManifest(IRPosition::inst(*AI.CB), *Alloca); 6841 6842 if (auto *II = dyn_cast<InvokeInst>(AI.CB)) { 6843 auto *NBB = II->getNormalDest(); 6844 BranchInst::Create(NBB, AI.CB->getParent()); 6845 A.deleteAfterManifest(*AI.CB); 6846 } else { 6847 A.deleteAfterManifest(*AI.CB); 6848 } 6849 6850 // Initialize the alloca with the same value as used by the allocation 6851 // function. We can skip undef as the initial value of an alloc is 6852 // undef, and the memset would simply end up being DSEd. 6853 if (!isa<UndefValue>(InitVal)) { 6854 IRBuilder<> Builder(Alloca->getNextNode()); 6855 // TODO: Use alignment above if align!=1 6856 Builder.CreateMemSet(Alloca, InitVal, Size, std::nullopt); 6857 } 6858 HasChanged = ChangeStatus::CHANGED; 6859 } 6860 6861 return HasChanged; 6862 } 6863 6864 std::optional<APInt> getAPInt(Attributor &A, const AbstractAttribute &AA, 6865 Value &V) { 6866 bool UsedAssumedInformation = false; 6867 std::optional<Constant *> SimpleV = 6868 A.getAssumedConstant(V, AA, UsedAssumedInformation); 6869 if (!SimpleV) 6870 return APInt(64, 0); 6871 if (auto *CI = dyn_cast_or_null<ConstantInt>(*SimpleV)) 6872 return CI->getValue(); 6873 return std::nullopt; 6874 } 6875 6876 std::optional<APInt> getSize(Attributor &A, const AbstractAttribute &AA, 6877 AllocationInfo &AI) { 6878 auto Mapper = [&](const Value *V) -> const Value * { 6879 bool UsedAssumedInformation = false; 6880 if (std::optional<Constant *> SimpleV = 6881 A.getAssumedConstant(*V, AA, UsedAssumedInformation)) 6882 if (*SimpleV) 6883 return *SimpleV; 6884 return V; 6885 }; 6886 6887 const Function *F = getAnchorScope(); 6888 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F); 6889 return getAllocSize(AI.CB, TLI, Mapper); 6890 } 6891 6892 /// Collection of all malloc-like calls in a function with associated 6893 /// information. 6894 MapVector<CallBase *, AllocationInfo *> AllocationInfos; 6895 6896 /// Collection of all free-like calls in a function with associated 6897 /// information. 6898 MapVector<CallBase *, DeallocationInfo *> DeallocationInfos; 6899 6900 ChangeStatus updateImpl(Attributor &A) override; 6901 }; 6902 6903 ChangeStatus AAHeapToStackFunction::updateImpl(Attributor &A) { 6904 ChangeStatus Changed = ChangeStatus::UNCHANGED; 6905 const Function *F = getAnchorScope(); 6906 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F); 6907 6908 const auto *LivenessAA = 6909 A.getAAFor<AAIsDead>(*this, IRPosition::function(*F), DepClassTy::NONE); 6910 6911 MustBeExecutedContextExplorer *Explorer = 6912 A.getInfoCache().getMustBeExecutedContextExplorer(); 6913 6914 bool StackIsAccessibleByOtherThreads = 6915 A.getInfoCache().stackIsAccessibleByOtherThreads(); 6916 6917 LoopInfo *LI = 6918 A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(*F); 6919 std::optional<bool> MayContainIrreducibleControl; 6920 auto IsInLoop = [&](BasicBlock &BB) { 6921 if (&F->getEntryBlock() == &BB) 6922 return false; 6923 if (!MayContainIrreducibleControl.has_value()) 6924 MayContainIrreducibleControl = mayContainIrreducibleControl(*F, LI); 6925 if (*MayContainIrreducibleControl) 6926 return true; 6927 if (!LI) 6928 return true; 6929 return LI->getLoopFor(&BB) != nullptr; 6930 }; 6931 6932 // Flag to ensure we update our deallocation information at most once per 6933 // updateImpl call and only if we use the free check reasoning. 6934 bool HasUpdatedFrees = false; 6935 6936 auto UpdateFrees = [&]() { 6937 HasUpdatedFrees = true; 6938 6939 for (auto &It : DeallocationInfos) { 6940 DeallocationInfo &DI = *It.second; 6941 // For now we cannot use deallocations that have unknown inputs, skip 6942 // them. 6943 if (DI.MightFreeUnknownObjects) 6944 continue; 6945 6946 // No need to analyze dead calls, ignore them instead. 6947 bool UsedAssumedInformation = false; 6948 if (A.isAssumedDead(*DI.CB, this, LivenessAA, UsedAssumedInformation, 6949 /* CheckBBLivenessOnly */ true)) 6950 continue; 6951 6952 // Use the non-optimistic version to get the freed object. 6953 Value *Obj = getUnderlyingObject(DI.FreedOp); 6954 if (!Obj) { 6955 LLVM_DEBUG(dbgs() << "[H2S] Unknown underlying object for free!\n"); 6956 DI.MightFreeUnknownObjects = true; 6957 continue; 6958 } 6959 6960 // Free of null and undef can be ignored as no-ops (or UB in the latter 6961 // case). 6962 if (isa<ConstantPointerNull>(Obj) || isa<UndefValue>(Obj)) 6963 continue; 6964 6965 CallBase *ObjCB = dyn_cast<CallBase>(Obj); 6966 if (!ObjCB) { 6967 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-call object: " << *Obj 6968 << "\n"); 6969 DI.MightFreeUnknownObjects = true; 6970 continue; 6971 } 6972 6973 AllocationInfo *AI = AllocationInfos.lookup(ObjCB); 6974 if (!AI) { 6975 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-allocation object: " << *Obj 6976 << "\n"); 6977 DI.MightFreeUnknownObjects = true; 6978 continue; 6979 } 6980 6981 DI.PotentialAllocationCalls.insert(ObjCB); 6982 } 6983 }; 6984 6985 auto FreeCheck = [&](AllocationInfo &AI) { 6986 // If the stack is not accessible by other threads, the "must-free" logic 6987 // doesn't apply as the pointer could be shared and needs to be places in 6988 // "shareable" memory. 6989 if (!StackIsAccessibleByOtherThreads) { 6990 bool IsKnownNoSycn; 6991 if (!AA::hasAssumedIRAttr<Attribute::NoSync>( 6992 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoSycn)) { 6993 LLVM_DEBUG( 6994 dbgs() << "[H2S] found an escaping use, stack is not accessible by " 6995 "other threads and function is not nosync:\n"); 6996 return false; 6997 } 6998 } 6999 if (!HasUpdatedFrees) 7000 UpdateFrees(); 7001 7002 // TODO: Allow multi exit functions that have different free calls. 7003 if (AI.PotentialFreeCalls.size() != 1) { 7004 LLVM_DEBUG(dbgs() << "[H2S] did not find one free call but " 7005 << AI.PotentialFreeCalls.size() << "\n"); 7006 return false; 7007 } 7008 CallBase *UniqueFree = *AI.PotentialFreeCalls.begin(); 7009 DeallocationInfo *DI = DeallocationInfos.lookup(UniqueFree); 7010 if (!DI) { 7011 LLVM_DEBUG( 7012 dbgs() << "[H2S] unique free call was not known as deallocation call " 7013 << *UniqueFree << "\n"); 7014 return false; 7015 } 7016 if (DI->MightFreeUnknownObjects) { 7017 LLVM_DEBUG( 7018 dbgs() << "[H2S] unique free call might free unknown allocations\n"); 7019 return false; 7020 } 7021 if (DI->PotentialAllocationCalls.empty()) 7022 return true; 7023 if (DI->PotentialAllocationCalls.size() > 1) { 7024 LLVM_DEBUG(dbgs() << "[H2S] unique free call might free " 7025 << DI->PotentialAllocationCalls.size() 7026 << " different allocations\n"); 7027 return false; 7028 } 7029 if (*DI->PotentialAllocationCalls.begin() != AI.CB) { 7030 LLVM_DEBUG( 7031 dbgs() 7032 << "[H2S] unique free call not known to free this allocation but " 7033 << **DI->PotentialAllocationCalls.begin() << "\n"); 7034 return false; 7035 } 7036 7037 // __kmpc_alloc_shared and __kmpc_alloc_free are by construction matched. 7038 if (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared) { 7039 Instruction *CtxI = isa<InvokeInst>(AI.CB) ? AI.CB : AI.CB->getNextNode(); 7040 if (!Explorer || !Explorer->findInContextOf(UniqueFree, CtxI)) { 7041 LLVM_DEBUG(dbgs() << "[H2S] unique free call might not be executed " 7042 "with the allocation " 7043 << *UniqueFree << "\n"); 7044 return false; 7045 } 7046 } 7047 return true; 7048 }; 7049 7050 auto UsesCheck = [&](AllocationInfo &AI) { 7051 bool ValidUsesOnly = true; 7052 7053 auto Pred = [&](const Use &U, bool &Follow) -> bool { 7054 Instruction *UserI = cast<Instruction>(U.getUser()); 7055 if (isa<LoadInst>(UserI)) 7056 return true; 7057 if (auto *SI = dyn_cast<StoreInst>(UserI)) { 7058 if (SI->getValueOperand() == U.get()) { 7059 LLVM_DEBUG(dbgs() 7060 << "[H2S] escaping store to memory: " << *UserI << "\n"); 7061 ValidUsesOnly = false; 7062 } else { 7063 // A store into the malloc'ed memory is fine. 7064 } 7065 return true; 7066 } 7067 if (auto *CB = dyn_cast<CallBase>(UserI)) { 7068 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd()) 7069 return true; 7070 if (DeallocationInfos.count(CB)) { 7071 AI.PotentialFreeCalls.insert(CB); 7072 return true; 7073 } 7074 7075 unsigned ArgNo = CB->getArgOperandNo(&U); 7076 auto CBIRP = IRPosition::callsite_argument(*CB, ArgNo); 7077 7078 bool IsKnownNoCapture; 7079 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>( 7080 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoCapture); 7081 7082 // If a call site argument use is nofree, we are fine. 7083 bool IsKnownNoFree; 7084 bool IsAssumedNoFree = AA::hasAssumedIRAttr<Attribute::NoFree>( 7085 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoFree); 7086 7087 if (!IsAssumedNoCapture || 7088 (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared && 7089 !IsAssumedNoFree)) { 7090 AI.HasPotentiallyFreeingUnknownUses |= !IsAssumedNoFree; 7091 7092 // Emit a missed remark if this is missed OpenMP globalization. 7093 auto Remark = [&](OptimizationRemarkMissed ORM) { 7094 return ORM 7095 << "Could not move globalized variable to the stack. " 7096 "Variable is potentially captured in call. Mark " 7097 "parameter as `__attribute__((noescape))` to override."; 7098 }; 7099 7100 if (ValidUsesOnly && 7101 AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared) 7102 A.emitRemark<OptimizationRemarkMissed>(CB, "OMP113", Remark); 7103 7104 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n"); 7105 ValidUsesOnly = false; 7106 } 7107 return true; 7108 } 7109 7110 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) || 7111 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) { 7112 Follow = true; 7113 return true; 7114 } 7115 // Unknown user for which we can not track uses further (in a way that 7116 // makes sense). 7117 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n"); 7118 ValidUsesOnly = false; 7119 return true; 7120 }; 7121 if (!A.checkForAllUses(Pred, *this, *AI.CB, /* CheckBBLivenessOnly */ false, 7122 DepClassTy::OPTIONAL, /* IgnoreDroppableUses */ true, 7123 [&](const Use &OldU, const Use &NewU) { 7124 auto *SI = dyn_cast<StoreInst>(OldU.getUser()); 7125 return !SI || StackIsAccessibleByOtherThreads || 7126 AA::isAssumedThreadLocalObject( 7127 A, *SI->getPointerOperand(), *this); 7128 })) 7129 return false; 7130 return ValidUsesOnly; 7131 }; 7132 7133 // The actual update starts here. We look at all allocations and depending on 7134 // their status perform the appropriate check(s). 7135 for (auto &It : AllocationInfos) { 7136 AllocationInfo &AI = *It.second; 7137 if (AI.Status == AllocationInfo::INVALID) 7138 continue; 7139 7140 if (Value *Align = getAllocAlignment(AI.CB, TLI)) { 7141 std::optional<APInt> APAlign = getAPInt(A, *this, *Align); 7142 if (!APAlign) { 7143 // Can't generate an alloca which respects the required alignment 7144 // on the allocation. 7145 LLVM_DEBUG(dbgs() << "[H2S] Unknown allocation alignment: " << *AI.CB 7146 << "\n"); 7147 AI.Status = AllocationInfo::INVALID; 7148 Changed = ChangeStatus::CHANGED; 7149 continue; 7150 } 7151 if (APAlign->ugt(llvm::Value::MaximumAlignment) || 7152 !APAlign->isPowerOf2()) { 7153 LLVM_DEBUG(dbgs() << "[H2S] Invalid allocation alignment: " << APAlign 7154 << "\n"); 7155 AI.Status = AllocationInfo::INVALID; 7156 Changed = ChangeStatus::CHANGED; 7157 continue; 7158 } 7159 } 7160 7161 std::optional<APInt> Size = getSize(A, *this, AI); 7162 if (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared && 7163 MaxHeapToStackSize != -1) { 7164 if (!Size || Size->ugt(MaxHeapToStackSize)) { 7165 LLVM_DEBUG({ 7166 if (!Size) 7167 dbgs() << "[H2S] Unknown allocation size: " << *AI.CB << "\n"; 7168 else 7169 dbgs() << "[H2S] Allocation size too large: " << *AI.CB << " vs. " 7170 << MaxHeapToStackSize << "\n"; 7171 }); 7172 7173 AI.Status = AllocationInfo::INVALID; 7174 Changed = ChangeStatus::CHANGED; 7175 continue; 7176 } 7177 } 7178 7179 switch (AI.Status) { 7180 case AllocationInfo::STACK_DUE_TO_USE: 7181 if (UsesCheck(AI)) 7182 break; 7183 AI.Status = AllocationInfo::STACK_DUE_TO_FREE; 7184 [[fallthrough]]; 7185 case AllocationInfo::STACK_DUE_TO_FREE: 7186 if (FreeCheck(AI)) 7187 break; 7188 AI.Status = AllocationInfo::INVALID; 7189 Changed = ChangeStatus::CHANGED; 7190 break; 7191 case AllocationInfo::INVALID: 7192 llvm_unreachable("Invalid allocations should never reach this point!"); 7193 }; 7194 7195 // Check if we still think we can move it into the entry block. If the 7196 // alloca comes from a converted __kmpc_alloc_shared then we can usually 7197 // ignore the potential compilations associated with loops. 7198 bool IsGlobalizedLocal = 7199 AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared; 7200 if (AI.MoveAllocaIntoEntry && 7201 (!Size.has_value() || 7202 (!IsGlobalizedLocal && IsInLoop(*AI.CB->getParent())))) 7203 AI.MoveAllocaIntoEntry = false; 7204 } 7205 7206 return Changed; 7207 } 7208 } // namespace 7209 7210 /// ----------------------- Privatizable Pointers ------------------------------ 7211 namespace { 7212 struct AAPrivatizablePtrImpl : public AAPrivatizablePtr { 7213 AAPrivatizablePtrImpl(const IRPosition &IRP, Attributor &A) 7214 : AAPrivatizablePtr(IRP, A), PrivatizableType(std::nullopt) {} 7215 7216 ChangeStatus indicatePessimisticFixpoint() override { 7217 AAPrivatizablePtr::indicatePessimisticFixpoint(); 7218 PrivatizableType = nullptr; 7219 return ChangeStatus::CHANGED; 7220 } 7221 7222 /// Identify the type we can chose for a private copy of the underlying 7223 /// argument. std::nullopt means it is not clear yet, nullptr means there is 7224 /// none. 7225 virtual std::optional<Type *> identifyPrivatizableType(Attributor &A) = 0; 7226 7227 /// Return a privatizable type that encloses both T0 and T1. 7228 /// TODO: This is merely a stub for now as we should manage a mapping as well. 7229 std::optional<Type *> combineTypes(std::optional<Type *> T0, 7230 std::optional<Type *> T1) { 7231 if (!T0) 7232 return T1; 7233 if (!T1) 7234 return T0; 7235 if (T0 == T1) 7236 return T0; 7237 return nullptr; 7238 } 7239 7240 std::optional<Type *> getPrivatizableType() const override { 7241 return PrivatizableType; 7242 } 7243 7244 const std::string getAsStr(Attributor *A) const override { 7245 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]"; 7246 } 7247 7248 protected: 7249 std::optional<Type *> PrivatizableType; 7250 }; 7251 7252 // TODO: Do this for call site arguments (probably also other values) as well. 7253 7254 struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl { 7255 AAPrivatizablePtrArgument(const IRPosition &IRP, Attributor &A) 7256 : AAPrivatizablePtrImpl(IRP, A) {} 7257 7258 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...) 7259 std::optional<Type *> identifyPrivatizableType(Attributor &A) override { 7260 // If this is a byval argument and we know all the call sites (so we can 7261 // rewrite them), there is no need to check them explicitly. 7262 bool UsedAssumedInformation = false; 7263 SmallVector<Attribute, 1> Attrs; 7264 A.getAttrs(getIRPosition(), {Attribute::ByVal}, Attrs, 7265 /* IgnoreSubsumingPositions */ true); 7266 if (!Attrs.empty() && 7267 A.checkForAllCallSites([](AbstractCallSite ACS) { return true; }, *this, 7268 true, UsedAssumedInformation)) 7269 return Attrs[0].getValueAsType(); 7270 7271 std::optional<Type *> Ty; 7272 unsigned ArgNo = getIRPosition().getCallSiteArgNo(); 7273 7274 // Make sure the associated call site argument has the same type at all call 7275 // sites and it is an allocation we know is safe to privatize, for now that 7276 // means we only allow alloca instructions. 7277 // TODO: We can additionally analyze the accesses in the callee to create 7278 // the type from that information instead. That is a little more 7279 // involved and will be done in a follow up patch. 7280 auto CallSiteCheck = [&](AbstractCallSite ACS) { 7281 IRPosition ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo); 7282 // Check if a coresponding argument was found or if it is one not 7283 // associated (which can happen for callback calls). 7284 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID) 7285 return false; 7286 7287 // Check that all call sites agree on a type. 7288 auto *PrivCSArgAA = 7289 A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos, DepClassTy::REQUIRED); 7290 if (!PrivCSArgAA) 7291 return false; 7292 std::optional<Type *> CSTy = PrivCSArgAA->getPrivatizableType(); 7293 7294 LLVM_DEBUG({ 7295 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: "; 7296 if (CSTy && *CSTy) 7297 (*CSTy)->print(dbgs()); 7298 else if (CSTy) 7299 dbgs() << "<nullptr>"; 7300 else 7301 dbgs() << "<none>"; 7302 }); 7303 7304 Ty = combineTypes(Ty, CSTy); 7305 7306 LLVM_DEBUG({ 7307 dbgs() << " : New Type: "; 7308 if (Ty && *Ty) 7309 (*Ty)->print(dbgs()); 7310 else if (Ty) 7311 dbgs() << "<nullptr>"; 7312 else 7313 dbgs() << "<none>"; 7314 dbgs() << "\n"; 7315 }); 7316 7317 return !Ty || *Ty; 7318 }; 7319 7320 if (!A.checkForAllCallSites(CallSiteCheck, *this, true, 7321 UsedAssumedInformation)) 7322 return nullptr; 7323 return Ty; 7324 } 7325 7326 /// See AbstractAttribute::updateImpl(...). 7327 ChangeStatus updateImpl(Attributor &A) override { 7328 PrivatizableType = identifyPrivatizableType(A); 7329 if (!PrivatizableType) 7330 return ChangeStatus::UNCHANGED; 7331 if (!*PrivatizableType) 7332 return indicatePessimisticFixpoint(); 7333 7334 // The dependence is optional so we don't give up once we give up on the 7335 // alignment. 7336 A.getAAFor<AAAlign>(*this, IRPosition::value(getAssociatedValue()), 7337 DepClassTy::OPTIONAL); 7338 7339 // Avoid arguments with padding for now. 7340 if (!A.hasAttr(getIRPosition(), Attribute::ByVal) && 7341 !isDenselyPacked(*PrivatizableType, A.getInfoCache().getDL())) { 7342 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n"); 7343 return indicatePessimisticFixpoint(); 7344 } 7345 7346 // Collect the types that will replace the privatizable type in the function 7347 // signature. 7348 SmallVector<Type *, 16> ReplacementTypes; 7349 identifyReplacementTypes(*PrivatizableType, ReplacementTypes); 7350 7351 // Verify callee and caller agree on how the promoted argument would be 7352 // passed. 7353 Function &Fn = *getIRPosition().getAnchorScope(); 7354 const auto *TTI = 7355 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn); 7356 if (!TTI) { 7357 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Missing TTI for function " 7358 << Fn.getName() << "\n"); 7359 return indicatePessimisticFixpoint(); 7360 } 7361 7362 auto CallSiteCheck = [&](AbstractCallSite ACS) { 7363 CallBase *CB = ACS.getInstruction(); 7364 return TTI->areTypesABICompatible( 7365 CB->getCaller(), 7366 dyn_cast_if_present<Function>(CB->getCalledOperand()), 7367 ReplacementTypes); 7368 }; 7369 bool UsedAssumedInformation = false; 7370 if (!A.checkForAllCallSites(CallSiteCheck, *this, true, 7371 UsedAssumedInformation)) { 7372 LLVM_DEBUG( 7373 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for " 7374 << Fn.getName() << "\n"); 7375 return indicatePessimisticFixpoint(); 7376 } 7377 7378 // Register a rewrite of the argument. 7379 Argument *Arg = getAssociatedArgument(); 7380 if (!A.isValidFunctionSignatureRewrite(*Arg, ReplacementTypes)) { 7381 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n"); 7382 return indicatePessimisticFixpoint(); 7383 } 7384 7385 unsigned ArgNo = Arg->getArgNo(); 7386 7387 // Helper to check if for the given call site the associated argument is 7388 // passed to a callback where the privatization would be different. 7389 auto IsCompatiblePrivArgOfCallback = [&](CallBase &CB) { 7390 SmallVector<const Use *, 4> CallbackUses; 7391 AbstractCallSite::getCallbackUses(CB, CallbackUses); 7392 for (const Use *U : CallbackUses) { 7393 AbstractCallSite CBACS(U); 7394 assert(CBACS && CBACS.isCallbackCall()); 7395 for (Argument &CBArg : CBACS.getCalledFunction()->args()) { 7396 int CBArgNo = CBACS.getCallArgOperandNo(CBArg); 7397 7398 LLVM_DEBUG({ 7399 dbgs() 7400 << "[AAPrivatizablePtr] Argument " << *Arg 7401 << "check if can be privatized in the context of its parent (" 7402 << Arg->getParent()->getName() 7403 << ")\n[AAPrivatizablePtr] because it is an argument in a " 7404 "callback (" 7405 << CBArgNo << "@" << CBACS.getCalledFunction()->getName() 7406 << ")\n[AAPrivatizablePtr] " << CBArg << " : " 7407 << CBACS.getCallArgOperand(CBArg) << " vs " 7408 << CB.getArgOperand(ArgNo) << "\n" 7409 << "[AAPrivatizablePtr] " << CBArg << " : " 7410 << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n"; 7411 }); 7412 7413 if (CBArgNo != int(ArgNo)) 7414 continue; 7415 const auto *CBArgPrivAA = A.getAAFor<AAPrivatizablePtr>( 7416 *this, IRPosition::argument(CBArg), DepClassTy::REQUIRED); 7417 if (CBArgPrivAA && CBArgPrivAA->isValidState()) { 7418 auto CBArgPrivTy = CBArgPrivAA->getPrivatizableType(); 7419 if (!CBArgPrivTy) 7420 continue; 7421 if (*CBArgPrivTy == PrivatizableType) 7422 continue; 7423 } 7424 7425 LLVM_DEBUG({ 7426 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg 7427 << " cannot be privatized in the context of its parent (" 7428 << Arg->getParent()->getName() 7429 << ")\n[AAPrivatizablePtr] because it is an argument in a " 7430 "callback (" 7431 << CBArgNo << "@" << CBACS.getCalledFunction()->getName() 7432 << ").\n[AAPrivatizablePtr] for which the argument " 7433 "privatization is not compatible.\n"; 7434 }); 7435 return false; 7436 } 7437 } 7438 return true; 7439 }; 7440 7441 // Helper to check if for the given call site the associated argument is 7442 // passed to a direct call where the privatization would be different. 7443 auto IsCompatiblePrivArgOfDirectCS = [&](AbstractCallSite ACS) { 7444 CallBase *DC = cast<CallBase>(ACS.getInstruction()); 7445 int DCArgNo = ACS.getCallArgOperandNo(ArgNo); 7446 assert(DCArgNo >= 0 && unsigned(DCArgNo) < DC->arg_size() && 7447 "Expected a direct call operand for callback call operand"); 7448 7449 Function *DCCallee = 7450 dyn_cast_if_present<Function>(DC->getCalledOperand()); 7451 LLVM_DEBUG({ 7452 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg 7453 << " check if be privatized in the context of its parent (" 7454 << Arg->getParent()->getName() 7455 << ")\n[AAPrivatizablePtr] because it is an argument in a " 7456 "direct call of (" 7457 << DCArgNo << "@" << DCCallee->getName() << ").\n"; 7458 }); 7459 7460 if (unsigned(DCArgNo) < DCCallee->arg_size()) { 7461 const auto *DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>( 7462 *this, IRPosition::argument(*DCCallee->getArg(DCArgNo)), 7463 DepClassTy::REQUIRED); 7464 if (DCArgPrivAA && DCArgPrivAA->isValidState()) { 7465 auto DCArgPrivTy = DCArgPrivAA->getPrivatizableType(); 7466 if (!DCArgPrivTy) 7467 return true; 7468 if (*DCArgPrivTy == PrivatizableType) 7469 return true; 7470 } 7471 } 7472 7473 LLVM_DEBUG({ 7474 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg 7475 << " cannot be privatized in the context of its parent (" 7476 << Arg->getParent()->getName() 7477 << ")\n[AAPrivatizablePtr] because it is an argument in a " 7478 "direct call of (" 7479 << ACS.getInstruction()->getCalledOperand()->getName() 7480 << ").\n[AAPrivatizablePtr] for which the argument " 7481 "privatization is not compatible.\n"; 7482 }); 7483 return false; 7484 }; 7485 7486 // Helper to check if the associated argument is used at the given abstract 7487 // call site in a way that is incompatible with the privatization assumed 7488 // here. 7489 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) { 7490 if (ACS.isDirectCall()) 7491 return IsCompatiblePrivArgOfCallback(*ACS.getInstruction()); 7492 if (ACS.isCallbackCall()) 7493 return IsCompatiblePrivArgOfDirectCS(ACS); 7494 return false; 7495 }; 7496 7497 if (!A.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite, *this, true, 7498 UsedAssumedInformation)) 7499 return indicatePessimisticFixpoint(); 7500 7501 return ChangeStatus::UNCHANGED; 7502 } 7503 7504 /// Given a type to private \p PrivType, collect the constituates (which are 7505 /// used) in \p ReplacementTypes. 7506 static void 7507 identifyReplacementTypes(Type *PrivType, 7508 SmallVectorImpl<Type *> &ReplacementTypes) { 7509 // TODO: For now we expand the privatization type to the fullest which can 7510 // lead to dead arguments that need to be removed later. 7511 assert(PrivType && "Expected privatizable type!"); 7512 7513 // Traverse the type, extract constituate types on the outermost level. 7514 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) { 7515 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) 7516 ReplacementTypes.push_back(PrivStructType->getElementType(u)); 7517 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) { 7518 ReplacementTypes.append(PrivArrayType->getNumElements(), 7519 PrivArrayType->getElementType()); 7520 } else { 7521 ReplacementTypes.push_back(PrivType); 7522 } 7523 } 7524 7525 /// Initialize \p Base according to the type \p PrivType at position \p IP. 7526 /// The values needed are taken from the arguments of \p F starting at 7527 /// position \p ArgNo. 7528 static void createInitialization(Type *PrivType, Value &Base, Function &F, 7529 unsigned ArgNo, BasicBlock::iterator IP) { 7530 assert(PrivType && "Expected privatizable type!"); 7531 7532 IRBuilder<NoFolder> IRB(IP->getParent(), IP); 7533 const DataLayout &DL = F.getDataLayout(); 7534 7535 // Traverse the type, build GEPs and stores. 7536 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) { 7537 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType); 7538 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) { 7539 Value *Ptr = 7540 constructPointer(&Base, PrivStructLayout->getElementOffset(u), IRB); 7541 new StoreInst(F.getArg(ArgNo + u), Ptr, IP); 7542 } 7543 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) { 7544 Type *PointeeTy = PrivArrayType->getElementType(); 7545 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy); 7546 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) { 7547 Value *Ptr = constructPointer(&Base, u * PointeeTySize, IRB); 7548 new StoreInst(F.getArg(ArgNo + u), Ptr, IP); 7549 } 7550 } else { 7551 new StoreInst(F.getArg(ArgNo), &Base, IP); 7552 } 7553 } 7554 7555 /// Extract values from \p Base according to the type \p PrivType at the 7556 /// call position \p ACS. The values are appended to \p ReplacementValues. 7557 void createReplacementValues(Align Alignment, Type *PrivType, 7558 AbstractCallSite ACS, Value *Base, 7559 SmallVectorImpl<Value *> &ReplacementValues) { 7560 assert(Base && "Expected base value!"); 7561 assert(PrivType && "Expected privatizable type!"); 7562 Instruction *IP = ACS.getInstruction(); 7563 7564 IRBuilder<NoFolder> IRB(IP); 7565 const DataLayout &DL = IP->getDataLayout(); 7566 7567 // Traverse the type, build GEPs and loads. 7568 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) { 7569 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType); 7570 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) { 7571 Type *PointeeTy = PrivStructType->getElementType(u); 7572 Value *Ptr = 7573 constructPointer(Base, PrivStructLayout->getElementOffset(u), IRB); 7574 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator()); 7575 L->setAlignment(Alignment); 7576 ReplacementValues.push_back(L); 7577 } 7578 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) { 7579 Type *PointeeTy = PrivArrayType->getElementType(); 7580 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy); 7581 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) { 7582 Value *Ptr = constructPointer(Base, u * PointeeTySize, IRB); 7583 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator()); 7584 L->setAlignment(Alignment); 7585 ReplacementValues.push_back(L); 7586 } 7587 } else { 7588 LoadInst *L = new LoadInst(PrivType, Base, "", IP->getIterator()); 7589 L->setAlignment(Alignment); 7590 ReplacementValues.push_back(L); 7591 } 7592 } 7593 7594 /// See AbstractAttribute::manifest(...) 7595 ChangeStatus manifest(Attributor &A) override { 7596 if (!PrivatizableType) 7597 return ChangeStatus::UNCHANGED; 7598 assert(*PrivatizableType && "Expected privatizable type!"); 7599 7600 // Collect all tail calls in the function as we cannot allow new allocas to 7601 // escape into tail recursion. 7602 // TODO: Be smarter about new allocas escaping into tail calls. 7603 SmallVector<CallInst *, 16> TailCalls; 7604 bool UsedAssumedInformation = false; 7605 if (!A.checkForAllInstructions( 7606 [&](Instruction &I) { 7607 CallInst &CI = cast<CallInst>(I); 7608 if (CI.isTailCall()) 7609 TailCalls.push_back(&CI); 7610 return true; 7611 }, 7612 *this, {Instruction::Call}, UsedAssumedInformation)) 7613 return ChangeStatus::UNCHANGED; 7614 7615 Argument *Arg = getAssociatedArgument(); 7616 // Query AAAlign attribute for alignment of associated argument to 7617 // determine the best alignment of loads. 7618 const auto *AlignAA = 7619 A.getAAFor<AAAlign>(*this, IRPosition::value(*Arg), DepClassTy::NONE); 7620 7621 // Callback to repair the associated function. A new alloca is placed at the 7622 // beginning and initialized with the values passed through arguments. The 7623 // new alloca replaces the use of the old pointer argument. 7624 Attributor::ArgumentReplacementInfo::CalleeRepairCBTy FnRepairCB = 7625 [=](const Attributor::ArgumentReplacementInfo &ARI, 7626 Function &ReplacementFn, Function::arg_iterator ArgIt) { 7627 BasicBlock &EntryBB = ReplacementFn.getEntryBlock(); 7628 BasicBlock::iterator IP = EntryBB.getFirstInsertionPt(); 7629 const DataLayout &DL = IP->getDataLayout(); 7630 unsigned AS = DL.getAllocaAddrSpace(); 7631 Instruction *AI = new AllocaInst(*PrivatizableType, AS, 7632 Arg->getName() + ".priv", IP); 7633 createInitialization(*PrivatizableType, *AI, ReplacementFn, 7634 ArgIt->getArgNo(), IP); 7635 7636 if (AI->getType() != Arg->getType()) 7637 AI = BitCastInst::CreatePointerBitCastOrAddrSpaceCast( 7638 AI, Arg->getType(), "", IP); 7639 Arg->replaceAllUsesWith(AI); 7640 7641 for (CallInst *CI : TailCalls) 7642 CI->setTailCall(false); 7643 }; 7644 7645 // Callback to repair a call site of the associated function. The elements 7646 // of the privatizable type are loaded prior to the call and passed to the 7647 // new function version. 7648 Attributor::ArgumentReplacementInfo::ACSRepairCBTy ACSRepairCB = 7649 [=](const Attributor::ArgumentReplacementInfo &ARI, 7650 AbstractCallSite ACS, SmallVectorImpl<Value *> &NewArgOperands) { 7651 // When no alignment is specified for the load instruction, 7652 // natural alignment is assumed. 7653 createReplacementValues( 7654 AlignAA ? AlignAA->getAssumedAlign() : Align(0), 7655 *PrivatizableType, ACS, 7656 ACS.getCallArgOperand(ARI.getReplacedArg().getArgNo()), 7657 NewArgOperands); 7658 }; 7659 7660 // Collect the types that will replace the privatizable type in the function 7661 // signature. 7662 SmallVector<Type *, 16> ReplacementTypes; 7663 identifyReplacementTypes(*PrivatizableType, ReplacementTypes); 7664 7665 // Register a rewrite of the argument. 7666 if (A.registerFunctionSignatureRewrite(*Arg, ReplacementTypes, 7667 std::move(FnRepairCB), 7668 std::move(ACSRepairCB))) 7669 return ChangeStatus::CHANGED; 7670 return ChangeStatus::UNCHANGED; 7671 } 7672 7673 /// See AbstractAttribute::trackStatistics() 7674 void trackStatistics() const override { 7675 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr); 7676 } 7677 }; 7678 7679 struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl { 7680 AAPrivatizablePtrFloating(const IRPosition &IRP, Attributor &A) 7681 : AAPrivatizablePtrImpl(IRP, A) {} 7682 7683 /// See AbstractAttribute::initialize(...). 7684 void initialize(Attributor &A) override { 7685 // TODO: We can privatize more than arguments. 7686 indicatePessimisticFixpoint(); 7687 } 7688 7689 ChangeStatus updateImpl(Attributor &A) override { 7690 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::" 7691 "updateImpl will not be called"); 7692 } 7693 7694 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...) 7695 std::optional<Type *> identifyPrivatizableType(Attributor &A) override { 7696 Value *Obj = getUnderlyingObject(&getAssociatedValue()); 7697 if (!Obj) { 7698 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n"); 7699 return nullptr; 7700 } 7701 7702 if (auto *AI = dyn_cast<AllocaInst>(Obj)) 7703 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize())) 7704 if (CI->isOne()) 7705 return AI->getAllocatedType(); 7706 if (auto *Arg = dyn_cast<Argument>(Obj)) { 7707 auto *PrivArgAA = A.getAAFor<AAPrivatizablePtr>( 7708 *this, IRPosition::argument(*Arg), DepClassTy::REQUIRED); 7709 if (PrivArgAA && PrivArgAA->isAssumedPrivatizablePtr()) 7710 return PrivArgAA->getPrivatizableType(); 7711 } 7712 7713 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid " 7714 "alloca nor privatizable argument: " 7715 << *Obj << "!\n"); 7716 return nullptr; 7717 } 7718 7719 /// See AbstractAttribute::trackStatistics() 7720 void trackStatistics() const override { 7721 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr); 7722 } 7723 }; 7724 7725 struct AAPrivatizablePtrCallSiteArgument final 7726 : public AAPrivatizablePtrFloating { 7727 AAPrivatizablePtrCallSiteArgument(const IRPosition &IRP, Attributor &A) 7728 : AAPrivatizablePtrFloating(IRP, A) {} 7729 7730 /// See AbstractAttribute::initialize(...). 7731 void initialize(Attributor &A) override { 7732 if (A.hasAttr(getIRPosition(), Attribute::ByVal)) 7733 indicateOptimisticFixpoint(); 7734 } 7735 7736 /// See AbstractAttribute::updateImpl(...). 7737 ChangeStatus updateImpl(Attributor &A) override { 7738 PrivatizableType = identifyPrivatizableType(A); 7739 if (!PrivatizableType) 7740 return ChangeStatus::UNCHANGED; 7741 if (!*PrivatizableType) 7742 return indicatePessimisticFixpoint(); 7743 7744 const IRPosition &IRP = getIRPosition(); 7745 bool IsKnownNoCapture; 7746 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>( 7747 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoCapture); 7748 if (!IsAssumedNoCapture) { 7749 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n"); 7750 return indicatePessimisticFixpoint(); 7751 } 7752 7753 bool IsKnownNoAlias; 7754 if (!AA::hasAssumedIRAttr<Attribute::NoAlias>( 7755 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoAlias)) { 7756 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n"); 7757 return indicatePessimisticFixpoint(); 7758 } 7759 7760 bool IsKnown; 7761 if (!AA::isAssumedReadOnly(A, IRP, *this, IsKnown)) { 7762 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n"); 7763 return indicatePessimisticFixpoint(); 7764 } 7765 7766 return ChangeStatus::UNCHANGED; 7767 } 7768 7769 /// See AbstractAttribute::trackStatistics() 7770 void trackStatistics() const override { 7771 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr); 7772 } 7773 }; 7774 7775 struct AAPrivatizablePtrCallSiteReturned final 7776 : public AAPrivatizablePtrFloating { 7777 AAPrivatizablePtrCallSiteReturned(const IRPosition &IRP, Attributor &A) 7778 : AAPrivatizablePtrFloating(IRP, A) {} 7779 7780 /// See AbstractAttribute::initialize(...). 7781 void initialize(Attributor &A) override { 7782 // TODO: We can privatize more than arguments. 7783 indicatePessimisticFixpoint(); 7784 } 7785 7786 /// See AbstractAttribute::trackStatistics() 7787 void trackStatistics() const override { 7788 STATS_DECLTRACK_CSRET_ATTR(privatizable_ptr); 7789 } 7790 }; 7791 7792 struct AAPrivatizablePtrReturned final : public AAPrivatizablePtrFloating { 7793 AAPrivatizablePtrReturned(const IRPosition &IRP, Attributor &A) 7794 : AAPrivatizablePtrFloating(IRP, A) {} 7795 7796 /// See AbstractAttribute::initialize(...). 7797 void initialize(Attributor &A) override { 7798 // TODO: We can privatize more than arguments. 7799 indicatePessimisticFixpoint(); 7800 } 7801 7802 /// See AbstractAttribute::trackStatistics() 7803 void trackStatistics() const override { 7804 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr); 7805 } 7806 }; 7807 } // namespace 7808 7809 /// -------------------- Memory Behavior Attributes ---------------------------- 7810 /// Includes read-none, read-only, and write-only. 7811 /// ---------------------------------------------------------------------------- 7812 namespace { 7813 struct AAMemoryBehaviorImpl : public AAMemoryBehavior { 7814 AAMemoryBehaviorImpl(const IRPosition &IRP, Attributor &A) 7815 : AAMemoryBehavior(IRP, A) {} 7816 7817 /// See AbstractAttribute::initialize(...). 7818 void initialize(Attributor &A) override { 7819 intersectAssumedBits(BEST_STATE); 7820 getKnownStateFromValue(A, getIRPosition(), getState()); 7821 AAMemoryBehavior::initialize(A); 7822 } 7823 7824 /// Return the memory behavior information encoded in the IR for \p IRP. 7825 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP, 7826 BitIntegerState &State, 7827 bool IgnoreSubsumingPositions = false) { 7828 SmallVector<Attribute, 2> Attrs; 7829 A.getAttrs(IRP, AttrKinds, Attrs, IgnoreSubsumingPositions); 7830 for (const Attribute &Attr : Attrs) { 7831 switch (Attr.getKindAsEnum()) { 7832 case Attribute::ReadNone: 7833 State.addKnownBits(NO_ACCESSES); 7834 break; 7835 case Attribute::ReadOnly: 7836 State.addKnownBits(NO_WRITES); 7837 break; 7838 case Attribute::WriteOnly: 7839 State.addKnownBits(NO_READS); 7840 break; 7841 default: 7842 llvm_unreachable("Unexpected attribute!"); 7843 } 7844 } 7845 7846 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) { 7847 if (!I->mayReadFromMemory()) 7848 State.addKnownBits(NO_READS); 7849 if (!I->mayWriteToMemory()) 7850 State.addKnownBits(NO_WRITES); 7851 } 7852 } 7853 7854 /// See AbstractAttribute::getDeducedAttributes(...). 7855 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, 7856 SmallVectorImpl<Attribute> &Attrs) const override { 7857 assert(Attrs.size() == 0); 7858 if (isAssumedReadNone()) 7859 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone)); 7860 else if (isAssumedReadOnly()) 7861 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly)); 7862 else if (isAssumedWriteOnly()) 7863 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly)); 7864 assert(Attrs.size() <= 1); 7865 } 7866 7867 /// See AbstractAttribute::manifest(...). 7868 ChangeStatus manifest(Attributor &A) override { 7869 const IRPosition &IRP = getIRPosition(); 7870 7871 if (A.hasAttr(IRP, Attribute::ReadNone, 7872 /* IgnoreSubsumingPositions */ true)) 7873 return ChangeStatus::UNCHANGED; 7874 7875 // Check if we would improve the existing attributes first. 7876 SmallVector<Attribute, 4> DeducedAttrs; 7877 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs); 7878 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) { 7879 return A.hasAttr(IRP, Attr.getKindAsEnum(), 7880 /* IgnoreSubsumingPositions */ true); 7881 })) 7882 return ChangeStatus::UNCHANGED; 7883 7884 // Clear existing attributes. 7885 A.removeAttrs(IRP, AttrKinds); 7886 // Clear conflicting writable attribute. 7887 if (isAssumedReadOnly()) 7888 A.removeAttrs(IRP, Attribute::Writable); 7889 7890 // Use the generic manifest method. 7891 return IRAttribute::manifest(A); 7892 } 7893 7894 /// See AbstractState::getAsStr(). 7895 const std::string getAsStr(Attributor *A) const override { 7896 if (isAssumedReadNone()) 7897 return "readnone"; 7898 if (isAssumedReadOnly()) 7899 return "readonly"; 7900 if (isAssumedWriteOnly()) 7901 return "writeonly"; 7902 return "may-read/write"; 7903 } 7904 7905 /// The set of IR attributes AAMemoryBehavior deals with. 7906 static const Attribute::AttrKind AttrKinds[3]; 7907 }; 7908 7909 const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = { 7910 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly}; 7911 7912 /// Memory behavior attribute for a floating value. 7913 struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl { 7914 AAMemoryBehaviorFloating(const IRPosition &IRP, Attributor &A) 7915 : AAMemoryBehaviorImpl(IRP, A) {} 7916 7917 /// See AbstractAttribute::updateImpl(...). 7918 ChangeStatus updateImpl(Attributor &A) override; 7919 7920 /// See AbstractAttribute::trackStatistics() 7921 void trackStatistics() const override { 7922 if (isAssumedReadNone()) 7923 STATS_DECLTRACK_FLOATING_ATTR(readnone) 7924 else if (isAssumedReadOnly()) 7925 STATS_DECLTRACK_FLOATING_ATTR(readonly) 7926 else if (isAssumedWriteOnly()) 7927 STATS_DECLTRACK_FLOATING_ATTR(writeonly) 7928 } 7929 7930 private: 7931 /// Return true if users of \p UserI might access the underlying 7932 /// variable/location described by \p U and should therefore be analyzed. 7933 bool followUsersOfUseIn(Attributor &A, const Use &U, 7934 const Instruction *UserI); 7935 7936 /// Update the state according to the effect of use \p U in \p UserI. 7937 void analyzeUseIn(Attributor &A, const Use &U, const Instruction *UserI); 7938 }; 7939 7940 /// Memory behavior attribute for function argument. 7941 struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating { 7942 AAMemoryBehaviorArgument(const IRPosition &IRP, Attributor &A) 7943 : AAMemoryBehaviorFloating(IRP, A) {} 7944 7945 /// See AbstractAttribute::initialize(...). 7946 void initialize(Attributor &A) override { 7947 intersectAssumedBits(BEST_STATE); 7948 const IRPosition &IRP = getIRPosition(); 7949 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we 7950 // can query it when we use has/getAttr. That would allow us to reuse the 7951 // initialize of the base class here. 7952 bool HasByVal = A.hasAttr(IRP, {Attribute::ByVal}, 7953 /* IgnoreSubsumingPositions */ true); 7954 getKnownStateFromValue(A, IRP, getState(), 7955 /* IgnoreSubsumingPositions */ HasByVal); 7956 } 7957 7958 ChangeStatus manifest(Attributor &A) override { 7959 // TODO: Pointer arguments are not supported on vectors of pointers yet. 7960 if (!getAssociatedValue().getType()->isPointerTy()) 7961 return ChangeStatus::UNCHANGED; 7962 7963 // TODO: From readattrs.ll: "inalloca parameters are always 7964 // considered written" 7965 if (A.hasAttr(getIRPosition(), 7966 {Attribute::InAlloca, Attribute::Preallocated})) { 7967 removeKnownBits(NO_WRITES); 7968 removeAssumedBits(NO_WRITES); 7969 } 7970 A.removeAttrs(getIRPosition(), AttrKinds); 7971 return AAMemoryBehaviorFloating::manifest(A); 7972 } 7973 7974 /// See AbstractAttribute::trackStatistics() 7975 void trackStatistics() const override { 7976 if (isAssumedReadNone()) 7977 STATS_DECLTRACK_ARG_ATTR(readnone) 7978 else if (isAssumedReadOnly()) 7979 STATS_DECLTRACK_ARG_ATTR(readonly) 7980 else if (isAssumedWriteOnly()) 7981 STATS_DECLTRACK_ARG_ATTR(writeonly) 7982 } 7983 }; 7984 7985 struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument { 7986 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP, Attributor &A) 7987 : AAMemoryBehaviorArgument(IRP, A) {} 7988 7989 /// See AbstractAttribute::initialize(...). 7990 void initialize(Attributor &A) override { 7991 // If we don't have an associated attribute this is either a variadic call 7992 // or an indirect call, either way, nothing to do here. 7993 Argument *Arg = getAssociatedArgument(); 7994 if (!Arg) { 7995 indicatePessimisticFixpoint(); 7996 return; 7997 } 7998 if (Arg->hasByValAttr()) { 7999 addKnownBits(NO_WRITES); 8000 removeKnownBits(NO_READS); 8001 removeAssumedBits(NO_READS); 8002 } 8003 AAMemoryBehaviorArgument::initialize(A); 8004 if (getAssociatedFunction()->isDeclaration()) 8005 indicatePessimisticFixpoint(); 8006 } 8007 8008 /// See AbstractAttribute::updateImpl(...). 8009 ChangeStatus updateImpl(Attributor &A) override { 8010 // TODO: Once we have call site specific value information we can provide 8011 // call site specific liveness liveness information and then it makes 8012 // sense to specialize attributes for call sites arguments instead of 8013 // redirecting requests to the callee argument. 8014 Argument *Arg = getAssociatedArgument(); 8015 const IRPosition &ArgPos = IRPosition::argument(*Arg); 8016 auto *ArgAA = 8017 A.getAAFor<AAMemoryBehavior>(*this, ArgPos, DepClassTy::REQUIRED); 8018 if (!ArgAA) 8019 return indicatePessimisticFixpoint(); 8020 return clampStateAndIndicateChange(getState(), ArgAA->getState()); 8021 } 8022 8023 /// See AbstractAttribute::trackStatistics() 8024 void trackStatistics() const override { 8025 if (isAssumedReadNone()) 8026 STATS_DECLTRACK_CSARG_ATTR(readnone) 8027 else if (isAssumedReadOnly()) 8028 STATS_DECLTRACK_CSARG_ATTR(readonly) 8029 else if (isAssumedWriteOnly()) 8030 STATS_DECLTRACK_CSARG_ATTR(writeonly) 8031 } 8032 }; 8033 8034 /// Memory behavior attribute for a call site return position. 8035 struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating { 8036 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP, Attributor &A) 8037 : AAMemoryBehaviorFloating(IRP, A) {} 8038 8039 /// See AbstractAttribute::initialize(...). 8040 void initialize(Attributor &A) override { 8041 AAMemoryBehaviorImpl::initialize(A); 8042 } 8043 /// See AbstractAttribute::manifest(...). 8044 ChangeStatus manifest(Attributor &A) override { 8045 // We do not annotate returned values. 8046 return ChangeStatus::UNCHANGED; 8047 } 8048 8049 /// See AbstractAttribute::trackStatistics() 8050 void trackStatistics() const override {} 8051 }; 8052 8053 /// An AA to represent the memory behavior function attributes. 8054 struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl { 8055 AAMemoryBehaviorFunction(const IRPosition &IRP, Attributor &A) 8056 : AAMemoryBehaviorImpl(IRP, A) {} 8057 8058 /// See AbstractAttribute::updateImpl(Attributor &A). 8059 ChangeStatus updateImpl(Attributor &A) override; 8060 8061 /// See AbstractAttribute::manifest(...). 8062 ChangeStatus manifest(Attributor &A) override { 8063 // TODO: It would be better to merge this with AAMemoryLocation, so that 8064 // we could determine read/write per location. This would also have the 8065 // benefit of only one place trying to manifest the memory attribute. 8066 Function &F = cast<Function>(getAnchorValue()); 8067 MemoryEffects ME = MemoryEffects::unknown(); 8068 if (isAssumedReadNone()) 8069 ME = MemoryEffects::none(); 8070 else if (isAssumedReadOnly()) 8071 ME = MemoryEffects::readOnly(); 8072 else if (isAssumedWriteOnly()) 8073 ME = MemoryEffects::writeOnly(); 8074 8075 A.removeAttrs(getIRPosition(), AttrKinds); 8076 // Clear conflicting writable attribute. 8077 if (ME.onlyReadsMemory()) 8078 for (Argument &Arg : F.args()) 8079 A.removeAttrs(IRPosition::argument(Arg), Attribute::Writable); 8080 return A.manifestAttrs(getIRPosition(), 8081 Attribute::getWithMemoryEffects(F.getContext(), ME)); 8082 } 8083 8084 /// See AbstractAttribute::trackStatistics() 8085 void trackStatistics() const override { 8086 if (isAssumedReadNone()) 8087 STATS_DECLTRACK_FN_ATTR(readnone) 8088 else if (isAssumedReadOnly()) 8089 STATS_DECLTRACK_FN_ATTR(readonly) 8090 else if (isAssumedWriteOnly()) 8091 STATS_DECLTRACK_FN_ATTR(writeonly) 8092 } 8093 }; 8094 8095 /// AAMemoryBehavior attribute for call sites. 8096 struct AAMemoryBehaviorCallSite final 8097 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl> { 8098 AAMemoryBehaviorCallSite(const IRPosition &IRP, Attributor &A) 8099 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl>(IRP, A) {} 8100 8101 /// See AbstractAttribute::manifest(...). 8102 ChangeStatus manifest(Attributor &A) override { 8103 // TODO: Deduplicate this with AAMemoryBehaviorFunction. 8104 CallBase &CB = cast<CallBase>(getAnchorValue()); 8105 MemoryEffects ME = MemoryEffects::unknown(); 8106 if (isAssumedReadNone()) 8107 ME = MemoryEffects::none(); 8108 else if (isAssumedReadOnly()) 8109 ME = MemoryEffects::readOnly(); 8110 else if (isAssumedWriteOnly()) 8111 ME = MemoryEffects::writeOnly(); 8112 8113 A.removeAttrs(getIRPosition(), AttrKinds); 8114 // Clear conflicting writable attribute. 8115 if (ME.onlyReadsMemory()) 8116 for (Use &U : CB.args()) 8117 A.removeAttrs(IRPosition::callsite_argument(CB, U.getOperandNo()), 8118 Attribute::Writable); 8119 return A.manifestAttrs( 8120 getIRPosition(), Attribute::getWithMemoryEffects(CB.getContext(), ME)); 8121 } 8122 8123 /// See AbstractAttribute::trackStatistics() 8124 void trackStatistics() const override { 8125 if (isAssumedReadNone()) 8126 STATS_DECLTRACK_CS_ATTR(readnone) 8127 else if (isAssumedReadOnly()) 8128 STATS_DECLTRACK_CS_ATTR(readonly) 8129 else if (isAssumedWriteOnly()) 8130 STATS_DECLTRACK_CS_ATTR(writeonly) 8131 } 8132 }; 8133 8134 ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) { 8135 8136 // The current assumed state used to determine a change. 8137 auto AssumedState = getAssumed(); 8138 8139 auto CheckRWInst = [&](Instruction &I) { 8140 // If the instruction has an own memory behavior state, use it to restrict 8141 // the local state. No further analysis is required as the other memory 8142 // state is as optimistic as it gets. 8143 if (const auto *CB = dyn_cast<CallBase>(&I)) { 8144 const auto *MemBehaviorAA = A.getAAFor<AAMemoryBehavior>( 8145 *this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED); 8146 if (MemBehaviorAA) { 8147 intersectAssumedBits(MemBehaviorAA->getAssumed()); 8148 return !isAtFixpoint(); 8149 } 8150 } 8151 8152 // Remove access kind modifiers if necessary. 8153 if (I.mayReadFromMemory()) 8154 removeAssumedBits(NO_READS); 8155 if (I.mayWriteToMemory()) 8156 removeAssumedBits(NO_WRITES); 8157 return !isAtFixpoint(); 8158 }; 8159 8160 bool UsedAssumedInformation = false; 8161 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this, 8162 UsedAssumedInformation)) 8163 return indicatePessimisticFixpoint(); 8164 8165 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED 8166 : ChangeStatus::UNCHANGED; 8167 } 8168 8169 ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) { 8170 8171 const IRPosition &IRP = getIRPosition(); 8172 const IRPosition &FnPos = IRPosition::function_scope(IRP); 8173 AAMemoryBehavior::StateType &S = getState(); 8174 8175 // First, check the function scope. We take the known information and we avoid 8176 // work if the assumed information implies the current assumed information for 8177 // this attribute. This is a valid for all but byval arguments. 8178 Argument *Arg = IRP.getAssociatedArgument(); 8179 AAMemoryBehavior::base_t FnMemAssumedState = 8180 AAMemoryBehavior::StateType::getWorstState(); 8181 if (!Arg || !Arg->hasByValAttr()) { 8182 const auto *FnMemAA = 8183 A.getAAFor<AAMemoryBehavior>(*this, FnPos, DepClassTy::OPTIONAL); 8184 if (FnMemAA) { 8185 FnMemAssumedState = FnMemAA->getAssumed(); 8186 S.addKnownBits(FnMemAA->getKnown()); 8187 if ((S.getAssumed() & FnMemAA->getAssumed()) == S.getAssumed()) 8188 return ChangeStatus::UNCHANGED; 8189 } 8190 } 8191 8192 // The current assumed state used to determine a change. 8193 auto AssumedState = S.getAssumed(); 8194 8195 // Make sure the value is not captured (except through "return"), if 8196 // it is, any information derived would be irrelevant anyway as we cannot 8197 // check the potential aliases introduced by the capture. However, no need 8198 // to fall back to anythign less optimistic than the function state. 8199 bool IsKnownNoCapture; 8200 const AANoCapture *ArgNoCaptureAA = nullptr; 8201 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>( 8202 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture, false, 8203 &ArgNoCaptureAA); 8204 8205 if (!IsAssumedNoCapture && 8206 (!ArgNoCaptureAA || !ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned())) { 8207 S.intersectAssumedBits(FnMemAssumedState); 8208 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED 8209 : ChangeStatus::UNCHANGED; 8210 } 8211 8212 // Visit and expand uses until all are analyzed or a fixpoint is reached. 8213 auto UsePred = [&](const Use &U, bool &Follow) -> bool { 8214 Instruction *UserI = cast<Instruction>(U.getUser()); 8215 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << *U << " in " << *UserI 8216 << " \n"); 8217 8218 // Droppable users, e.g., llvm::assume does not actually perform any action. 8219 if (UserI->isDroppable()) 8220 return true; 8221 8222 // Check if the users of UserI should also be visited. 8223 Follow = followUsersOfUseIn(A, U, UserI); 8224 8225 // If UserI might touch memory we analyze the use in detail. 8226 if (UserI->mayReadOrWriteMemory()) 8227 analyzeUseIn(A, U, UserI); 8228 8229 return !isAtFixpoint(); 8230 }; 8231 8232 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) 8233 return indicatePessimisticFixpoint(); 8234 8235 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED 8236 : ChangeStatus::UNCHANGED; 8237 } 8238 8239 bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use &U, 8240 const Instruction *UserI) { 8241 // The loaded value is unrelated to the pointer argument, no need to 8242 // follow the users of the load. 8243 if (isa<LoadInst>(UserI) || isa<ReturnInst>(UserI)) 8244 return false; 8245 8246 // By default we follow all uses assuming UserI might leak information on U, 8247 // we have special handling for call sites operands though. 8248 const auto *CB = dyn_cast<CallBase>(UserI); 8249 if (!CB || !CB->isArgOperand(&U)) 8250 return true; 8251 8252 // If the use is a call argument known not to be captured, the users of 8253 // the call do not need to be visited because they have to be unrelated to 8254 // the input. Note that this check is not trivial even though we disallow 8255 // general capturing of the underlying argument. The reason is that the 8256 // call might the argument "through return", which we allow and for which we 8257 // need to check call users. 8258 if (U.get()->getType()->isPointerTy()) { 8259 unsigned ArgNo = CB->getArgOperandNo(&U); 8260 bool IsKnownNoCapture; 8261 return !AA::hasAssumedIRAttr<Attribute::Captures>( 8262 A, this, IRPosition::callsite_argument(*CB, ArgNo), 8263 DepClassTy::OPTIONAL, IsKnownNoCapture); 8264 } 8265 8266 return true; 8267 } 8268 8269 void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use &U, 8270 const Instruction *UserI) { 8271 assert(UserI->mayReadOrWriteMemory()); 8272 8273 switch (UserI->getOpcode()) { 8274 default: 8275 // TODO: Handle all atomics and other side-effect operations we know of. 8276 break; 8277 case Instruction::Load: 8278 // Loads cause the NO_READS property to disappear. 8279 removeAssumedBits(NO_READS); 8280 return; 8281 8282 case Instruction::Store: 8283 // Stores cause the NO_WRITES property to disappear if the use is the 8284 // pointer operand. Note that while capturing was taken care of somewhere 8285 // else we need to deal with stores of the value that is not looked through. 8286 if (cast<StoreInst>(UserI)->getPointerOperand() == U.get()) 8287 removeAssumedBits(NO_WRITES); 8288 else 8289 indicatePessimisticFixpoint(); 8290 return; 8291 8292 case Instruction::Call: 8293 case Instruction::CallBr: 8294 case Instruction::Invoke: { 8295 // For call sites we look at the argument memory behavior attribute (this 8296 // could be recursive!) in order to restrict our own state. 8297 const auto *CB = cast<CallBase>(UserI); 8298 8299 // Give up on operand bundles. 8300 if (CB->isBundleOperand(&U)) { 8301 indicatePessimisticFixpoint(); 8302 return; 8303 } 8304 8305 // Calling a function does read the function pointer, maybe write it if the 8306 // function is self-modifying. 8307 if (CB->isCallee(&U)) { 8308 removeAssumedBits(NO_READS); 8309 break; 8310 } 8311 8312 // Adjust the possible access behavior based on the information on the 8313 // argument. 8314 IRPosition Pos; 8315 if (U.get()->getType()->isPointerTy()) 8316 Pos = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U)); 8317 else 8318 Pos = IRPosition::callsite_function(*CB); 8319 const auto *MemBehaviorAA = 8320 A.getAAFor<AAMemoryBehavior>(*this, Pos, DepClassTy::OPTIONAL); 8321 if (!MemBehaviorAA) 8322 break; 8323 // "assumed" has at most the same bits as the MemBehaviorAA assumed 8324 // and at least "known". 8325 intersectAssumedBits(MemBehaviorAA->getAssumed()); 8326 return; 8327 } 8328 }; 8329 8330 // Generally, look at the "may-properties" and adjust the assumed state if we 8331 // did not trigger special handling before. 8332 if (UserI->mayReadFromMemory()) 8333 removeAssumedBits(NO_READS); 8334 if (UserI->mayWriteToMemory()) 8335 removeAssumedBits(NO_WRITES); 8336 } 8337 } // namespace 8338 8339 /// -------------------- Memory Locations Attributes --------------------------- 8340 /// Includes read-none, argmemonly, inaccessiblememonly, 8341 /// inaccessiblememorargmemonly 8342 /// ---------------------------------------------------------------------------- 8343 8344 std::string AAMemoryLocation::getMemoryLocationsAsStr( 8345 AAMemoryLocation::MemoryLocationsKind MLK) { 8346 if (0 == (MLK & AAMemoryLocation::NO_LOCATIONS)) 8347 return "all memory"; 8348 if (MLK == AAMemoryLocation::NO_LOCATIONS) 8349 return "no memory"; 8350 std::string S = "memory:"; 8351 if (0 == (MLK & AAMemoryLocation::NO_LOCAL_MEM)) 8352 S += "stack,"; 8353 if (0 == (MLK & AAMemoryLocation::NO_CONST_MEM)) 8354 S += "constant,"; 8355 if (0 == (MLK & AAMemoryLocation::NO_GLOBAL_INTERNAL_MEM)) 8356 S += "internal global,"; 8357 if (0 == (MLK & AAMemoryLocation::NO_GLOBAL_EXTERNAL_MEM)) 8358 S += "external global,"; 8359 if (0 == (MLK & AAMemoryLocation::NO_ARGUMENT_MEM)) 8360 S += "argument,"; 8361 if (0 == (MLK & AAMemoryLocation::NO_INACCESSIBLE_MEM)) 8362 S += "inaccessible,"; 8363 if (0 == (MLK & AAMemoryLocation::NO_MALLOCED_MEM)) 8364 S += "malloced,"; 8365 if (0 == (MLK & AAMemoryLocation::NO_UNKOWN_MEM)) 8366 S += "unknown,"; 8367 S.pop_back(); 8368 return S; 8369 } 8370 8371 namespace { 8372 struct AAMemoryLocationImpl : public AAMemoryLocation { 8373 8374 AAMemoryLocationImpl(const IRPosition &IRP, Attributor &A) 8375 : AAMemoryLocation(IRP, A), Allocator(A.Allocator) { 8376 AccessKind2Accesses.fill(nullptr); 8377 } 8378 8379 ~AAMemoryLocationImpl() { 8380 // The AccessSets are allocated via a BumpPtrAllocator, we call 8381 // the destructor manually. 8382 for (AccessSet *AS : AccessKind2Accesses) 8383 if (AS) 8384 AS->~AccessSet(); 8385 } 8386 8387 /// See AbstractAttribute::initialize(...). 8388 void initialize(Attributor &A) override { 8389 intersectAssumedBits(BEST_STATE); 8390 getKnownStateFromValue(A, getIRPosition(), getState()); 8391 AAMemoryLocation::initialize(A); 8392 } 8393 8394 /// Return the memory behavior information encoded in the IR for \p IRP. 8395 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP, 8396 BitIntegerState &State, 8397 bool IgnoreSubsumingPositions = false) { 8398 // For internal functions we ignore `argmemonly` and 8399 // `inaccessiblememorargmemonly` as we might break it via interprocedural 8400 // constant propagation. It is unclear if this is the best way but it is 8401 // unlikely this will cause real performance problems. If we are deriving 8402 // attributes for the anchor function we even remove the attribute in 8403 // addition to ignoring it. 8404 // TODO: A better way to handle this would be to add ~NO_GLOBAL_MEM / 8405 // MemoryEffects::Other as a possible location. 8406 bool UseArgMemOnly = true; 8407 Function *AnchorFn = IRP.getAnchorScope(); 8408 if (AnchorFn && A.isRunOn(*AnchorFn)) 8409 UseArgMemOnly = !AnchorFn->hasLocalLinkage(); 8410 8411 SmallVector<Attribute, 2> Attrs; 8412 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions); 8413 for (const Attribute &Attr : Attrs) { 8414 // TODO: We can map MemoryEffects to Attributor locations more precisely. 8415 MemoryEffects ME = Attr.getMemoryEffects(); 8416 if (ME.doesNotAccessMemory()) { 8417 State.addKnownBits(NO_LOCAL_MEM | NO_CONST_MEM); 8418 continue; 8419 } 8420 if (ME.onlyAccessesInaccessibleMem()) { 8421 State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true)); 8422 continue; 8423 } 8424 if (ME.onlyAccessesArgPointees()) { 8425 if (UseArgMemOnly) 8426 State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true)); 8427 else { 8428 // Remove location information, only keep read/write info. 8429 ME = MemoryEffects(ME.getModRef()); 8430 A.manifestAttrs(IRP, 8431 Attribute::getWithMemoryEffects( 8432 IRP.getAnchorValue().getContext(), ME), 8433 /*ForceReplace*/ true); 8434 } 8435 continue; 8436 } 8437 if (ME.onlyAccessesInaccessibleOrArgMem()) { 8438 if (UseArgMemOnly) 8439 State.addKnownBits(inverseLocation( 8440 NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true)); 8441 else { 8442 // Remove location information, only keep read/write info. 8443 ME = MemoryEffects(ME.getModRef()); 8444 A.manifestAttrs(IRP, 8445 Attribute::getWithMemoryEffects( 8446 IRP.getAnchorValue().getContext(), ME), 8447 /*ForceReplace*/ true); 8448 } 8449 continue; 8450 } 8451 } 8452 } 8453 8454 /// See AbstractAttribute::getDeducedAttributes(...). 8455 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, 8456 SmallVectorImpl<Attribute> &Attrs) const override { 8457 // TODO: We can map Attributor locations to MemoryEffects more precisely. 8458 assert(Attrs.size() == 0); 8459 if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION) { 8460 if (isAssumedReadNone()) 8461 Attrs.push_back( 8462 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::none())); 8463 else if (isAssumedInaccessibleMemOnly()) 8464 Attrs.push_back(Attribute::getWithMemoryEffects( 8465 Ctx, MemoryEffects::inaccessibleMemOnly())); 8466 else if (isAssumedArgMemOnly()) 8467 Attrs.push_back( 8468 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::argMemOnly())); 8469 else if (isAssumedInaccessibleOrArgMemOnly()) 8470 Attrs.push_back(Attribute::getWithMemoryEffects( 8471 Ctx, MemoryEffects::inaccessibleOrArgMemOnly())); 8472 } 8473 assert(Attrs.size() <= 1); 8474 } 8475 8476 /// See AbstractAttribute::manifest(...). 8477 ChangeStatus manifest(Attributor &A) override { 8478 // TODO: If AAMemoryLocation and AAMemoryBehavior are merged, we could 8479 // provide per-location modref information here. 8480 const IRPosition &IRP = getIRPosition(); 8481 8482 SmallVector<Attribute, 1> DeducedAttrs; 8483 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs); 8484 if (DeducedAttrs.size() != 1) 8485 return ChangeStatus::UNCHANGED; 8486 MemoryEffects ME = DeducedAttrs[0].getMemoryEffects(); 8487 8488 return A.manifestAttrs(IRP, Attribute::getWithMemoryEffects( 8489 IRP.getAnchorValue().getContext(), ME)); 8490 } 8491 8492 /// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...). 8493 bool checkForAllAccessesToMemoryKind( 8494 function_ref<bool(const Instruction *, const Value *, AccessKind, 8495 MemoryLocationsKind)> 8496 Pred, 8497 MemoryLocationsKind RequestedMLK) const override { 8498 if (!isValidState()) 8499 return false; 8500 8501 MemoryLocationsKind AssumedMLK = getAssumedNotAccessedLocation(); 8502 if (AssumedMLK == NO_LOCATIONS) 8503 return true; 8504 8505 unsigned Idx = 0; 8506 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; 8507 CurMLK *= 2, ++Idx) { 8508 if (CurMLK & RequestedMLK) 8509 continue; 8510 8511 if (const AccessSet *Accesses = AccessKind2Accesses[Idx]) 8512 for (const AccessInfo &AI : *Accesses) 8513 if (!Pred(AI.I, AI.Ptr, AI.Kind, CurMLK)) 8514 return false; 8515 } 8516 8517 return true; 8518 } 8519 8520 ChangeStatus indicatePessimisticFixpoint() override { 8521 // If we give up and indicate a pessimistic fixpoint this instruction will 8522 // become an access for all potential access kinds: 8523 // TODO: Add pointers for argmemonly and globals to improve the results of 8524 // checkForAllAccessesToMemoryKind. 8525 bool Changed = false; 8526 MemoryLocationsKind KnownMLK = getKnown(); 8527 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()); 8528 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) 8529 if (!(CurMLK & KnownMLK)) 8530 updateStateAndAccessesMap(getState(), CurMLK, I, nullptr, Changed, 8531 getAccessKindFromInst(I)); 8532 return AAMemoryLocation::indicatePessimisticFixpoint(); 8533 } 8534 8535 protected: 8536 /// Helper struct to tie together an instruction that has a read or write 8537 /// effect with the pointer it accesses (if any). 8538 struct AccessInfo { 8539 8540 /// The instruction that caused the access. 8541 const Instruction *I; 8542 8543 /// The base pointer that is accessed, or null if unknown. 8544 const Value *Ptr; 8545 8546 /// The kind of access (read/write/read+write). 8547 AccessKind Kind; 8548 8549 bool operator==(const AccessInfo &RHS) const { 8550 return I == RHS.I && Ptr == RHS.Ptr && Kind == RHS.Kind; 8551 } 8552 bool operator()(const AccessInfo &LHS, const AccessInfo &RHS) const { 8553 if (LHS.I != RHS.I) 8554 return LHS.I < RHS.I; 8555 if (LHS.Ptr != RHS.Ptr) 8556 return LHS.Ptr < RHS.Ptr; 8557 if (LHS.Kind != RHS.Kind) 8558 return LHS.Kind < RHS.Kind; 8559 return false; 8560 } 8561 }; 8562 8563 /// Mapping from *single* memory location kinds, e.g., LOCAL_MEM with the 8564 /// value of NO_LOCAL_MEM, to the accesses encountered for this memory kind. 8565 using AccessSet = SmallSet<AccessInfo, 2, AccessInfo>; 8566 std::array<AccessSet *, llvm::CTLog2<VALID_STATE>()> AccessKind2Accesses; 8567 8568 /// Categorize the pointer arguments of CB that might access memory in 8569 /// AccessedLoc and update the state and access map accordingly. 8570 void 8571 categorizeArgumentPointerLocations(Attributor &A, CallBase &CB, 8572 AAMemoryLocation::StateType &AccessedLocs, 8573 bool &Changed); 8574 8575 /// Return the kind(s) of location that may be accessed by \p V. 8576 AAMemoryLocation::MemoryLocationsKind 8577 categorizeAccessedLocations(Attributor &A, Instruction &I, bool &Changed); 8578 8579 /// Return the access kind as determined by \p I. 8580 AccessKind getAccessKindFromInst(const Instruction *I) { 8581 AccessKind AK = READ_WRITE; 8582 if (I) { 8583 AK = I->mayReadFromMemory() ? READ : NONE; 8584 AK = AccessKind(AK | (I->mayWriteToMemory() ? WRITE : NONE)); 8585 } 8586 return AK; 8587 } 8588 8589 /// Update the state \p State and the AccessKind2Accesses given that \p I is 8590 /// an access of kind \p AK to a \p MLK memory location with the access 8591 /// pointer \p Ptr. 8592 void updateStateAndAccessesMap(AAMemoryLocation::StateType &State, 8593 MemoryLocationsKind MLK, const Instruction *I, 8594 const Value *Ptr, bool &Changed, 8595 AccessKind AK = READ_WRITE) { 8596 8597 assert(isPowerOf2_32(MLK) && "Expected a single location set!"); 8598 auto *&Accesses = AccessKind2Accesses[llvm::Log2_32(MLK)]; 8599 if (!Accesses) 8600 Accesses = new (Allocator) AccessSet(); 8601 Changed |= Accesses->insert(AccessInfo{I, Ptr, AK}).second; 8602 if (MLK == NO_UNKOWN_MEM) 8603 MLK = NO_LOCATIONS; 8604 State.removeAssumedBits(MLK); 8605 } 8606 8607 /// Determine the underlying locations kinds for \p Ptr, e.g., globals or 8608 /// arguments, and update the state and access map accordingly. 8609 void categorizePtrValue(Attributor &A, const Instruction &I, const Value &Ptr, 8610 AAMemoryLocation::StateType &State, bool &Changed, 8611 unsigned AccessAS = 0); 8612 8613 /// Used to allocate access sets. 8614 BumpPtrAllocator &Allocator; 8615 }; 8616 8617 void AAMemoryLocationImpl::categorizePtrValue( 8618 Attributor &A, const Instruction &I, const Value &Ptr, 8619 AAMemoryLocation::StateType &State, bool &Changed, unsigned AccessAS) { 8620 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize pointer locations for " 8621 << Ptr << " [" 8622 << getMemoryLocationsAsStr(State.getAssumed()) << "]\n"); 8623 8624 auto Pred = [&](Value &Obj) { 8625 unsigned ObjectAS = Obj.getType()->getPointerAddressSpace(); 8626 // TODO: recognize the TBAA used for constant accesses. 8627 MemoryLocationsKind MLK = NO_LOCATIONS; 8628 8629 // Filter accesses to constant (GPU) memory if we have an AS at the access 8630 // site or the object is known to actually have the associated AS. 8631 if ((AccessAS == (unsigned)AA::GPUAddressSpace::Constant || 8632 (ObjectAS == (unsigned)AA::GPUAddressSpace::Constant && 8633 isIdentifiedObject(&Obj))) && 8634 AA::isGPU(*I.getModule())) 8635 return true; 8636 8637 if (isa<UndefValue>(&Obj)) 8638 return true; 8639 if (isa<Argument>(&Obj)) { 8640 // TODO: For now we do not treat byval arguments as local copies performed 8641 // on the call edge, though, we should. To make that happen we need to 8642 // teach various passes, e.g., DSE, about the copy effect of a byval. That 8643 // would also allow us to mark functions only accessing byval arguments as 8644 // readnone again, arguably their accesses have no effect outside of the 8645 // function, like accesses to allocas. 8646 MLK = NO_ARGUMENT_MEM; 8647 } else if (auto *GV = dyn_cast<GlobalValue>(&Obj)) { 8648 // Reading constant memory is not treated as a read "effect" by the 8649 // function attr pass so we won't neither. Constants defined by TBAA are 8650 // similar. (We know we do not write it because it is constant.) 8651 if (auto *GVar = dyn_cast<GlobalVariable>(GV)) 8652 if (GVar->isConstant()) 8653 return true; 8654 8655 if (GV->hasLocalLinkage()) 8656 MLK = NO_GLOBAL_INTERNAL_MEM; 8657 else 8658 MLK = NO_GLOBAL_EXTERNAL_MEM; 8659 } else if (isa<ConstantPointerNull>(&Obj) && 8660 (!NullPointerIsDefined(getAssociatedFunction(), AccessAS) || 8661 !NullPointerIsDefined(getAssociatedFunction(), ObjectAS))) { 8662 return true; 8663 } else if (isa<AllocaInst>(&Obj)) { 8664 MLK = NO_LOCAL_MEM; 8665 } else if (const auto *CB = dyn_cast<CallBase>(&Obj)) { 8666 bool IsKnownNoAlias; 8667 if (AA::hasAssumedIRAttr<Attribute::NoAlias>( 8668 A, this, IRPosition::callsite_returned(*CB), DepClassTy::OPTIONAL, 8669 IsKnownNoAlias)) 8670 MLK = NO_MALLOCED_MEM; 8671 else 8672 MLK = NO_UNKOWN_MEM; 8673 } else { 8674 MLK = NO_UNKOWN_MEM; 8675 } 8676 8677 assert(MLK != NO_LOCATIONS && "No location specified!"); 8678 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Ptr value can be categorized: " 8679 << Obj << " -> " << getMemoryLocationsAsStr(MLK) << "\n"); 8680 updateStateAndAccessesMap(State, MLK, &I, &Obj, Changed, 8681 getAccessKindFromInst(&I)); 8682 8683 return true; 8684 }; 8685 8686 const auto *AA = A.getAAFor<AAUnderlyingObjects>( 8687 *this, IRPosition::value(Ptr), DepClassTy::OPTIONAL); 8688 if (!AA || !AA->forallUnderlyingObjects(Pred, AA::Intraprocedural)) { 8689 LLVM_DEBUG( 8690 dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n"); 8691 updateStateAndAccessesMap(State, NO_UNKOWN_MEM, &I, nullptr, Changed, 8692 getAccessKindFromInst(&I)); 8693 return; 8694 } 8695 8696 LLVM_DEBUG( 8697 dbgs() << "[AAMemoryLocation] Accessed locations with pointer locations: " 8698 << getMemoryLocationsAsStr(State.getAssumed()) << "\n"); 8699 } 8700 8701 void AAMemoryLocationImpl::categorizeArgumentPointerLocations( 8702 Attributor &A, CallBase &CB, AAMemoryLocation::StateType &AccessedLocs, 8703 bool &Changed) { 8704 for (unsigned ArgNo = 0, E = CB.arg_size(); ArgNo < E; ++ArgNo) { 8705 8706 // Skip non-pointer arguments. 8707 const Value *ArgOp = CB.getArgOperand(ArgNo); 8708 if (!ArgOp->getType()->isPtrOrPtrVectorTy()) 8709 continue; 8710 8711 // Skip readnone arguments. 8712 const IRPosition &ArgOpIRP = IRPosition::callsite_argument(CB, ArgNo); 8713 const auto *ArgOpMemLocationAA = 8714 A.getAAFor<AAMemoryBehavior>(*this, ArgOpIRP, DepClassTy::OPTIONAL); 8715 8716 if (ArgOpMemLocationAA && ArgOpMemLocationAA->isAssumedReadNone()) 8717 continue; 8718 8719 // Categorize potentially accessed pointer arguments as if there was an 8720 // access instruction with them as pointer. 8721 categorizePtrValue(A, CB, *ArgOp, AccessedLocs, Changed); 8722 } 8723 } 8724 8725 AAMemoryLocation::MemoryLocationsKind 8726 AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I, 8727 bool &Changed) { 8728 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize accessed locations for " 8729 << I << "\n"); 8730 8731 AAMemoryLocation::StateType AccessedLocs; 8732 AccessedLocs.intersectAssumedBits(NO_LOCATIONS); 8733 8734 if (auto *CB = dyn_cast<CallBase>(&I)) { 8735 8736 // First check if we assume any memory is access is visible. 8737 const auto *CBMemLocationAA = A.getAAFor<AAMemoryLocation>( 8738 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL); 8739 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I 8740 << " [" << CBMemLocationAA << "]\n"); 8741 if (!CBMemLocationAA) { 8742 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr, 8743 Changed, getAccessKindFromInst(&I)); 8744 return NO_UNKOWN_MEM; 8745 } 8746 8747 if (CBMemLocationAA->isAssumedReadNone()) 8748 return NO_LOCATIONS; 8749 8750 if (CBMemLocationAA->isAssumedInaccessibleMemOnly()) { 8751 updateStateAndAccessesMap(AccessedLocs, NO_INACCESSIBLE_MEM, &I, nullptr, 8752 Changed, getAccessKindFromInst(&I)); 8753 return AccessedLocs.getAssumed(); 8754 } 8755 8756 uint32_t CBAssumedNotAccessedLocs = 8757 CBMemLocationAA->getAssumedNotAccessedLocation(); 8758 8759 // Set the argmemonly and global bit as we handle them separately below. 8760 uint32_t CBAssumedNotAccessedLocsNoArgMem = 8761 CBAssumedNotAccessedLocs | NO_ARGUMENT_MEM | NO_GLOBAL_MEM; 8762 8763 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) { 8764 if (CBAssumedNotAccessedLocsNoArgMem & CurMLK) 8765 continue; 8766 updateStateAndAccessesMap(AccessedLocs, CurMLK, &I, nullptr, Changed, 8767 getAccessKindFromInst(&I)); 8768 } 8769 8770 // Now handle global memory if it might be accessed. This is slightly tricky 8771 // as NO_GLOBAL_MEM has multiple bits set. 8772 bool HasGlobalAccesses = ((~CBAssumedNotAccessedLocs) & NO_GLOBAL_MEM); 8773 if (HasGlobalAccesses) { 8774 auto AccessPred = [&](const Instruction *, const Value *Ptr, 8775 AccessKind Kind, MemoryLocationsKind MLK) { 8776 updateStateAndAccessesMap(AccessedLocs, MLK, &I, Ptr, Changed, 8777 getAccessKindFromInst(&I)); 8778 return true; 8779 }; 8780 if (!CBMemLocationAA->checkForAllAccessesToMemoryKind( 8781 AccessPred, inverseLocation(NO_GLOBAL_MEM, false, false))) 8782 return AccessedLocs.getWorstState(); 8783 } 8784 8785 LLVM_DEBUG( 8786 dbgs() << "[AAMemoryLocation] Accessed state before argument handling: " 8787 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n"); 8788 8789 // Now handle argument memory if it might be accessed. 8790 bool HasArgAccesses = ((~CBAssumedNotAccessedLocs) & NO_ARGUMENT_MEM); 8791 if (HasArgAccesses) 8792 categorizeArgumentPointerLocations(A, *CB, AccessedLocs, Changed); 8793 8794 LLVM_DEBUG( 8795 dbgs() << "[AAMemoryLocation] Accessed state after argument handling: " 8796 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n"); 8797 8798 return AccessedLocs.getAssumed(); 8799 } 8800 8801 if (const Value *Ptr = getPointerOperand(&I, /* AllowVolatile */ true)) { 8802 LLVM_DEBUG( 8803 dbgs() << "[AAMemoryLocation] Categorize memory access with pointer: " 8804 << I << " [" << *Ptr << "]\n"); 8805 categorizePtrValue(A, I, *Ptr, AccessedLocs, Changed, 8806 Ptr->getType()->getPointerAddressSpace()); 8807 return AccessedLocs.getAssumed(); 8808 } 8809 8810 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Failed to categorize instruction: " 8811 << I << "\n"); 8812 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr, Changed, 8813 getAccessKindFromInst(&I)); 8814 return AccessedLocs.getAssumed(); 8815 } 8816 8817 /// An AA to represent the memory behavior function attributes. 8818 struct AAMemoryLocationFunction final : public AAMemoryLocationImpl { 8819 AAMemoryLocationFunction(const IRPosition &IRP, Attributor &A) 8820 : AAMemoryLocationImpl(IRP, A) {} 8821 8822 /// See AbstractAttribute::updateImpl(Attributor &A). 8823 ChangeStatus updateImpl(Attributor &A) override { 8824 8825 const auto *MemBehaviorAA = 8826 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE); 8827 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) { 8828 if (MemBehaviorAA->isKnownReadNone()) 8829 return indicateOptimisticFixpoint(); 8830 assert(isAssumedReadNone() && 8831 "AAMemoryLocation was not read-none but AAMemoryBehavior was!"); 8832 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL); 8833 return ChangeStatus::UNCHANGED; 8834 } 8835 8836 // The current assumed state used to determine a change. 8837 auto AssumedState = getAssumed(); 8838 bool Changed = false; 8839 8840 auto CheckRWInst = [&](Instruction &I) { 8841 MemoryLocationsKind MLK = categorizeAccessedLocations(A, I, Changed); 8842 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I 8843 << ": " << getMemoryLocationsAsStr(MLK) << "\n"); 8844 removeAssumedBits(inverseLocation(MLK, false, false)); 8845 // Stop once only the valid bit set in the *not assumed location*, thus 8846 // once we don't actually exclude any memory locations in the state. 8847 return getAssumedNotAccessedLocation() != VALID_STATE; 8848 }; 8849 8850 bool UsedAssumedInformation = false; 8851 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this, 8852 UsedAssumedInformation)) 8853 return indicatePessimisticFixpoint(); 8854 8855 Changed |= AssumedState != getAssumed(); 8856 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 8857 } 8858 8859 /// See AbstractAttribute::trackStatistics() 8860 void trackStatistics() const override { 8861 if (isAssumedReadNone()) 8862 STATS_DECLTRACK_FN_ATTR(readnone) 8863 else if (isAssumedArgMemOnly()) 8864 STATS_DECLTRACK_FN_ATTR(argmemonly) 8865 else if (isAssumedInaccessibleMemOnly()) 8866 STATS_DECLTRACK_FN_ATTR(inaccessiblememonly) 8867 else if (isAssumedInaccessibleOrArgMemOnly()) 8868 STATS_DECLTRACK_FN_ATTR(inaccessiblememorargmemonly) 8869 } 8870 }; 8871 8872 /// AAMemoryLocation attribute for call sites. 8873 struct AAMemoryLocationCallSite final : AAMemoryLocationImpl { 8874 AAMemoryLocationCallSite(const IRPosition &IRP, Attributor &A) 8875 : AAMemoryLocationImpl(IRP, A) {} 8876 8877 /// See AbstractAttribute::updateImpl(...). 8878 ChangeStatus updateImpl(Attributor &A) override { 8879 // TODO: Once we have call site specific value information we can provide 8880 // call site specific liveness liveness information and then it makes 8881 // sense to specialize attributes for call sites arguments instead of 8882 // redirecting requests to the callee argument. 8883 Function *F = getAssociatedFunction(); 8884 const IRPosition &FnPos = IRPosition::function(*F); 8885 auto *FnAA = 8886 A.getAAFor<AAMemoryLocation>(*this, FnPos, DepClassTy::REQUIRED); 8887 if (!FnAA) 8888 return indicatePessimisticFixpoint(); 8889 bool Changed = false; 8890 auto AccessPred = [&](const Instruction *I, const Value *Ptr, 8891 AccessKind Kind, MemoryLocationsKind MLK) { 8892 updateStateAndAccessesMap(getState(), MLK, I, Ptr, Changed, 8893 getAccessKindFromInst(I)); 8894 return true; 8895 }; 8896 if (!FnAA->checkForAllAccessesToMemoryKind(AccessPred, ALL_LOCATIONS)) 8897 return indicatePessimisticFixpoint(); 8898 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 8899 } 8900 8901 /// See AbstractAttribute::trackStatistics() 8902 void trackStatistics() const override { 8903 if (isAssumedReadNone()) 8904 STATS_DECLTRACK_CS_ATTR(readnone) 8905 } 8906 }; 8907 } // namespace 8908 8909 /// ------------------ denormal-fp-math Attribute ------------------------- 8910 8911 namespace { 8912 struct AADenormalFPMathImpl : public AADenormalFPMath { 8913 AADenormalFPMathImpl(const IRPosition &IRP, Attributor &A) 8914 : AADenormalFPMath(IRP, A) {} 8915 8916 const std::string getAsStr(Attributor *A) const override { 8917 std::string Str("AADenormalFPMath["); 8918 raw_string_ostream OS(Str); 8919 8920 DenormalState Known = getKnown(); 8921 if (Known.Mode.isValid()) 8922 OS << "denormal-fp-math=" << Known.Mode; 8923 else 8924 OS << "invalid"; 8925 8926 if (Known.ModeF32.isValid()) 8927 OS << " denormal-fp-math-f32=" << Known.ModeF32; 8928 OS << ']'; 8929 return Str; 8930 } 8931 }; 8932 8933 struct AADenormalFPMathFunction final : AADenormalFPMathImpl { 8934 AADenormalFPMathFunction(const IRPosition &IRP, Attributor &A) 8935 : AADenormalFPMathImpl(IRP, A) {} 8936 8937 void initialize(Attributor &A) override { 8938 const Function *F = getAnchorScope(); 8939 DenormalMode Mode = F->getDenormalModeRaw(); 8940 DenormalMode ModeF32 = F->getDenormalModeF32Raw(); 8941 8942 // TODO: Handling this here prevents handling the case where a callee has a 8943 // fixed denormal-fp-math with dynamic denormal-fp-math-f32, but called from 8944 // a function with a fully fixed mode. 8945 if (ModeF32 == DenormalMode::getInvalid()) 8946 ModeF32 = Mode; 8947 Known = DenormalState{Mode, ModeF32}; 8948 if (isModeFixed()) 8949 indicateFixpoint(); 8950 } 8951 8952 ChangeStatus updateImpl(Attributor &A) override { 8953 ChangeStatus Change = ChangeStatus::UNCHANGED; 8954 8955 auto CheckCallSite = [=, &Change, &A](AbstractCallSite CS) { 8956 Function *Caller = CS.getInstruction()->getFunction(); 8957 LLVM_DEBUG(dbgs() << "[AADenormalFPMath] Call " << Caller->getName() 8958 << "->" << getAssociatedFunction()->getName() << '\n'); 8959 8960 const auto *CallerInfo = A.getAAFor<AADenormalFPMath>( 8961 *this, IRPosition::function(*Caller), DepClassTy::REQUIRED); 8962 if (!CallerInfo) 8963 return false; 8964 8965 Change = Change | clampStateAndIndicateChange(this->getState(), 8966 CallerInfo->getState()); 8967 return true; 8968 }; 8969 8970 bool AllCallSitesKnown = true; 8971 if (!A.checkForAllCallSites(CheckCallSite, *this, true, AllCallSitesKnown)) 8972 return indicatePessimisticFixpoint(); 8973 8974 if (Change == ChangeStatus::CHANGED && isModeFixed()) 8975 indicateFixpoint(); 8976 return Change; 8977 } 8978 8979 ChangeStatus manifest(Attributor &A) override { 8980 LLVMContext &Ctx = getAssociatedFunction()->getContext(); 8981 8982 SmallVector<Attribute, 2> AttrToAdd; 8983 SmallVector<StringRef, 2> AttrToRemove; 8984 if (Known.Mode == DenormalMode::getDefault()) { 8985 AttrToRemove.push_back("denormal-fp-math"); 8986 } else { 8987 AttrToAdd.push_back( 8988 Attribute::get(Ctx, "denormal-fp-math", Known.Mode.str())); 8989 } 8990 8991 if (Known.ModeF32 != Known.Mode) { 8992 AttrToAdd.push_back( 8993 Attribute::get(Ctx, "denormal-fp-math-f32", Known.ModeF32.str())); 8994 } else { 8995 AttrToRemove.push_back("denormal-fp-math-f32"); 8996 } 8997 8998 auto &IRP = getIRPosition(); 8999 9000 // TODO: There should be a combined add and remove API. 9001 return A.removeAttrs(IRP, AttrToRemove) | 9002 A.manifestAttrs(IRP, AttrToAdd, /*ForceReplace=*/true); 9003 } 9004 9005 void trackStatistics() const override { 9006 STATS_DECLTRACK_FN_ATTR(denormal_fp_math) 9007 } 9008 }; 9009 } // namespace 9010 9011 /// ------------------ Value Constant Range Attribute ------------------------- 9012 9013 namespace { 9014 struct AAValueConstantRangeImpl : AAValueConstantRange { 9015 using StateType = IntegerRangeState; 9016 AAValueConstantRangeImpl(const IRPosition &IRP, Attributor &A) 9017 : AAValueConstantRange(IRP, A) {} 9018 9019 /// See AbstractAttribute::initialize(..). 9020 void initialize(Attributor &A) override { 9021 if (A.hasSimplificationCallback(getIRPosition())) { 9022 indicatePessimisticFixpoint(); 9023 return; 9024 } 9025 9026 // Intersect a range given by SCEV. 9027 intersectKnown(getConstantRangeFromSCEV(A, getCtxI())); 9028 9029 // Intersect a range given by LVI. 9030 intersectKnown(getConstantRangeFromLVI(A, getCtxI())); 9031 } 9032 9033 /// See AbstractAttribute::getAsStr(). 9034 const std::string getAsStr(Attributor *A) const override { 9035 std::string Str; 9036 llvm::raw_string_ostream OS(Str); 9037 OS << "range(" << getBitWidth() << ")<"; 9038 getKnown().print(OS); 9039 OS << " / "; 9040 getAssumed().print(OS); 9041 OS << ">"; 9042 return Str; 9043 } 9044 9045 /// Helper function to get a SCEV expr for the associated value at program 9046 /// point \p I. 9047 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const { 9048 if (!getAnchorScope()) 9049 return nullptr; 9050 9051 ScalarEvolution *SE = 9052 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>( 9053 *getAnchorScope()); 9054 9055 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>( 9056 *getAnchorScope()); 9057 9058 if (!SE || !LI) 9059 return nullptr; 9060 9061 const SCEV *S = SE->getSCEV(&getAssociatedValue()); 9062 if (!I) 9063 return S; 9064 9065 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent())); 9066 } 9067 9068 /// Helper function to get a range from SCEV for the associated value at 9069 /// program point \p I. 9070 ConstantRange getConstantRangeFromSCEV(Attributor &A, 9071 const Instruction *I = nullptr) const { 9072 if (!getAnchorScope()) 9073 return getWorstState(getBitWidth()); 9074 9075 ScalarEvolution *SE = 9076 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>( 9077 *getAnchorScope()); 9078 9079 const SCEV *S = getSCEV(A, I); 9080 if (!SE || !S) 9081 return getWorstState(getBitWidth()); 9082 9083 return SE->getUnsignedRange(S); 9084 } 9085 9086 /// Helper function to get a range from LVI for the associated value at 9087 /// program point \p I. 9088 ConstantRange 9089 getConstantRangeFromLVI(Attributor &A, 9090 const Instruction *CtxI = nullptr) const { 9091 if (!getAnchorScope()) 9092 return getWorstState(getBitWidth()); 9093 9094 LazyValueInfo *LVI = 9095 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>( 9096 *getAnchorScope()); 9097 9098 if (!LVI || !CtxI) 9099 return getWorstState(getBitWidth()); 9100 return LVI->getConstantRange(&getAssociatedValue(), 9101 const_cast<Instruction *>(CtxI), 9102 /*UndefAllowed*/ false); 9103 } 9104 9105 /// Return true if \p CtxI is valid for querying outside analyses. 9106 /// This basically makes sure we do not ask intra-procedural analysis 9107 /// about a context in the wrong function or a context that violates 9108 /// dominance assumptions they might have. The \p AllowAACtxI flag indicates 9109 /// if the original context of this AA is OK or should be considered invalid. 9110 bool isValidCtxInstructionForOutsideAnalysis(Attributor &A, 9111 const Instruction *CtxI, 9112 bool AllowAACtxI) const { 9113 if (!CtxI || (!AllowAACtxI && CtxI == getCtxI())) 9114 return false; 9115 9116 // Our context might be in a different function, neither intra-procedural 9117 // analysis (ScalarEvolution nor LazyValueInfo) can handle that. 9118 if (!AA::isValidInScope(getAssociatedValue(), CtxI->getFunction())) 9119 return false; 9120 9121 // If the context is not dominated by the value there are paths to the 9122 // context that do not define the value. This cannot be handled by 9123 // LazyValueInfo so we need to bail. 9124 if (auto *I = dyn_cast<Instruction>(&getAssociatedValue())) { 9125 InformationCache &InfoCache = A.getInfoCache(); 9126 const DominatorTree *DT = 9127 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>( 9128 *I->getFunction()); 9129 return DT && DT->dominates(I, CtxI); 9130 } 9131 9132 return true; 9133 } 9134 9135 /// See AAValueConstantRange::getKnownConstantRange(..). 9136 ConstantRange 9137 getKnownConstantRange(Attributor &A, 9138 const Instruction *CtxI = nullptr) const override { 9139 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI, 9140 /* AllowAACtxI */ false)) 9141 return getKnown(); 9142 9143 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI); 9144 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI); 9145 return getKnown().intersectWith(SCEVR).intersectWith(LVIR); 9146 } 9147 9148 /// See AAValueConstantRange::getAssumedConstantRange(..). 9149 ConstantRange 9150 getAssumedConstantRange(Attributor &A, 9151 const Instruction *CtxI = nullptr) const override { 9152 // TODO: Make SCEV use Attributor assumption. 9153 // We may be able to bound a variable range via assumptions in 9154 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to 9155 // evolve to x^2 + x, then we can say that y is in [2, 12]. 9156 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI, 9157 /* AllowAACtxI */ false)) 9158 return getAssumed(); 9159 9160 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI); 9161 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI); 9162 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR); 9163 } 9164 9165 /// Helper function to create MDNode for range metadata. 9166 static MDNode * 9167 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx, 9168 const ConstantRange &AssumedConstantRange) { 9169 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get( 9170 Ty, AssumedConstantRange.getLower())), 9171 ConstantAsMetadata::get(ConstantInt::get( 9172 Ty, AssumedConstantRange.getUpper()))}; 9173 return MDNode::get(Ctx, LowAndHigh); 9174 } 9175 9176 /// Return true if \p Assumed is included in ranges from instruction \p I. 9177 static bool isBetterRange(const ConstantRange &Assumed, 9178 const Instruction &I) { 9179 if (Assumed.isFullSet()) 9180 return false; 9181 9182 std::optional<ConstantRange> Known; 9183 9184 if (const auto *CB = dyn_cast<CallBase>(&I)) { 9185 Known = CB->getRange(); 9186 } else if (MDNode *KnownRanges = I.getMetadata(LLVMContext::MD_range)) { 9187 // If multiple ranges are annotated in IR, we give up to annotate assumed 9188 // range for now. 9189 9190 // TODO: If there exists a known range which containts assumed range, we 9191 // can say assumed range is better. 9192 if (KnownRanges->getNumOperands() > 2) 9193 return false; 9194 9195 ConstantInt *Lower = 9196 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0)); 9197 ConstantInt *Upper = 9198 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1)); 9199 9200 Known.emplace(Lower->getValue(), Upper->getValue()); 9201 } 9202 return !Known || (*Known != Assumed && Known->contains(Assumed)); 9203 } 9204 9205 /// Helper function to set range metadata. 9206 static bool 9207 setRangeMetadataIfisBetterRange(Instruction *I, 9208 const ConstantRange &AssumedConstantRange) { 9209 if (isBetterRange(AssumedConstantRange, *I)) { 9210 I->setMetadata(LLVMContext::MD_range, 9211 getMDNodeForConstantRange(I->getType(), I->getContext(), 9212 AssumedConstantRange)); 9213 return true; 9214 } 9215 return false; 9216 } 9217 /// Helper function to set range return attribute. 9218 static bool 9219 setRangeRetAttrIfisBetterRange(Attributor &A, const IRPosition &IRP, 9220 Instruction *I, 9221 const ConstantRange &AssumedConstantRange) { 9222 if (isBetterRange(AssumedConstantRange, *I)) { 9223 A.manifestAttrs(IRP, 9224 Attribute::get(I->getContext(), Attribute::Range, 9225 AssumedConstantRange), 9226 /*ForceReplace*/ true); 9227 return true; 9228 } 9229 return false; 9230 } 9231 9232 /// See AbstractAttribute::manifest() 9233 ChangeStatus manifest(Attributor &A) override { 9234 ChangeStatus Changed = ChangeStatus::UNCHANGED; 9235 ConstantRange AssumedConstantRange = getAssumedConstantRange(A); 9236 assert(!AssumedConstantRange.isFullSet() && "Invalid state"); 9237 9238 auto &V = getAssociatedValue(); 9239 if (!AssumedConstantRange.isEmptySet() && 9240 !AssumedConstantRange.isSingleElement()) { 9241 if (Instruction *I = dyn_cast<Instruction>(&V)) { 9242 assert(I == getCtxI() && "Should not annotate an instruction which is " 9243 "not the context instruction"); 9244 if (isa<LoadInst>(I)) 9245 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange)) 9246 Changed = ChangeStatus::CHANGED; 9247 if (isa<CallInst>(I)) 9248 if (setRangeRetAttrIfisBetterRange(A, getIRPosition(), I, 9249 AssumedConstantRange)) 9250 Changed = ChangeStatus::CHANGED; 9251 } 9252 } 9253 9254 return Changed; 9255 } 9256 }; 9257 9258 struct AAValueConstantRangeArgument final 9259 : AAArgumentFromCallSiteArguments< 9260 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState, 9261 true /* BridgeCallBaseContext */> { 9262 using Base = AAArgumentFromCallSiteArguments< 9263 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState, 9264 true /* BridgeCallBaseContext */>; 9265 AAValueConstantRangeArgument(const IRPosition &IRP, Attributor &A) 9266 : Base(IRP, A) {} 9267 9268 /// See AbstractAttribute::trackStatistics() 9269 void trackStatistics() const override { 9270 STATS_DECLTRACK_ARG_ATTR(value_range) 9271 } 9272 }; 9273 9274 struct AAValueConstantRangeReturned 9275 : AAReturnedFromReturnedValues<AAValueConstantRange, 9276 AAValueConstantRangeImpl, 9277 AAValueConstantRangeImpl::StateType, 9278 /* PropagateCallBaseContext */ true> { 9279 using Base = 9280 AAReturnedFromReturnedValues<AAValueConstantRange, 9281 AAValueConstantRangeImpl, 9282 AAValueConstantRangeImpl::StateType, 9283 /* PropagateCallBaseContext */ true>; 9284 AAValueConstantRangeReturned(const IRPosition &IRP, Attributor &A) 9285 : Base(IRP, A) {} 9286 9287 /// See AbstractAttribute::initialize(...). 9288 void initialize(Attributor &A) override { 9289 if (!A.isFunctionIPOAmendable(*getAssociatedFunction())) 9290 indicatePessimisticFixpoint(); 9291 } 9292 9293 /// See AbstractAttribute::trackStatistics() 9294 void trackStatistics() const override { 9295 STATS_DECLTRACK_FNRET_ATTR(value_range) 9296 } 9297 }; 9298 9299 struct AAValueConstantRangeFloating : AAValueConstantRangeImpl { 9300 AAValueConstantRangeFloating(const IRPosition &IRP, Attributor &A) 9301 : AAValueConstantRangeImpl(IRP, A) {} 9302 9303 /// See AbstractAttribute::initialize(...). 9304 void initialize(Attributor &A) override { 9305 AAValueConstantRangeImpl::initialize(A); 9306 if (isAtFixpoint()) 9307 return; 9308 9309 Value &V = getAssociatedValue(); 9310 9311 if (auto *C = dyn_cast<ConstantInt>(&V)) { 9312 unionAssumed(ConstantRange(C->getValue())); 9313 indicateOptimisticFixpoint(); 9314 return; 9315 } 9316 9317 if (isa<UndefValue>(&V)) { 9318 // Collapse the undef state to 0. 9319 unionAssumed(ConstantRange(APInt(getBitWidth(), 0))); 9320 indicateOptimisticFixpoint(); 9321 return; 9322 } 9323 9324 if (isa<CallBase>(&V)) 9325 return; 9326 9327 if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V)) 9328 return; 9329 9330 // If it is a load instruction with range metadata, use it. 9331 if (LoadInst *LI = dyn_cast<LoadInst>(&V)) 9332 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) { 9333 intersectKnown(getConstantRangeFromMetadata(*RangeMD)); 9334 return; 9335 } 9336 9337 // We can work with PHI and select instruction as we traverse their operands 9338 // during update. 9339 if (isa<SelectInst>(V) || isa<PHINode>(V)) 9340 return; 9341 9342 // Otherwise we give up. 9343 indicatePessimisticFixpoint(); 9344 9345 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: " 9346 << getAssociatedValue() << "\n"); 9347 } 9348 9349 bool calculateBinaryOperator( 9350 Attributor &A, BinaryOperator *BinOp, IntegerRangeState &T, 9351 const Instruction *CtxI, 9352 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) { 9353 Value *LHS = BinOp->getOperand(0); 9354 Value *RHS = BinOp->getOperand(1); 9355 9356 // Simplify the operands first. 9357 bool UsedAssumedInformation = false; 9358 const auto &SimplifiedLHS = A.getAssumedSimplified( 9359 IRPosition::value(*LHS, getCallBaseContext()), *this, 9360 UsedAssumedInformation, AA::Interprocedural); 9361 if (!SimplifiedLHS.has_value()) 9362 return true; 9363 if (!*SimplifiedLHS) 9364 return false; 9365 LHS = *SimplifiedLHS; 9366 9367 const auto &SimplifiedRHS = A.getAssumedSimplified( 9368 IRPosition::value(*RHS, getCallBaseContext()), *this, 9369 UsedAssumedInformation, AA::Interprocedural); 9370 if (!SimplifiedRHS.has_value()) 9371 return true; 9372 if (!*SimplifiedRHS) 9373 return false; 9374 RHS = *SimplifiedRHS; 9375 9376 // TODO: Allow non integers as well. 9377 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy()) 9378 return false; 9379 9380 auto *LHSAA = A.getAAFor<AAValueConstantRange>( 9381 *this, IRPosition::value(*LHS, getCallBaseContext()), 9382 DepClassTy::REQUIRED); 9383 if (!LHSAA) 9384 return false; 9385 QuerriedAAs.push_back(LHSAA); 9386 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI); 9387 9388 auto *RHSAA = A.getAAFor<AAValueConstantRange>( 9389 *this, IRPosition::value(*RHS, getCallBaseContext()), 9390 DepClassTy::REQUIRED); 9391 if (!RHSAA) 9392 return false; 9393 QuerriedAAs.push_back(RHSAA); 9394 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI); 9395 9396 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange); 9397 9398 T.unionAssumed(AssumedRange); 9399 9400 // TODO: Track a known state too. 9401 9402 return T.isValidState(); 9403 } 9404 9405 bool calculateCastInst( 9406 Attributor &A, CastInst *CastI, IntegerRangeState &T, 9407 const Instruction *CtxI, 9408 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) { 9409 assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!"); 9410 // TODO: Allow non integers as well. 9411 Value *OpV = CastI->getOperand(0); 9412 9413 // Simplify the operand first. 9414 bool UsedAssumedInformation = false; 9415 const auto &SimplifiedOpV = A.getAssumedSimplified( 9416 IRPosition::value(*OpV, getCallBaseContext()), *this, 9417 UsedAssumedInformation, AA::Interprocedural); 9418 if (!SimplifiedOpV.has_value()) 9419 return true; 9420 if (!*SimplifiedOpV) 9421 return false; 9422 OpV = *SimplifiedOpV; 9423 9424 if (!OpV->getType()->isIntegerTy()) 9425 return false; 9426 9427 auto *OpAA = A.getAAFor<AAValueConstantRange>( 9428 *this, IRPosition::value(*OpV, getCallBaseContext()), 9429 DepClassTy::REQUIRED); 9430 if (!OpAA) 9431 return false; 9432 QuerriedAAs.push_back(OpAA); 9433 T.unionAssumed(OpAA->getAssumed().castOp(CastI->getOpcode(), 9434 getState().getBitWidth())); 9435 return T.isValidState(); 9436 } 9437 9438 bool 9439 calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T, 9440 const Instruction *CtxI, 9441 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) { 9442 Value *LHS = CmpI->getOperand(0); 9443 Value *RHS = CmpI->getOperand(1); 9444 9445 // Simplify the operands first. 9446 bool UsedAssumedInformation = false; 9447 const auto &SimplifiedLHS = A.getAssumedSimplified( 9448 IRPosition::value(*LHS, getCallBaseContext()), *this, 9449 UsedAssumedInformation, AA::Interprocedural); 9450 if (!SimplifiedLHS.has_value()) 9451 return true; 9452 if (!*SimplifiedLHS) 9453 return false; 9454 LHS = *SimplifiedLHS; 9455 9456 const auto &SimplifiedRHS = A.getAssumedSimplified( 9457 IRPosition::value(*RHS, getCallBaseContext()), *this, 9458 UsedAssumedInformation, AA::Interprocedural); 9459 if (!SimplifiedRHS.has_value()) 9460 return true; 9461 if (!*SimplifiedRHS) 9462 return false; 9463 RHS = *SimplifiedRHS; 9464 9465 // TODO: Allow non integers as well. 9466 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy()) 9467 return false; 9468 9469 auto *LHSAA = A.getAAFor<AAValueConstantRange>( 9470 *this, IRPosition::value(*LHS, getCallBaseContext()), 9471 DepClassTy::REQUIRED); 9472 if (!LHSAA) 9473 return false; 9474 QuerriedAAs.push_back(LHSAA); 9475 auto *RHSAA = A.getAAFor<AAValueConstantRange>( 9476 *this, IRPosition::value(*RHS, getCallBaseContext()), 9477 DepClassTy::REQUIRED); 9478 if (!RHSAA) 9479 return false; 9480 QuerriedAAs.push_back(RHSAA); 9481 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI); 9482 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI); 9483 9484 // If one of them is empty set, we can't decide. 9485 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet()) 9486 return true; 9487 9488 bool MustTrue = false, MustFalse = false; 9489 9490 auto AllowedRegion = 9491 ConstantRange::makeAllowedICmpRegion(CmpI->getPredicate(), RHSAARange); 9492 9493 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet()) 9494 MustFalse = true; 9495 9496 if (LHSAARange.icmp(CmpI->getPredicate(), RHSAARange)) 9497 MustTrue = true; 9498 9499 assert((!MustTrue || !MustFalse) && 9500 "Either MustTrue or MustFalse should be false!"); 9501 9502 if (MustTrue) 9503 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1))); 9504 else if (MustFalse) 9505 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0))); 9506 else 9507 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true)); 9508 9509 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " after " 9510 << (MustTrue ? "true" : (MustFalse ? "false" : "unknown")) 9511 << ": " << T << "\n\t" << *LHSAA << "\t<op>\n\t" 9512 << *RHSAA); 9513 9514 // TODO: Track a known state too. 9515 return T.isValidState(); 9516 } 9517 9518 /// See AbstractAttribute::updateImpl(...). 9519 ChangeStatus updateImpl(Attributor &A) override { 9520 9521 IntegerRangeState T(getBitWidth()); 9522 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool { 9523 Instruction *I = dyn_cast<Instruction>(&V); 9524 if (!I || isa<CallBase>(I)) { 9525 9526 // Simplify the operand first. 9527 bool UsedAssumedInformation = false; 9528 const auto &SimplifiedOpV = A.getAssumedSimplified( 9529 IRPosition::value(V, getCallBaseContext()), *this, 9530 UsedAssumedInformation, AA::Interprocedural); 9531 if (!SimplifiedOpV.has_value()) 9532 return true; 9533 if (!*SimplifiedOpV) 9534 return false; 9535 Value *VPtr = *SimplifiedOpV; 9536 9537 // If the value is not instruction, we query AA to Attributor. 9538 const auto *AA = A.getAAFor<AAValueConstantRange>( 9539 *this, IRPosition::value(*VPtr, getCallBaseContext()), 9540 DepClassTy::REQUIRED); 9541 9542 // Clamp operator is not used to utilize a program point CtxI. 9543 if (AA) 9544 T.unionAssumed(AA->getAssumedConstantRange(A, CtxI)); 9545 else 9546 return false; 9547 9548 return T.isValidState(); 9549 } 9550 9551 SmallVector<const AAValueConstantRange *, 4> QuerriedAAs; 9552 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) { 9553 if (!calculateBinaryOperator(A, BinOp, T, CtxI, QuerriedAAs)) 9554 return false; 9555 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) { 9556 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs)) 9557 return false; 9558 } else if (auto *CastI = dyn_cast<CastInst>(I)) { 9559 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs)) 9560 return false; 9561 } else { 9562 // Give up with other instructions. 9563 // TODO: Add other instructions 9564 9565 T.indicatePessimisticFixpoint(); 9566 return false; 9567 } 9568 9569 // Catch circular reasoning in a pessimistic way for now. 9570 // TODO: Check how the range evolves and if we stripped anything, see also 9571 // AADereferenceable or AAAlign for similar situations. 9572 for (const AAValueConstantRange *QueriedAA : QuerriedAAs) { 9573 if (QueriedAA != this) 9574 continue; 9575 // If we are in a stady state we do not need to worry. 9576 if (T.getAssumed() == getState().getAssumed()) 9577 continue; 9578 T.indicatePessimisticFixpoint(); 9579 } 9580 9581 return T.isValidState(); 9582 }; 9583 9584 if (!VisitValueCB(getAssociatedValue(), getCtxI())) 9585 return indicatePessimisticFixpoint(); 9586 9587 // Ensure that long def-use chains can't cause circular reasoning either by 9588 // introducing a cutoff below. 9589 if (clampStateAndIndicateChange(getState(), T) == ChangeStatus::UNCHANGED) 9590 return ChangeStatus::UNCHANGED; 9591 if (++NumChanges > MaxNumChanges) { 9592 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] performed " << NumChanges 9593 << " but only " << MaxNumChanges 9594 << " are allowed to avoid cyclic reasoning."); 9595 return indicatePessimisticFixpoint(); 9596 } 9597 return ChangeStatus::CHANGED; 9598 } 9599 9600 /// See AbstractAttribute::trackStatistics() 9601 void trackStatistics() const override { 9602 STATS_DECLTRACK_FLOATING_ATTR(value_range) 9603 } 9604 9605 /// Tracker to bail after too many widening steps of the constant range. 9606 int NumChanges = 0; 9607 9608 /// Upper bound for the number of allowed changes (=widening steps) for the 9609 /// constant range before we give up. 9610 static constexpr int MaxNumChanges = 5; 9611 }; 9612 9613 struct AAValueConstantRangeFunction : AAValueConstantRangeImpl { 9614 AAValueConstantRangeFunction(const IRPosition &IRP, Attributor &A) 9615 : AAValueConstantRangeImpl(IRP, A) {} 9616 9617 /// See AbstractAttribute::initialize(...). 9618 ChangeStatus updateImpl(Attributor &A) override { 9619 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will " 9620 "not be called"); 9621 } 9622 9623 /// See AbstractAttribute::trackStatistics() 9624 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) } 9625 }; 9626 9627 struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction { 9628 AAValueConstantRangeCallSite(const IRPosition &IRP, Attributor &A) 9629 : AAValueConstantRangeFunction(IRP, A) {} 9630 9631 /// See AbstractAttribute::trackStatistics() 9632 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) } 9633 }; 9634 9635 struct AAValueConstantRangeCallSiteReturned 9636 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl, 9637 AAValueConstantRangeImpl::StateType, 9638 /* IntroduceCallBaseContext */ true> { 9639 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP, Attributor &A) 9640 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl, 9641 AAValueConstantRangeImpl::StateType, 9642 /* IntroduceCallBaseContext */ true>(IRP, A) {} 9643 9644 /// See AbstractAttribute::initialize(...). 9645 void initialize(Attributor &A) override { 9646 // If it is a call instruction with range attribute, use the range. 9647 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue())) { 9648 if (std::optional<ConstantRange> Range = CI->getRange()) 9649 intersectKnown(*Range); 9650 } 9651 9652 AAValueConstantRangeImpl::initialize(A); 9653 } 9654 9655 /// See AbstractAttribute::trackStatistics() 9656 void trackStatistics() const override { 9657 STATS_DECLTRACK_CSRET_ATTR(value_range) 9658 } 9659 }; 9660 struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating { 9661 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP, Attributor &A) 9662 : AAValueConstantRangeFloating(IRP, A) {} 9663 9664 /// See AbstractAttribute::manifest() 9665 ChangeStatus manifest(Attributor &A) override { 9666 return ChangeStatus::UNCHANGED; 9667 } 9668 9669 /// See AbstractAttribute::trackStatistics() 9670 void trackStatistics() const override { 9671 STATS_DECLTRACK_CSARG_ATTR(value_range) 9672 } 9673 }; 9674 } // namespace 9675 9676 /// ------------------ Potential Values Attribute ------------------------- 9677 9678 namespace { 9679 struct AAPotentialConstantValuesImpl : AAPotentialConstantValues { 9680 using StateType = PotentialConstantIntValuesState; 9681 9682 AAPotentialConstantValuesImpl(const IRPosition &IRP, Attributor &A) 9683 : AAPotentialConstantValues(IRP, A) {} 9684 9685 /// See AbstractAttribute::initialize(..). 9686 void initialize(Attributor &A) override { 9687 if (A.hasSimplificationCallback(getIRPosition())) 9688 indicatePessimisticFixpoint(); 9689 else 9690 AAPotentialConstantValues::initialize(A); 9691 } 9692 9693 bool fillSetWithConstantValues(Attributor &A, const IRPosition &IRP, SetTy &S, 9694 bool &ContainsUndef, bool ForSelf) { 9695 SmallVector<AA::ValueAndContext> Values; 9696 bool UsedAssumedInformation = false; 9697 if (!A.getAssumedSimplifiedValues(IRP, *this, Values, AA::Interprocedural, 9698 UsedAssumedInformation)) { 9699 // Avoid recursion when the caller is computing constant values for this 9700 // IRP itself. 9701 if (ForSelf) 9702 return false; 9703 if (!IRP.getAssociatedType()->isIntegerTy()) 9704 return false; 9705 auto *PotentialValuesAA = A.getAAFor<AAPotentialConstantValues>( 9706 *this, IRP, DepClassTy::REQUIRED); 9707 if (!PotentialValuesAA || !PotentialValuesAA->getState().isValidState()) 9708 return false; 9709 ContainsUndef = PotentialValuesAA->getState().undefIsContained(); 9710 S = PotentialValuesAA->getState().getAssumedSet(); 9711 return true; 9712 } 9713 9714 // Copy all the constant values, except UndefValue. ContainsUndef is true 9715 // iff Values contains only UndefValue instances. If there are other known 9716 // constants, then UndefValue is dropped. 9717 ContainsUndef = false; 9718 for (auto &It : Values) { 9719 if (isa<UndefValue>(It.getValue())) { 9720 ContainsUndef = true; 9721 continue; 9722 } 9723 auto *CI = dyn_cast<ConstantInt>(It.getValue()); 9724 if (!CI) 9725 return false; 9726 S.insert(CI->getValue()); 9727 } 9728 ContainsUndef &= S.empty(); 9729 9730 return true; 9731 } 9732 9733 /// See AbstractAttribute::getAsStr(). 9734 const std::string getAsStr(Attributor *A) const override { 9735 std::string Str; 9736 llvm::raw_string_ostream OS(Str); 9737 OS << getState(); 9738 return Str; 9739 } 9740 9741 /// See AbstractAttribute::updateImpl(...). 9742 ChangeStatus updateImpl(Attributor &A) override { 9743 return indicatePessimisticFixpoint(); 9744 } 9745 }; 9746 9747 struct AAPotentialConstantValuesArgument final 9748 : AAArgumentFromCallSiteArguments<AAPotentialConstantValues, 9749 AAPotentialConstantValuesImpl, 9750 PotentialConstantIntValuesState> { 9751 using Base = AAArgumentFromCallSiteArguments<AAPotentialConstantValues, 9752 AAPotentialConstantValuesImpl, 9753 PotentialConstantIntValuesState>; 9754 AAPotentialConstantValuesArgument(const IRPosition &IRP, Attributor &A) 9755 : Base(IRP, A) {} 9756 9757 /// See AbstractAttribute::trackStatistics() 9758 void trackStatistics() const override { 9759 STATS_DECLTRACK_ARG_ATTR(potential_values) 9760 } 9761 }; 9762 9763 struct AAPotentialConstantValuesReturned 9764 : AAReturnedFromReturnedValues<AAPotentialConstantValues, 9765 AAPotentialConstantValuesImpl> { 9766 using Base = AAReturnedFromReturnedValues<AAPotentialConstantValues, 9767 AAPotentialConstantValuesImpl>; 9768 AAPotentialConstantValuesReturned(const IRPosition &IRP, Attributor &A) 9769 : Base(IRP, A) {} 9770 9771 void initialize(Attributor &A) override { 9772 if (!A.isFunctionIPOAmendable(*getAssociatedFunction())) 9773 indicatePessimisticFixpoint(); 9774 Base::initialize(A); 9775 } 9776 9777 /// See AbstractAttribute::trackStatistics() 9778 void trackStatistics() const override { 9779 STATS_DECLTRACK_FNRET_ATTR(potential_values) 9780 } 9781 }; 9782 9783 struct AAPotentialConstantValuesFloating : AAPotentialConstantValuesImpl { 9784 AAPotentialConstantValuesFloating(const IRPosition &IRP, Attributor &A) 9785 : AAPotentialConstantValuesImpl(IRP, A) {} 9786 9787 /// See AbstractAttribute::initialize(..). 9788 void initialize(Attributor &A) override { 9789 AAPotentialConstantValuesImpl::initialize(A); 9790 if (isAtFixpoint()) 9791 return; 9792 9793 Value &V = getAssociatedValue(); 9794 9795 if (auto *C = dyn_cast<ConstantInt>(&V)) { 9796 unionAssumed(C->getValue()); 9797 indicateOptimisticFixpoint(); 9798 return; 9799 } 9800 9801 if (isa<UndefValue>(&V)) { 9802 unionAssumedWithUndef(); 9803 indicateOptimisticFixpoint(); 9804 return; 9805 } 9806 9807 if (isa<BinaryOperator>(&V) || isa<ICmpInst>(&V) || isa<CastInst>(&V)) 9808 return; 9809 9810 if (isa<SelectInst>(V) || isa<PHINode>(V) || isa<LoadInst>(V)) 9811 return; 9812 9813 indicatePessimisticFixpoint(); 9814 9815 LLVM_DEBUG(dbgs() << "[AAPotentialConstantValues] We give up: " 9816 << getAssociatedValue() << "\n"); 9817 } 9818 9819 static bool calculateICmpInst(const ICmpInst *ICI, const APInt &LHS, 9820 const APInt &RHS) { 9821 return ICmpInst::compare(LHS, RHS, ICI->getPredicate()); 9822 } 9823 9824 static APInt calculateCastInst(const CastInst *CI, const APInt &Src, 9825 uint32_t ResultBitWidth) { 9826 Instruction::CastOps CastOp = CI->getOpcode(); 9827 switch (CastOp) { 9828 default: 9829 llvm_unreachable("unsupported or not integer cast"); 9830 case Instruction::Trunc: 9831 return Src.trunc(ResultBitWidth); 9832 case Instruction::SExt: 9833 return Src.sext(ResultBitWidth); 9834 case Instruction::ZExt: 9835 return Src.zext(ResultBitWidth); 9836 case Instruction::BitCast: 9837 return Src; 9838 } 9839 } 9840 9841 static APInt calculateBinaryOperator(const BinaryOperator *BinOp, 9842 const APInt &LHS, const APInt &RHS, 9843 bool &SkipOperation, bool &Unsupported) { 9844 Instruction::BinaryOps BinOpcode = BinOp->getOpcode(); 9845 // Unsupported is set to true when the binary operator is not supported. 9846 // SkipOperation is set to true when UB occur with the given operand pair 9847 // (LHS, RHS). 9848 // TODO: we should look at nsw and nuw keywords to handle operations 9849 // that create poison or undef value. 9850 switch (BinOpcode) { 9851 default: 9852 Unsupported = true; 9853 return LHS; 9854 case Instruction::Add: 9855 return LHS + RHS; 9856 case Instruction::Sub: 9857 return LHS - RHS; 9858 case Instruction::Mul: 9859 return LHS * RHS; 9860 case Instruction::UDiv: 9861 if (RHS.isZero()) { 9862 SkipOperation = true; 9863 return LHS; 9864 } 9865 return LHS.udiv(RHS); 9866 case Instruction::SDiv: 9867 if (RHS.isZero()) { 9868 SkipOperation = true; 9869 return LHS; 9870 } 9871 return LHS.sdiv(RHS); 9872 case Instruction::URem: 9873 if (RHS.isZero()) { 9874 SkipOperation = true; 9875 return LHS; 9876 } 9877 return LHS.urem(RHS); 9878 case Instruction::SRem: 9879 if (RHS.isZero()) { 9880 SkipOperation = true; 9881 return LHS; 9882 } 9883 return LHS.srem(RHS); 9884 case Instruction::Shl: 9885 return LHS.shl(RHS); 9886 case Instruction::LShr: 9887 return LHS.lshr(RHS); 9888 case Instruction::AShr: 9889 return LHS.ashr(RHS); 9890 case Instruction::And: 9891 return LHS & RHS; 9892 case Instruction::Or: 9893 return LHS | RHS; 9894 case Instruction::Xor: 9895 return LHS ^ RHS; 9896 } 9897 } 9898 9899 bool calculateBinaryOperatorAndTakeUnion(const BinaryOperator *BinOp, 9900 const APInt &LHS, const APInt &RHS) { 9901 bool SkipOperation = false; 9902 bool Unsupported = false; 9903 APInt Result = 9904 calculateBinaryOperator(BinOp, LHS, RHS, SkipOperation, Unsupported); 9905 if (Unsupported) 9906 return false; 9907 // If SkipOperation is true, we can ignore this operand pair (L, R). 9908 if (!SkipOperation) 9909 unionAssumed(Result); 9910 return isValidState(); 9911 } 9912 9913 ChangeStatus updateWithICmpInst(Attributor &A, ICmpInst *ICI) { 9914 auto AssumedBefore = getAssumed(); 9915 Value *LHS = ICI->getOperand(0); 9916 Value *RHS = ICI->getOperand(1); 9917 9918 bool LHSContainsUndef = false, RHSContainsUndef = false; 9919 SetTy LHSAAPVS, RHSAAPVS; 9920 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS, 9921 LHSContainsUndef, /* ForSelf */ false) || 9922 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS, 9923 RHSContainsUndef, /* ForSelf */ false)) 9924 return indicatePessimisticFixpoint(); 9925 9926 // TODO: make use of undef flag to limit potential values aggressively. 9927 bool MaybeTrue = false, MaybeFalse = false; 9928 const APInt Zero(RHS->getType()->getIntegerBitWidth(), 0); 9929 if (LHSContainsUndef && RHSContainsUndef) { 9930 // The result of any comparison between undefs can be soundly replaced 9931 // with undef. 9932 unionAssumedWithUndef(); 9933 } else if (LHSContainsUndef) { 9934 for (const APInt &R : RHSAAPVS) { 9935 bool CmpResult = calculateICmpInst(ICI, Zero, R); 9936 MaybeTrue |= CmpResult; 9937 MaybeFalse |= !CmpResult; 9938 if (MaybeTrue & MaybeFalse) 9939 return indicatePessimisticFixpoint(); 9940 } 9941 } else if (RHSContainsUndef) { 9942 for (const APInt &L : LHSAAPVS) { 9943 bool CmpResult = calculateICmpInst(ICI, L, Zero); 9944 MaybeTrue |= CmpResult; 9945 MaybeFalse |= !CmpResult; 9946 if (MaybeTrue & MaybeFalse) 9947 return indicatePessimisticFixpoint(); 9948 } 9949 } else { 9950 for (const APInt &L : LHSAAPVS) { 9951 for (const APInt &R : RHSAAPVS) { 9952 bool CmpResult = calculateICmpInst(ICI, L, R); 9953 MaybeTrue |= CmpResult; 9954 MaybeFalse |= !CmpResult; 9955 if (MaybeTrue & MaybeFalse) 9956 return indicatePessimisticFixpoint(); 9957 } 9958 } 9959 } 9960 if (MaybeTrue) 9961 unionAssumed(APInt(/* numBits */ 1, /* val */ 1)); 9962 if (MaybeFalse) 9963 unionAssumed(APInt(/* numBits */ 1, /* val */ 0)); 9964 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 9965 : ChangeStatus::CHANGED; 9966 } 9967 9968 ChangeStatus updateWithSelectInst(Attributor &A, SelectInst *SI) { 9969 auto AssumedBefore = getAssumed(); 9970 Value *LHS = SI->getTrueValue(); 9971 Value *RHS = SI->getFalseValue(); 9972 9973 bool UsedAssumedInformation = false; 9974 std::optional<Constant *> C = A.getAssumedConstant( 9975 *SI->getCondition(), *this, UsedAssumedInformation); 9976 9977 // Check if we only need one operand. 9978 bool OnlyLeft = false, OnlyRight = false; 9979 if (C && *C && (*C)->isOneValue()) 9980 OnlyLeft = true; 9981 else if (C && *C && (*C)->isZeroValue()) 9982 OnlyRight = true; 9983 9984 bool LHSContainsUndef = false, RHSContainsUndef = false; 9985 SetTy LHSAAPVS, RHSAAPVS; 9986 if (!OnlyRight && 9987 !fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS, 9988 LHSContainsUndef, /* ForSelf */ false)) 9989 return indicatePessimisticFixpoint(); 9990 9991 if (!OnlyLeft && 9992 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS, 9993 RHSContainsUndef, /* ForSelf */ false)) 9994 return indicatePessimisticFixpoint(); 9995 9996 if (OnlyLeft || OnlyRight) { 9997 // select (true/false), lhs, rhs 9998 auto *OpAA = OnlyLeft ? &LHSAAPVS : &RHSAAPVS; 9999 auto Undef = OnlyLeft ? LHSContainsUndef : RHSContainsUndef; 10000 10001 if (Undef) 10002 unionAssumedWithUndef(); 10003 else { 10004 for (const auto &It : *OpAA) 10005 unionAssumed(It); 10006 } 10007 10008 } else if (LHSContainsUndef && RHSContainsUndef) { 10009 // select i1 *, undef , undef => undef 10010 unionAssumedWithUndef(); 10011 } else { 10012 for (const auto &It : LHSAAPVS) 10013 unionAssumed(It); 10014 for (const auto &It : RHSAAPVS) 10015 unionAssumed(It); 10016 } 10017 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 10018 : ChangeStatus::CHANGED; 10019 } 10020 10021 ChangeStatus updateWithCastInst(Attributor &A, CastInst *CI) { 10022 auto AssumedBefore = getAssumed(); 10023 if (!CI->isIntegerCast()) 10024 return indicatePessimisticFixpoint(); 10025 assert(CI->getNumOperands() == 1 && "Expected cast to be unary!"); 10026 uint32_t ResultBitWidth = CI->getDestTy()->getIntegerBitWidth(); 10027 Value *Src = CI->getOperand(0); 10028 10029 bool SrcContainsUndef = false; 10030 SetTy SrcPVS; 10031 if (!fillSetWithConstantValues(A, IRPosition::value(*Src), SrcPVS, 10032 SrcContainsUndef, /* ForSelf */ false)) 10033 return indicatePessimisticFixpoint(); 10034 10035 if (SrcContainsUndef) 10036 unionAssumedWithUndef(); 10037 else { 10038 for (const APInt &S : SrcPVS) { 10039 APInt T = calculateCastInst(CI, S, ResultBitWidth); 10040 unionAssumed(T); 10041 } 10042 } 10043 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 10044 : ChangeStatus::CHANGED; 10045 } 10046 10047 ChangeStatus updateWithBinaryOperator(Attributor &A, BinaryOperator *BinOp) { 10048 auto AssumedBefore = getAssumed(); 10049 Value *LHS = BinOp->getOperand(0); 10050 Value *RHS = BinOp->getOperand(1); 10051 10052 bool LHSContainsUndef = false, RHSContainsUndef = false; 10053 SetTy LHSAAPVS, RHSAAPVS; 10054 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS, 10055 LHSContainsUndef, /* ForSelf */ false) || 10056 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS, 10057 RHSContainsUndef, /* ForSelf */ false)) 10058 return indicatePessimisticFixpoint(); 10059 10060 const APInt Zero = APInt(LHS->getType()->getIntegerBitWidth(), 0); 10061 10062 // TODO: make use of undef flag to limit potential values aggressively. 10063 if (LHSContainsUndef && RHSContainsUndef) { 10064 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, Zero)) 10065 return indicatePessimisticFixpoint(); 10066 } else if (LHSContainsUndef) { 10067 for (const APInt &R : RHSAAPVS) { 10068 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, R)) 10069 return indicatePessimisticFixpoint(); 10070 } 10071 } else if (RHSContainsUndef) { 10072 for (const APInt &L : LHSAAPVS) { 10073 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, Zero)) 10074 return indicatePessimisticFixpoint(); 10075 } 10076 } else { 10077 for (const APInt &L : LHSAAPVS) { 10078 for (const APInt &R : RHSAAPVS) { 10079 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, R)) 10080 return indicatePessimisticFixpoint(); 10081 } 10082 } 10083 } 10084 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 10085 : ChangeStatus::CHANGED; 10086 } 10087 10088 ChangeStatus updateWithInstruction(Attributor &A, Instruction *Inst) { 10089 auto AssumedBefore = getAssumed(); 10090 SetTy Incoming; 10091 bool ContainsUndef; 10092 if (!fillSetWithConstantValues(A, IRPosition::value(*Inst), Incoming, 10093 ContainsUndef, /* ForSelf */ true)) 10094 return indicatePessimisticFixpoint(); 10095 if (ContainsUndef) { 10096 unionAssumedWithUndef(); 10097 } else { 10098 for (const auto &It : Incoming) 10099 unionAssumed(It); 10100 } 10101 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 10102 : ChangeStatus::CHANGED; 10103 } 10104 10105 /// See AbstractAttribute::updateImpl(...). 10106 ChangeStatus updateImpl(Attributor &A) override { 10107 Value &V = getAssociatedValue(); 10108 Instruction *I = dyn_cast<Instruction>(&V); 10109 10110 if (auto *ICI = dyn_cast<ICmpInst>(I)) 10111 return updateWithICmpInst(A, ICI); 10112 10113 if (auto *SI = dyn_cast<SelectInst>(I)) 10114 return updateWithSelectInst(A, SI); 10115 10116 if (auto *CI = dyn_cast<CastInst>(I)) 10117 return updateWithCastInst(A, CI); 10118 10119 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) 10120 return updateWithBinaryOperator(A, BinOp); 10121 10122 if (isa<PHINode>(I) || isa<LoadInst>(I)) 10123 return updateWithInstruction(A, I); 10124 10125 return indicatePessimisticFixpoint(); 10126 } 10127 10128 /// See AbstractAttribute::trackStatistics() 10129 void trackStatistics() const override { 10130 STATS_DECLTRACK_FLOATING_ATTR(potential_values) 10131 } 10132 }; 10133 10134 struct AAPotentialConstantValuesFunction : AAPotentialConstantValuesImpl { 10135 AAPotentialConstantValuesFunction(const IRPosition &IRP, Attributor &A) 10136 : AAPotentialConstantValuesImpl(IRP, A) {} 10137 10138 /// See AbstractAttribute::initialize(...). 10139 ChangeStatus updateImpl(Attributor &A) override { 10140 llvm_unreachable( 10141 "AAPotentialConstantValues(Function|CallSite)::updateImpl will " 10142 "not be called"); 10143 } 10144 10145 /// See AbstractAttribute::trackStatistics() 10146 void trackStatistics() const override { 10147 STATS_DECLTRACK_FN_ATTR(potential_values) 10148 } 10149 }; 10150 10151 struct AAPotentialConstantValuesCallSite : AAPotentialConstantValuesFunction { 10152 AAPotentialConstantValuesCallSite(const IRPosition &IRP, Attributor &A) 10153 : AAPotentialConstantValuesFunction(IRP, A) {} 10154 10155 /// See AbstractAttribute::trackStatistics() 10156 void trackStatistics() const override { 10157 STATS_DECLTRACK_CS_ATTR(potential_values) 10158 } 10159 }; 10160 10161 struct AAPotentialConstantValuesCallSiteReturned 10162 : AACalleeToCallSite<AAPotentialConstantValues, 10163 AAPotentialConstantValuesImpl> { 10164 AAPotentialConstantValuesCallSiteReturned(const IRPosition &IRP, 10165 Attributor &A) 10166 : AACalleeToCallSite<AAPotentialConstantValues, 10167 AAPotentialConstantValuesImpl>(IRP, A) {} 10168 10169 /// See AbstractAttribute::trackStatistics() 10170 void trackStatistics() const override { 10171 STATS_DECLTRACK_CSRET_ATTR(potential_values) 10172 } 10173 }; 10174 10175 struct AAPotentialConstantValuesCallSiteArgument 10176 : AAPotentialConstantValuesFloating { 10177 AAPotentialConstantValuesCallSiteArgument(const IRPosition &IRP, 10178 Attributor &A) 10179 : AAPotentialConstantValuesFloating(IRP, A) {} 10180 10181 /// See AbstractAttribute::initialize(..). 10182 void initialize(Attributor &A) override { 10183 AAPotentialConstantValuesImpl::initialize(A); 10184 if (isAtFixpoint()) 10185 return; 10186 10187 Value &V = getAssociatedValue(); 10188 10189 if (auto *C = dyn_cast<ConstantInt>(&V)) { 10190 unionAssumed(C->getValue()); 10191 indicateOptimisticFixpoint(); 10192 return; 10193 } 10194 10195 if (isa<UndefValue>(&V)) { 10196 unionAssumedWithUndef(); 10197 indicateOptimisticFixpoint(); 10198 return; 10199 } 10200 } 10201 10202 /// See AbstractAttribute::updateImpl(...). 10203 ChangeStatus updateImpl(Attributor &A) override { 10204 Value &V = getAssociatedValue(); 10205 auto AssumedBefore = getAssumed(); 10206 auto *AA = A.getAAFor<AAPotentialConstantValues>( 10207 *this, IRPosition::value(V), DepClassTy::REQUIRED); 10208 if (!AA) 10209 return indicatePessimisticFixpoint(); 10210 const auto &S = AA->getAssumed(); 10211 unionAssumed(S); 10212 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 10213 : ChangeStatus::CHANGED; 10214 } 10215 10216 /// See AbstractAttribute::trackStatistics() 10217 void trackStatistics() const override { 10218 STATS_DECLTRACK_CSARG_ATTR(potential_values) 10219 } 10220 }; 10221 } // namespace 10222 10223 /// ------------------------ NoUndef Attribute --------------------------------- 10224 bool AANoUndef::isImpliedByIR(Attributor &A, const IRPosition &IRP, 10225 Attribute::AttrKind ImpliedAttributeKind, 10226 bool IgnoreSubsumingPositions) { 10227 assert(ImpliedAttributeKind == Attribute::NoUndef && 10228 "Unexpected attribute kind"); 10229 if (A.hasAttr(IRP, {Attribute::NoUndef}, IgnoreSubsumingPositions, 10230 Attribute::NoUndef)) 10231 return true; 10232 10233 Value &Val = IRP.getAssociatedValue(); 10234 if (IRP.getPositionKind() != IRPosition::IRP_RETURNED && 10235 isGuaranteedNotToBeUndefOrPoison(&Val)) { 10236 LLVMContext &Ctx = Val.getContext(); 10237 A.manifestAttrs(IRP, Attribute::get(Ctx, Attribute::NoUndef)); 10238 return true; 10239 } 10240 10241 return false; 10242 } 10243 10244 namespace { 10245 struct AANoUndefImpl : AANoUndef { 10246 AANoUndefImpl(const IRPosition &IRP, Attributor &A) : AANoUndef(IRP, A) {} 10247 10248 /// See AbstractAttribute::initialize(...). 10249 void initialize(Attributor &A) override { 10250 Value &V = getAssociatedValue(); 10251 if (isa<UndefValue>(V)) 10252 indicatePessimisticFixpoint(); 10253 assert(!isImpliedByIR(A, getIRPosition(), Attribute::NoUndef)); 10254 } 10255 10256 /// See followUsesInMBEC 10257 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I, 10258 AANoUndef::StateType &State) { 10259 const Value *UseV = U->get(); 10260 const DominatorTree *DT = nullptr; 10261 AssumptionCache *AC = nullptr; 10262 InformationCache &InfoCache = A.getInfoCache(); 10263 if (Function *F = getAnchorScope()) { 10264 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F); 10265 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F); 10266 } 10267 State.setKnown(isGuaranteedNotToBeUndefOrPoison(UseV, AC, I, DT)); 10268 bool TrackUse = false; 10269 // Track use for instructions which must produce undef or poison bits when 10270 // at least one operand contains such bits. 10271 if (isa<CastInst>(*I) || isa<GetElementPtrInst>(*I)) 10272 TrackUse = true; 10273 return TrackUse; 10274 } 10275 10276 /// See AbstractAttribute::getAsStr(). 10277 const std::string getAsStr(Attributor *A) const override { 10278 return getAssumed() ? "noundef" : "may-undef-or-poison"; 10279 } 10280 10281 ChangeStatus manifest(Attributor &A) override { 10282 // We don't manifest noundef attribute for dead positions because the 10283 // associated values with dead positions would be replaced with undef 10284 // values. 10285 bool UsedAssumedInformation = false; 10286 if (A.isAssumedDead(getIRPosition(), nullptr, nullptr, 10287 UsedAssumedInformation)) 10288 return ChangeStatus::UNCHANGED; 10289 // A position whose simplified value does not have any value is 10290 // considered to be dead. We don't manifest noundef in such positions for 10291 // the same reason above. 10292 if (!A.getAssumedSimplified(getIRPosition(), *this, UsedAssumedInformation, 10293 AA::Interprocedural) 10294 .has_value()) 10295 return ChangeStatus::UNCHANGED; 10296 return AANoUndef::manifest(A); 10297 } 10298 }; 10299 10300 struct AANoUndefFloating : public AANoUndefImpl { 10301 AANoUndefFloating(const IRPosition &IRP, Attributor &A) 10302 : AANoUndefImpl(IRP, A) {} 10303 10304 /// See AbstractAttribute::initialize(...). 10305 void initialize(Attributor &A) override { 10306 AANoUndefImpl::initialize(A); 10307 if (!getState().isAtFixpoint() && getAnchorScope() && 10308 !getAnchorScope()->isDeclaration()) 10309 if (Instruction *CtxI = getCtxI()) 10310 followUsesInMBEC(*this, A, getState(), *CtxI); 10311 } 10312 10313 /// See AbstractAttribute::updateImpl(...). 10314 ChangeStatus updateImpl(Attributor &A) override { 10315 auto VisitValueCB = [&](const IRPosition &IRP) -> bool { 10316 bool IsKnownNoUndef; 10317 return AA::hasAssumedIRAttr<Attribute::NoUndef>( 10318 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoUndef); 10319 }; 10320 10321 bool Stripped; 10322 bool UsedAssumedInformation = false; 10323 Value *AssociatedValue = &getAssociatedValue(); 10324 SmallVector<AA::ValueAndContext> Values; 10325 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values, 10326 AA::AnyScope, UsedAssumedInformation)) 10327 Stripped = false; 10328 else 10329 Stripped = 10330 Values.size() != 1 || Values.front().getValue() != AssociatedValue; 10331 10332 if (!Stripped) { 10333 // If we haven't stripped anything we might still be able to use a 10334 // different AA, but only if the IRP changes. Effectively when we 10335 // interpret this not as a call site value but as a floating/argument 10336 // value. 10337 const IRPosition AVIRP = IRPosition::value(*AssociatedValue); 10338 if (AVIRP == getIRPosition() || !VisitValueCB(AVIRP)) 10339 return indicatePessimisticFixpoint(); 10340 return ChangeStatus::UNCHANGED; 10341 } 10342 10343 for (const auto &VAC : Values) 10344 if (!VisitValueCB(IRPosition::value(*VAC.getValue()))) 10345 return indicatePessimisticFixpoint(); 10346 10347 return ChangeStatus::UNCHANGED; 10348 } 10349 10350 /// See AbstractAttribute::trackStatistics() 10351 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) } 10352 }; 10353 10354 struct AANoUndefReturned final 10355 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl> { 10356 AANoUndefReturned(const IRPosition &IRP, Attributor &A) 10357 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl>(IRP, A) {} 10358 10359 /// See AbstractAttribute::trackStatistics() 10360 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) } 10361 }; 10362 10363 struct AANoUndefArgument final 10364 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl> { 10365 AANoUndefArgument(const IRPosition &IRP, Attributor &A) 10366 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl>(IRP, A) {} 10367 10368 /// See AbstractAttribute::trackStatistics() 10369 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noundef) } 10370 }; 10371 10372 struct AANoUndefCallSiteArgument final : AANoUndefFloating { 10373 AANoUndefCallSiteArgument(const IRPosition &IRP, Attributor &A) 10374 : AANoUndefFloating(IRP, A) {} 10375 10376 /// See AbstractAttribute::trackStatistics() 10377 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noundef) } 10378 }; 10379 10380 struct AANoUndefCallSiteReturned final 10381 : AACalleeToCallSite<AANoUndef, AANoUndefImpl> { 10382 AANoUndefCallSiteReturned(const IRPosition &IRP, Attributor &A) 10383 : AACalleeToCallSite<AANoUndef, AANoUndefImpl>(IRP, A) {} 10384 10385 /// See AbstractAttribute::trackStatistics() 10386 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) } 10387 }; 10388 10389 /// ------------------------ NoFPClass Attribute ------------------------------- 10390 10391 struct AANoFPClassImpl : AANoFPClass { 10392 AANoFPClassImpl(const IRPosition &IRP, Attributor &A) : AANoFPClass(IRP, A) {} 10393 10394 void initialize(Attributor &A) override { 10395 const IRPosition &IRP = getIRPosition(); 10396 10397 Value &V = IRP.getAssociatedValue(); 10398 if (isa<UndefValue>(V)) { 10399 indicateOptimisticFixpoint(); 10400 return; 10401 } 10402 10403 SmallVector<Attribute> Attrs; 10404 A.getAttrs(getIRPosition(), {Attribute::NoFPClass}, Attrs, false); 10405 for (const auto &Attr : Attrs) { 10406 addKnownBits(Attr.getNoFPClass()); 10407 } 10408 10409 const DataLayout &DL = A.getDataLayout(); 10410 if (getPositionKind() != IRPosition::IRP_RETURNED) { 10411 KnownFPClass KnownFPClass = computeKnownFPClass(&V, DL); 10412 addKnownBits(~KnownFPClass.KnownFPClasses); 10413 } 10414 10415 if (Instruction *CtxI = getCtxI()) 10416 followUsesInMBEC(*this, A, getState(), *CtxI); 10417 } 10418 10419 /// See followUsesInMBEC 10420 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I, 10421 AANoFPClass::StateType &State) { 10422 // TODO: Determine what instructions can be looked through. 10423 auto *CB = dyn_cast<CallBase>(I); 10424 if (!CB) 10425 return false; 10426 10427 if (!CB->isArgOperand(U)) 10428 return false; 10429 10430 unsigned ArgNo = CB->getArgOperandNo(U); 10431 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo); 10432 if (auto *NoFPAA = A.getAAFor<AANoFPClass>(*this, IRP, DepClassTy::NONE)) 10433 State.addKnownBits(NoFPAA->getState().getKnown()); 10434 return false; 10435 } 10436 10437 const std::string getAsStr(Attributor *A) const override { 10438 std::string Result = "nofpclass"; 10439 raw_string_ostream OS(Result); 10440 OS << getKnownNoFPClass() << '/' << getAssumedNoFPClass(); 10441 return Result; 10442 } 10443 10444 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, 10445 SmallVectorImpl<Attribute> &Attrs) const override { 10446 Attrs.emplace_back(Attribute::getWithNoFPClass(Ctx, getAssumedNoFPClass())); 10447 } 10448 }; 10449 10450 struct AANoFPClassFloating : public AANoFPClassImpl { 10451 AANoFPClassFloating(const IRPosition &IRP, Attributor &A) 10452 : AANoFPClassImpl(IRP, A) {} 10453 10454 /// See AbstractAttribute::updateImpl(...). 10455 ChangeStatus updateImpl(Attributor &A) override { 10456 SmallVector<AA::ValueAndContext> Values; 10457 bool UsedAssumedInformation = false; 10458 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values, 10459 AA::AnyScope, UsedAssumedInformation)) { 10460 Values.push_back({getAssociatedValue(), getCtxI()}); 10461 } 10462 10463 StateType T; 10464 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool { 10465 const auto *AA = A.getAAFor<AANoFPClass>(*this, IRPosition::value(V), 10466 DepClassTy::REQUIRED); 10467 if (!AA || this == AA) { 10468 T.indicatePessimisticFixpoint(); 10469 } else { 10470 const AANoFPClass::StateType &S = 10471 static_cast<const AANoFPClass::StateType &>(AA->getState()); 10472 T ^= S; 10473 } 10474 return T.isValidState(); 10475 }; 10476 10477 for (const auto &VAC : Values) 10478 if (!VisitValueCB(*VAC.getValue(), VAC.getCtxI())) 10479 return indicatePessimisticFixpoint(); 10480 10481 return clampStateAndIndicateChange(getState(), T); 10482 } 10483 10484 /// See AbstractAttribute::trackStatistics() 10485 void trackStatistics() const override { 10486 STATS_DECLTRACK_FNRET_ATTR(nofpclass) 10487 } 10488 }; 10489 10490 struct AANoFPClassReturned final 10491 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl, 10492 AANoFPClassImpl::StateType, false, 10493 Attribute::None, false> { 10494 AANoFPClassReturned(const IRPosition &IRP, Attributor &A) 10495 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl, 10496 AANoFPClassImpl::StateType, false, 10497 Attribute::None, false>(IRP, A) {} 10498 10499 /// See AbstractAttribute::trackStatistics() 10500 void trackStatistics() const override { 10501 STATS_DECLTRACK_FNRET_ATTR(nofpclass) 10502 } 10503 }; 10504 10505 struct AANoFPClassArgument final 10506 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl> { 10507 AANoFPClassArgument(const IRPosition &IRP, Attributor &A) 10508 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl>(IRP, A) {} 10509 10510 /// See AbstractAttribute::trackStatistics() 10511 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofpclass) } 10512 }; 10513 10514 struct AANoFPClassCallSiteArgument final : AANoFPClassFloating { 10515 AANoFPClassCallSiteArgument(const IRPosition &IRP, Attributor &A) 10516 : AANoFPClassFloating(IRP, A) {} 10517 10518 /// See AbstractAttribute::trackStatistics() 10519 void trackStatistics() const override { 10520 STATS_DECLTRACK_CSARG_ATTR(nofpclass) 10521 } 10522 }; 10523 10524 struct AANoFPClassCallSiteReturned final 10525 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl> { 10526 AANoFPClassCallSiteReturned(const IRPosition &IRP, Attributor &A) 10527 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl>(IRP, A) {} 10528 10529 /// See AbstractAttribute::trackStatistics() 10530 void trackStatistics() const override { 10531 STATS_DECLTRACK_CSRET_ATTR(nofpclass) 10532 } 10533 }; 10534 10535 struct AACallEdgesImpl : public AACallEdges { 10536 AACallEdgesImpl(const IRPosition &IRP, Attributor &A) : AACallEdges(IRP, A) {} 10537 10538 const SetVector<Function *> &getOptimisticEdges() const override { 10539 return CalledFunctions; 10540 } 10541 10542 bool hasUnknownCallee() const override { return HasUnknownCallee; } 10543 10544 bool hasNonAsmUnknownCallee() const override { 10545 return HasUnknownCalleeNonAsm; 10546 } 10547 10548 const std::string getAsStr(Attributor *A) const override { 10549 return "CallEdges[" + std::to_string(HasUnknownCallee) + "," + 10550 std::to_string(CalledFunctions.size()) + "]"; 10551 } 10552 10553 void trackStatistics() const override {} 10554 10555 protected: 10556 void addCalledFunction(Function *Fn, ChangeStatus &Change) { 10557 if (CalledFunctions.insert(Fn)) { 10558 Change = ChangeStatus::CHANGED; 10559 LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn->getName() 10560 << "\n"); 10561 } 10562 } 10563 10564 void setHasUnknownCallee(bool NonAsm, ChangeStatus &Change) { 10565 if (!HasUnknownCallee) 10566 Change = ChangeStatus::CHANGED; 10567 if (NonAsm && !HasUnknownCalleeNonAsm) 10568 Change = ChangeStatus::CHANGED; 10569 HasUnknownCalleeNonAsm |= NonAsm; 10570 HasUnknownCallee = true; 10571 } 10572 10573 private: 10574 /// Optimistic set of functions that might be called by this position. 10575 SetVector<Function *> CalledFunctions; 10576 10577 /// Is there any call with a unknown callee. 10578 bool HasUnknownCallee = false; 10579 10580 /// Is there any call with a unknown callee, excluding any inline asm. 10581 bool HasUnknownCalleeNonAsm = false; 10582 }; 10583 10584 struct AACallEdgesCallSite : public AACallEdgesImpl { 10585 AACallEdgesCallSite(const IRPosition &IRP, Attributor &A) 10586 : AACallEdgesImpl(IRP, A) {} 10587 /// See AbstractAttribute::updateImpl(...). 10588 ChangeStatus updateImpl(Attributor &A) override { 10589 ChangeStatus Change = ChangeStatus::UNCHANGED; 10590 10591 auto VisitValue = [&](Value &V, const Instruction *CtxI) -> bool { 10592 if (Function *Fn = dyn_cast<Function>(&V)) { 10593 addCalledFunction(Fn, Change); 10594 } else { 10595 LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n"); 10596 setHasUnknownCallee(true, Change); 10597 } 10598 10599 // Explore all values. 10600 return true; 10601 }; 10602 10603 SmallVector<AA::ValueAndContext> Values; 10604 // Process any value that we might call. 10605 auto ProcessCalledOperand = [&](Value *V, Instruction *CtxI) { 10606 if (isa<Constant>(V)) { 10607 VisitValue(*V, CtxI); 10608 return; 10609 } 10610 10611 bool UsedAssumedInformation = false; 10612 Values.clear(); 10613 if (!A.getAssumedSimplifiedValues(IRPosition::value(*V), *this, Values, 10614 AA::AnyScope, UsedAssumedInformation)) { 10615 Values.push_back({*V, CtxI}); 10616 } 10617 for (auto &VAC : Values) 10618 VisitValue(*VAC.getValue(), VAC.getCtxI()); 10619 }; 10620 10621 CallBase *CB = cast<CallBase>(getCtxI()); 10622 10623 if (auto *IA = dyn_cast<InlineAsm>(CB->getCalledOperand())) { 10624 if (IA->hasSideEffects() && 10625 !hasAssumption(*CB->getCaller(), "ompx_no_call_asm") && 10626 !hasAssumption(*CB, "ompx_no_call_asm")) { 10627 setHasUnknownCallee(false, Change); 10628 } 10629 return Change; 10630 } 10631 10632 if (CB->isIndirectCall()) 10633 if (auto *IndirectCallAA = A.getAAFor<AAIndirectCallInfo>( 10634 *this, getIRPosition(), DepClassTy::OPTIONAL)) 10635 if (IndirectCallAA->foreachCallee( 10636 [&](Function *Fn) { return VisitValue(*Fn, CB); })) 10637 return Change; 10638 10639 // The most simple case. 10640 ProcessCalledOperand(CB->getCalledOperand(), CB); 10641 10642 // Process callback functions. 10643 SmallVector<const Use *, 4u> CallbackUses; 10644 AbstractCallSite::getCallbackUses(*CB, CallbackUses); 10645 for (const Use *U : CallbackUses) 10646 ProcessCalledOperand(U->get(), CB); 10647 10648 return Change; 10649 } 10650 }; 10651 10652 struct AACallEdgesFunction : public AACallEdgesImpl { 10653 AACallEdgesFunction(const IRPosition &IRP, Attributor &A) 10654 : AACallEdgesImpl(IRP, A) {} 10655 10656 /// See AbstractAttribute::updateImpl(...). 10657 ChangeStatus updateImpl(Attributor &A) override { 10658 ChangeStatus Change = ChangeStatus::UNCHANGED; 10659 10660 auto ProcessCallInst = [&](Instruction &Inst) { 10661 CallBase &CB = cast<CallBase>(Inst); 10662 10663 auto *CBEdges = A.getAAFor<AACallEdges>( 10664 *this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED); 10665 if (!CBEdges) 10666 return false; 10667 if (CBEdges->hasNonAsmUnknownCallee()) 10668 setHasUnknownCallee(true, Change); 10669 if (CBEdges->hasUnknownCallee()) 10670 setHasUnknownCallee(false, Change); 10671 10672 for (Function *F : CBEdges->getOptimisticEdges()) 10673 addCalledFunction(F, Change); 10674 10675 return true; 10676 }; 10677 10678 // Visit all callable instructions. 10679 bool UsedAssumedInformation = false; 10680 if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this, 10681 UsedAssumedInformation, 10682 /* CheckBBLivenessOnly */ true)) { 10683 // If we haven't looked at all call like instructions, assume that there 10684 // are unknown callees. 10685 setHasUnknownCallee(true, Change); 10686 } 10687 10688 return Change; 10689 } 10690 }; 10691 10692 /// -------------------AAInterFnReachability Attribute-------------------------- 10693 10694 struct AAInterFnReachabilityFunction 10695 : public CachedReachabilityAA<AAInterFnReachability, Function> { 10696 using Base = CachedReachabilityAA<AAInterFnReachability, Function>; 10697 AAInterFnReachabilityFunction(const IRPosition &IRP, Attributor &A) 10698 : Base(IRP, A) {} 10699 10700 bool instructionCanReach( 10701 Attributor &A, const Instruction &From, const Function &To, 10702 const AA::InstExclusionSetTy *ExclusionSet) const override { 10703 assert(From.getFunction() == getAnchorScope() && "Queried the wrong AA!"); 10704 auto *NonConstThis = const_cast<AAInterFnReachabilityFunction *>(this); 10705 10706 RQITy StackRQI(A, From, To, ExclusionSet, false); 10707 typename RQITy::Reachable Result; 10708 if (!NonConstThis->checkQueryCache(A, StackRQI, Result)) 10709 return NonConstThis->isReachableImpl(A, StackRQI, 10710 /*IsTemporaryRQI=*/true); 10711 return Result == RQITy::Reachable::Yes; 10712 } 10713 10714 bool isReachableImpl(Attributor &A, RQITy &RQI, 10715 bool IsTemporaryRQI) override { 10716 const Instruction *EntryI = 10717 &RQI.From->getFunction()->getEntryBlock().front(); 10718 if (EntryI != RQI.From && 10719 !instructionCanReach(A, *EntryI, *RQI.To, nullptr)) 10720 return rememberResult(A, RQITy::Reachable::No, RQI, false, 10721 IsTemporaryRQI); 10722 10723 auto CheckReachableCallBase = [&](CallBase *CB) { 10724 auto *CBEdges = A.getAAFor<AACallEdges>( 10725 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL); 10726 if (!CBEdges || !CBEdges->getState().isValidState()) 10727 return false; 10728 // TODO Check To backwards in this case. 10729 if (CBEdges->hasUnknownCallee()) 10730 return false; 10731 10732 for (Function *Fn : CBEdges->getOptimisticEdges()) { 10733 if (Fn == RQI.To) 10734 return false; 10735 10736 if (Fn->isDeclaration()) { 10737 if (Fn->hasFnAttribute(Attribute::NoCallback)) 10738 continue; 10739 // TODO Check To backwards in this case. 10740 return false; 10741 } 10742 10743 if (Fn == getAnchorScope()) { 10744 if (EntryI == RQI.From) 10745 continue; 10746 return false; 10747 } 10748 10749 const AAInterFnReachability *InterFnReachability = 10750 A.getAAFor<AAInterFnReachability>(*this, IRPosition::function(*Fn), 10751 DepClassTy::OPTIONAL); 10752 10753 const Instruction &FnFirstInst = Fn->getEntryBlock().front(); 10754 if (!InterFnReachability || 10755 InterFnReachability->instructionCanReach(A, FnFirstInst, *RQI.To, 10756 RQI.ExclusionSet)) 10757 return false; 10758 } 10759 return true; 10760 }; 10761 10762 const auto *IntraFnReachability = A.getAAFor<AAIntraFnReachability>( 10763 *this, IRPosition::function(*RQI.From->getFunction()), 10764 DepClassTy::OPTIONAL); 10765 10766 // Determine call like instructions that we can reach from the inst. 10767 auto CheckCallBase = [&](Instruction &CBInst) { 10768 // There are usually less nodes in the call graph, check inter function 10769 // reachability first. 10770 if (CheckReachableCallBase(cast<CallBase>(&CBInst))) 10771 return true; 10772 return IntraFnReachability && !IntraFnReachability->isAssumedReachable( 10773 A, *RQI.From, CBInst, RQI.ExclusionSet); 10774 }; 10775 10776 bool UsedExclusionSet = /* conservative */ true; 10777 bool UsedAssumedInformation = false; 10778 if (!A.checkForAllCallLikeInstructions(CheckCallBase, *this, 10779 UsedAssumedInformation, 10780 /* CheckBBLivenessOnly */ true)) 10781 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet, 10782 IsTemporaryRQI); 10783 10784 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet, 10785 IsTemporaryRQI); 10786 } 10787 10788 void trackStatistics() const override {} 10789 }; 10790 } // namespace 10791 10792 template <typename AAType> 10793 static std::optional<Constant *> 10794 askForAssumedConstant(Attributor &A, const AbstractAttribute &QueryingAA, 10795 const IRPosition &IRP, Type &Ty) { 10796 if (!Ty.isIntegerTy()) 10797 return nullptr; 10798 10799 // This will also pass the call base context. 10800 const auto *AA = A.getAAFor<AAType>(QueryingAA, IRP, DepClassTy::NONE); 10801 if (!AA) 10802 return nullptr; 10803 10804 std::optional<Constant *> COpt = AA->getAssumedConstant(A); 10805 10806 if (!COpt.has_value()) { 10807 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL); 10808 return std::nullopt; 10809 } 10810 if (auto *C = *COpt) { 10811 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL); 10812 return C; 10813 } 10814 return nullptr; 10815 } 10816 10817 Value *AAPotentialValues::getSingleValue( 10818 Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP, 10819 SmallVectorImpl<AA::ValueAndContext> &Values) { 10820 Type &Ty = *IRP.getAssociatedType(); 10821 std::optional<Value *> V; 10822 for (auto &It : Values) { 10823 V = AA::combineOptionalValuesInAAValueLatice(V, It.getValue(), &Ty); 10824 if (V.has_value() && !*V) 10825 break; 10826 } 10827 if (!V.has_value()) 10828 return UndefValue::get(&Ty); 10829 return *V; 10830 } 10831 10832 namespace { 10833 struct AAPotentialValuesImpl : AAPotentialValues { 10834 using StateType = PotentialLLVMValuesState; 10835 10836 AAPotentialValuesImpl(const IRPosition &IRP, Attributor &A) 10837 : AAPotentialValues(IRP, A) {} 10838 10839 /// See AbstractAttribute::initialize(..). 10840 void initialize(Attributor &A) override { 10841 if (A.hasSimplificationCallback(getIRPosition())) { 10842 indicatePessimisticFixpoint(); 10843 return; 10844 } 10845 Value *Stripped = getAssociatedValue().stripPointerCasts(); 10846 if (isa<Constant>(Stripped) && !isa<ConstantExpr>(Stripped)) { 10847 addValue(A, getState(), *Stripped, getCtxI(), AA::AnyScope, 10848 getAnchorScope()); 10849 indicateOptimisticFixpoint(); 10850 return; 10851 } 10852 AAPotentialValues::initialize(A); 10853 } 10854 10855 /// See AbstractAttribute::getAsStr(). 10856 const std::string getAsStr(Attributor *A) const override { 10857 std::string Str; 10858 llvm::raw_string_ostream OS(Str); 10859 OS << getState(); 10860 return Str; 10861 } 10862 10863 template <typename AAType> 10864 static std::optional<Value *> askOtherAA(Attributor &A, 10865 const AbstractAttribute &AA, 10866 const IRPosition &IRP, Type &Ty) { 10867 if (isa<Constant>(IRP.getAssociatedValue())) 10868 return &IRP.getAssociatedValue(); 10869 std::optional<Constant *> C = askForAssumedConstant<AAType>(A, AA, IRP, Ty); 10870 if (!C) 10871 return std::nullopt; 10872 if (*C) 10873 if (auto *CC = AA::getWithType(**C, Ty)) 10874 return CC; 10875 return nullptr; 10876 } 10877 10878 virtual void addValue(Attributor &A, StateType &State, Value &V, 10879 const Instruction *CtxI, AA::ValueScope S, 10880 Function *AnchorScope) const { 10881 10882 IRPosition ValIRP = IRPosition::value(V); 10883 if (auto *CB = dyn_cast_or_null<CallBase>(CtxI)) { 10884 for (const auto &U : CB->args()) { 10885 if (U.get() != &V) 10886 continue; 10887 ValIRP = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U)); 10888 break; 10889 } 10890 } 10891 10892 Value *VPtr = &V; 10893 if (ValIRP.getAssociatedType()->isIntegerTy()) { 10894 Type &Ty = *getAssociatedType(); 10895 std::optional<Value *> SimpleV = 10896 askOtherAA<AAValueConstantRange>(A, *this, ValIRP, Ty); 10897 if (SimpleV.has_value() && !*SimpleV) { 10898 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>( 10899 *this, ValIRP, DepClassTy::OPTIONAL); 10900 if (PotentialConstantsAA && PotentialConstantsAA->isValidState()) { 10901 for (const auto &It : PotentialConstantsAA->getAssumedSet()) 10902 State.unionAssumed({{*ConstantInt::get(&Ty, It), nullptr}, S}); 10903 if (PotentialConstantsAA->undefIsContained()) 10904 State.unionAssumed({{*UndefValue::get(&Ty), nullptr}, S}); 10905 return; 10906 } 10907 } 10908 if (!SimpleV.has_value()) 10909 return; 10910 10911 if (*SimpleV) 10912 VPtr = *SimpleV; 10913 } 10914 10915 if (isa<ConstantInt>(VPtr)) 10916 CtxI = nullptr; 10917 if (!AA::isValidInScope(*VPtr, AnchorScope)) 10918 S = AA::ValueScope(S | AA::Interprocedural); 10919 10920 State.unionAssumed({{*VPtr, CtxI}, S}); 10921 } 10922 10923 /// Helper struct to tie a value+context pair together with the scope for 10924 /// which this is the simplified version. 10925 struct ItemInfo { 10926 AA::ValueAndContext I; 10927 AA::ValueScope S; 10928 10929 bool operator==(const ItemInfo &II) const { 10930 return II.I == I && II.S == S; 10931 }; 10932 bool operator<(const ItemInfo &II) const { 10933 return std::tie(I, S) < std::tie(II.I, II.S); 10934 }; 10935 }; 10936 10937 bool recurseForValue(Attributor &A, const IRPosition &IRP, AA::ValueScope S) { 10938 SmallMapVector<AA::ValueAndContext, int, 8> ValueScopeMap; 10939 for (auto CS : {AA::Intraprocedural, AA::Interprocedural}) { 10940 if (!(CS & S)) 10941 continue; 10942 10943 bool UsedAssumedInformation = false; 10944 SmallVector<AA::ValueAndContext> Values; 10945 if (!A.getAssumedSimplifiedValues(IRP, this, Values, CS, 10946 UsedAssumedInformation)) 10947 return false; 10948 10949 for (auto &It : Values) 10950 ValueScopeMap[It] += CS; 10951 } 10952 for (auto &It : ValueScopeMap) 10953 addValue(A, getState(), *It.first.getValue(), It.first.getCtxI(), 10954 AA::ValueScope(It.second), getAnchorScope()); 10955 10956 return true; 10957 } 10958 10959 void giveUpOnIntraprocedural(Attributor &A) { 10960 auto NewS = StateType::getBestState(getState()); 10961 for (const auto &It : getAssumedSet()) { 10962 if (It.second == AA::Intraprocedural) 10963 continue; 10964 addValue(A, NewS, *It.first.getValue(), It.first.getCtxI(), 10965 AA::Interprocedural, getAnchorScope()); 10966 } 10967 assert(!undefIsContained() && "Undef should be an explicit value!"); 10968 addValue(A, NewS, getAssociatedValue(), getCtxI(), AA::Intraprocedural, 10969 getAnchorScope()); 10970 getState() = NewS; 10971 } 10972 10973 /// See AbstractState::indicatePessimisticFixpoint(...). 10974 ChangeStatus indicatePessimisticFixpoint() override { 10975 getState() = StateType::getBestState(getState()); 10976 getState().unionAssumed({{getAssociatedValue(), getCtxI()}, AA::AnyScope}); 10977 AAPotentialValues::indicateOptimisticFixpoint(); 10978 return ChangeStatus::CHANGED; 10979 } 10980 10981 /// See AbstractAttribute::updateImpl(...). 10982 ChangeStatus updateImpl(Attributor &A) override { 10983 return indicatePessimisticFixpoint(); 10984 } 10985 10986 /// See AbstractAttribute::manifest(...). 10987 ChangeStatus manifest(Attributor &A) override { 10988 SmallVector<AA::ValueAndContext> Values; 10989 for (AA::ValueScope S : {AA::Interprocedural, AA::Intraprocedural}) { 10990 Values.clear(); 10991 if (!getAssumedSimplifiedValues(A, Values, S)) 10992 continue; 10993 Value &OldV = getAssociatedValue(); 10994 if (isa<UndefValue>(OldV)) 10995 continue; 10996 Value *NewV = getSingleValue(A, *this, getIRPosition(), Values); 10997 if (!NewV || NewV == &OldV) 10998 continue; 10999 if (getCtxI() && 11000 !AA::isValidAtPosition({*NewV, *getCtxI()}, A.getInfoCache())) 11001 continue; 11002 if (A.changeAfterManifest(getIRPosition(), *NewV)) 11003 return ChangeStatus::CHANGED; 11004 } 11005 return ChangeStatus::UNCHANGED; 11006 } 11007 11008 bool getAssumedSimplifiedValues( 11009 Attributor &A, SmallVectorImpl<AA::ValueAndContext> &Values, 11010 AA::ValueScope S, bool RecurseForSelectAndPHI = false) const override { 11011 if (!isValidState()) 11012 return false; 11013 bool UsedAssumedInformation = false; 11014 for (const auto &It : getAssumedSet()) 11015 if (It.second & S) { 11016 if (RecurseForSelectAndPHI && (isa<PHINode>(It.first.getValue()) || 11017 isa<SelectInst>(It.first.getValue()))) { 11018 if (A.getAssumedSimplifiedValues( 11019 IRPosition::inst(*cast<Instruction>(It.first.getValue())), 11020 this, Values, S, UsedAssumedInformation)) 11021 continue; 11022 } 11023 Values.push_back(It.first); 11024 } 11025 assert(!undefIsContained() && "Undef should be an explicit value!"); 11026 return true; 11027 } 11028 }; 11029 11030 struct AAPotentialValuesFloating : AAPotentialValuesImpl { 11031 AAPotentialValuesFloating(const IRPosition &IRP, Attributor &A) 11032 : AAPotentialValuesImpl(IRP, A) {} 11033 11034 /// See AbstractAttribute::updateImpl(...). 11035 ChangeStatus updateImpl(Attributor &A) override { 11036 auto AssumedBefore = getAssumed(); 11037 11038 genericValueTraversal(A, &getAssociatedValue()); 11039 11040 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED 11041 : ChangeStatus::CHANGED; 11042 } 11043 11044 /// Helper struct to remember which AAIsDead instances we actually used. 11045 struct LivenessInfo { 11046 const AAIsDead *LivenessAA = nullptr; 11047 bool AnyDead = false; 11048 }; 11049 11050 /// Check if \p Cmp is a comparison we can simplify. 11051 /// 11052 /// We handle multiple cases, one in which at least one operand is an 11053 /// (assumed) nullptr. If so, try to simplify it using AANonNull on the other 11054 /// operand. Return true if successful, in that case Worklist will be updated. 11055 bool handleCmp(Attributor &A, Value &Cmp, Value *LHS, Value *RHS, 11056 CmpInst::Predicate Pred, ItemInfo II, 11057 SmallVectorImpl<ItemInfo> &Worklist) { 11058 11059 // Simplify the operands first. 11060 bool UsedAssumedInformation = false; 11061 SmallVector<AA::ValueAndContext> LHSValues, RHSValues; 11062 auto GetSimplifiedValues = [&](Value &V, 11063 SmallVector<AA::ValueAndContext> &Values) { 11064 if (!A.getAssumedSimplifiedValues( 11065 IRPosition::value(V, getCallBaseContext()), this, Values, 11066 AA::Intraprocedural, UsedAssumedInformation)) { 11067 Values.clear(); 11068 Values.push_back(AA::ValueAndContext{V, II.I.getCtxI()}); 11069 } 11070 return Values.empty(); 11071 }; 11072 if (GetSimplifiedValues(*LHS, LHSValues)) 11073 return true; 11074 if (GetSimplifiedValues(*RHS, RHSValues)) 11075 return true; 11076 11077 LLVMContext &Ctx = LHS->getContext(); 11078 11079 InformationCache &InfoCache = A.getInfoCache(); 11080 Instruction *CmpI = dyn_cast<Instruction>(&Cmp); 11081 Function *F = CmpI ? CmpI->getFunction() : nullptr; 11082 const auto *DT = 11083 F ? InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F) 11084 : nullptr; 11085 const auto *TLI = 11086 F ? A.getInfoCache().getTargetLibraryInfoForFunction(*F) : nullptr; 11087 auto *AC = 11088 F ? InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F) 11089 : nullptr; 11090 11091 const DataLayout &DL = A.getDataLayout(); 11092 SimplifyQuery Q(DL, TLI, DT, AC, CmpI); 11093 11094 auto CheckPair = [&](Value &LHSV, Value &RHSV) { 11095 if (isa<UndefValue>(LHSV) || isa<UndefValue>(RHSV)) { 11096 addValue(A, getState(), *UndefValue::get(Cmp.getType()), 11097 /* CtxI */ nullptr, II.S, getAnchorScope()); 11098 return true; 11099 } 11100 11101 // Handle the trivial case first in which we don't even need to think 11102 // about null or non-null. 11103 if (&LHSV == &RHSV && 11104 (CmpInst::isTrueWhenEqual(Pred) || CmpInst::isFalseWhenEqual(Pred))) { 11105 Constant *NewV = ConstantInt::get(Type::getInt1Ty(Ctx), 11106 CmpInst::isTrueWhenEqual(Pred)); 11107 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S, 11108 getAnchorScope()); 11109 return true; 11110 } 11111 11112 auto *TypedLHS = AA::getWithType(LHSV, *LHS->getType()); 11113 auto *TypedRHS = AA::getWithType(RHSV, *RHS->getType()); 11114 if (TypedLHS && TypedRHS) { 11115 Value *NewV = simplifyCmpInst(Pred, TypedLHS, TypedRHS, Q); 11116 if (NewV && NewV != &Cmp) { 11117 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S, 11118 getAnchorScope()); 11119 return true; 11120 } 11121 } 11122 11123 // From now on we only handle equalities (==, !=). 11124 if (!CmpInst::isEquality(Pred)) 11125 return false; 11126 11127 bool LHSIsNull = isa<ConstantPointerNull>(LHSV); 11128 bool RHSIsNull = isa<ConstantPointerNull>(RHSV); 11129 if (!LHSIsNull && !RHSIsNull) 11130 return false; 11131 11132 // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the 11133 // non-nullptr operand and if we assume it's non-null we can conclude the 11134 // result of the comparison. 11135 assert((LHSIsNull || RHSIsNull) && 11136 "Expected nullptr versus non-nullptr comparison at this point"); 11137 11138 // The index is the operand that we assume is not null. 11139 unsigned PtrIdx = LHSIsNull; 11140 bool IsKnownNonNull; 11141 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>( 11142 A, this, IRPosition::value(*(PtrIdx ? &RHSV : &LHSV)), 11143 DepClassTy::REQUIRED, IsKnownNonNull); 11144 if (!IsAssumedNonNull) 11145 return false; 11146 11147 // The new value depends on the predicate, true for != and false for ==. 11148 Constant *NewV = 11149 ConstantInt::get(Type::getInt1Ty(Ctx), Pred == CmpInst::ICMP_NE); 11150 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S, 11151 getAnchorScope()); 11152 return true; 11153 }; 11154 11155 for (auto &LHSValue : LHSValues) 11156 for (auto &RHSValue : RHSValues) 11157 if (!CheckPair(*LHSValue.getValue(), *RHSValue.getValue())) 11158 return false; 11159 return true; 11160 } 11161 11162 bool handleSelectInst(Attributor &A, SelectInst &SI, ItemInfo II, 11163 SmallVectorImpl<ItemInfo> &Worklist) { 11164 const Instruction *CtxI = II.I.getCtxI(); 11165 bool UsedAssumedInformation = false; 11166 11167 std::optional<Constant *> C = 11168 A.getAssumedConstant(*SI.getCondition(), *this, UsedAssumedInformation); 11169 bool NoValueYet = !C.has_value(); 11170 if (NoValueYet || isa_and_nonnull<UndefValue>(*C)) 11171 return true; 11172 if (auto *CI = dyn_cast_or_null<ConstantInt>(*C)) { 11173 if (CI->isZero()) 11174 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S}); 11175 else 11176 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S}); 11177 } else if (&SI == &getAssociatedValue()) { 11178 // We could not simplify the condition, assume both values. 11179 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S}); 11180 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S}); 11181 } else { 11182 std::optional<Value *> SimpleV = A.getAssumedSimplified( 11183 IRPosition::inst(SI), *this, UsedAssumedInformation, II.S); 11184 if (!SimpleV.has_value()) 11185 return true; 11186 if (*SimpleV) { 11187 addValue(A, getState(), **SimpleV, CtxI, II.S, getAnchorScope()); 11188 return true; 11189 } 11190 return false; 11191 } 11192 return true; 11193 } 11194 11195 bool handleLoadInst(Attributor &A, LoadInst &LI, ItemInfo II, 11196 SmallVectorImpl<ItemInfo> &Worklist) { 11197 SmallSetVector<Value *, 4> PotentialCopies; 11198 SmallSetVector<Instruction *, 4> PotentialValueOrigins; 11199 bool UsedAssumedInformation = false; 11200 if (!AA::getPotentiallyLoadedValues(A, LI, PotentialCopies, 11201 PotentialValueOrigins, *this, 11202 UsedAssumedInformation, 11203 /* OnlyExact */ true)) { 11204 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Failed to get potentially " 11205 "loaded values for load instruction " 11206 << LI << "\n"); 11207 return false; 11208 } 11209 11210 // Do not simplify loads that are only used in llvm.assume if we cannot also 11211 // remove all stores that may feed into the load. The reason is that the 11212 // assume is probably worth something as long as the stores are around. 11213 InformationCache &InfoCache = A.getInfoCache(); 11214 if (InfoCache.isOnlyUsedByAssume(LI)) { 11215 if (!llvm::all_of(PotentialValueOrigins, [&](Instruction *I) { 11216 if (!I || isa<AssumeInst>(I)) 11217 return true; 11218 if (auto *SI = dyn_cast<StoreInst>(I)) 11219 return A.isAssumedDead(SI->getOperandUse(0), this, 11220 /* LivenessAA */ nullptr, 11221 UsedAssumedInformation, 11222 /* CheckBBLivenessOnly */ false); 11223 return A.isAssumedDead(*I, this, /* LivenessAA */ nullptr, 11224 UsedAssumedInformation, 11225 /* CheckBBLivenessOnly */ false); 11226 })) { 11227 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Load is onl used by assumes " 11228 "and we cannot delete all the stores: " 11229 << LI << "\n"); 11230 return false; 11231 } 11232 } 11233 11234 // Values have to be dynamically unique or we loose the fact that a 11235 // single llvm::Value might represent two runtime values (e.g., 11236 // stack locations in different recursive calls). 11237 const Instruction *CtxI = II.I.getCtxI(); 11238 bool ScopeIsLocal = (II.S & AA::Intraprocedural); 11239 bool AllLocal = ScopeIsLocal; 11240 bool DynamicallyUnique = llvm::all_of(PotentialCopies, [&](Value *PC) { 11241 AllLocal &= AA::isValidInScope(*PC, getAnchorScope()); 11242 return AA::isDynamicallyUnique(A, *this, *PC); 11243 }); 11244 if (!DynamicallyUnique) { 11245 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Not all potentially loaded " 11246 "values are dynamically unique: " 11247 << LI << "\n"); 11248 return false; 11249 } 11250 11251 for (auto *PotentialCopy : PotentialCopies) { 11252 if (AllLocal) { 11253 Worklist.push_back({{*PotentialCopy, CtxI}, II.S}); 11254 } else { 11255 Worklist.push_back({{*PotentialCopy, CtxI}, AA::Interprocedural}); 11256 } 11257 } 11258 if (!AllLocal && ScopeIsLocal) 11259 addValue(A, getState(), LI, CtxI, AA::Intraprocedural, getAnchorScope()); 11260 return true; 11261 } 11262 11263 bool handlePHINode( 11264 Attributor &A, PHINode &PHI, ItemInfo II, 11265 SmallVectorImpl<ItemInfo> &Worklist, 11266 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) { 11267 auto GetLivenessInfo = [&](const Function &F) -> LivenessInfo & { 11268 LivenessInfo &LI = LivenessAAs[&F]; 11269 if (!LI.LivenessAA) 11270 LI.LivenessAA = A.getAAFor<AAIsDead>(*this, IRPosition::function(F), 11271 DepClassTy::NONE); 11272 return LI; 11273 }; 11274 11275 if (&PHI == &getAssociatedValue()) { 11276 LivenessInfo &LI = GetLivenessInfo(*PHI.getFunction()); 11277 const auto *CI = 11278 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>( 11279 *PHI.getFunction()); 11280 11281 Cycle *C = nullptr; 11282 bool CyclePHI = mayBeInCycle(CI, &PHI, /* HeaderOnly */ true, &C); 11283 for (unsigned u = 0, e = PHI.getNumIncomingValues(); u < e; u++) { 11284 BasicBlock *IncomingBB = PHI.getIncomingBlock(u); 11285 if (LI.LivenessAA && 11286 LI.LivenessAA->isEdgeDead(IncomingBB, PHI.getParent())) { 11287 LI.AnyDead = true; 11288 continue; 11289 } 11290 Value *V = PHI.getIncomingValue(u); 11291 if (V == &PHI) 11292 continue; 11293 11294 // If the incoming value is not the PHI but an instruction in the same 11295 // cycle we might have multiple versions of it flying around. 11296 if (CyclePHI && isa<Instruction>(V) && 11297 (!C || C->contains(cast<Instruction>(V)->getParent()))) 11298 return false; 11299 11300 Worklist.push_back({{*V, IncomingBB->getTerminator()}, II.S}); 11301 } 11302 return true; 11303 } 11304 11305 bool UsedAssumedInformation = false; 11306 std::optional<Value *> SimpleV = A.getAssumedSimplified( 11307 IRPosition::inst(PHI), *this, UsedAssumedInformation, II.S); 11308 if (!SimpleV.has_value()) 11309 return true; 11310 if (!(*SimpleV)) 11311 return false; 11312 addValue(A, getState(), **SimpleV, &PHI, II.S, getAnchorScope()); 11313 return true; 11314 } 11315 11316 /// Use the generic, non-optimistic InstSimplfy functionality if we managed to 11317 /// simplify any operand of the instruction \p I. Return true if successful, 11318 /// in that case Worklist will be updated. 11319 bool handleGenericInst(Attributor &A, Instruction &I, ItemInfo II, 11320 SmallVectorImpl<ItemInfo> &Worklist) { 11321 bool SomeSimplified = false; 11322 bool UsedAssumedInformation = false; 11323 11324 SmallVector<Value *, 8> NewOps(I.getNumOperands()); 11325 int Idx = 0; 11326 for (Value *Op : I.operands()) { 11327 const auto &SimplifiedOp = A.getAssumedSimplified( 11328 IRPosition::value(*Op, getCallBaseContext()), *this, 11329 UsedAssumedInformation, AA::Intraprocedural); 11330 // If we are not sure about any operand we are not sure about the entire 11331 // instruction, we'll wait. 11332 if (!SimplifiedOp.has_value()) 11333 return true; 11334 11335 if (*SimplifiedOp) 11336 NewOps[Idx] = *SimplifiedOp; 11337 else 11338 NewOps[Idx] = Op; 11339 11340 SomeSimplified |= (NewOps[Idx] != Op); 11341 ++Idx; 11342 } 11343 11344 // We won't bother with the InstSimplify interface if we didn't simplify any 11345 // operand ourselves. 11346 if (!SomeSimplified) 11347 return false; 11348 11349 InformationCache &InfoCache = A.getInfoCache(); 11350 Function *F = I.getFunction(); 11351 const auto *DT = 11352 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F); 11353 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F); 11354 auto *AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F); 11355 11356 const DataLayout &DL = I.getDataLayout(); 11357 SimplifyQuery Q(DL, TLI, DT, AC, &I); 11358 Value *NewV = simplifyInstructionWithOperands(&I, NewOps, Q); 11359 if (!NewV || NewV == &I) 11360 return false; 11361 11362 LLVM_DEBUG(dbgs() << "Generic inst " << I << " assumed simplified to " 11363 << *NewV << "\n"); 11364 Worklist.push_back({{*NewV, II.I.getCtxI()}, II.S}); 11365 return true; 11366 } 11367 11368 bool simplifyInstruction( 11369 Attributor &A, Instruction &I, ItemInfo II, 11370 SmallVectorImpl<ItemInfo> &Worklist, 11371 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) { 11372 if (auto *CI = dyn_cast<CmpInst>(&I)) 11373 return handleCmp(A, *CI, CI->getOperand(0), CI->getOperand(1), 11374 CI->getPredicate(), II, Worklist); 11375 11376 switch (I.getOpcode()) { 11377 case Instruction::Select: 11378 return handleSelectInst(A, cast<SelectInst>(I), II, Worklist); 11379 case Instruction::PHI: 11380 return handlePHINode(A, cast<PHINode>(I), II, Worklist, LivenessAAs); 11381 case Instruction::Load: 11382 return handleLoadInst(A, cast<LoadInst>(I), II, Worklist); 11383 default: 11384 return handleGenericInst(A, I, II, Worklist); 11385 }; 11386 return false; 11387 } 11388 11389 void genericValueTraversal(Attributor &A, Value *InitialV) { 11390 SmallMapVector<const Function *, LivenessInfo, 4> LivenessAAs; 11391 11392 SmallSet<ItemInfo, 16> Visited; 11393 SmallVector<ItemInfo, 16> Worklist; 11394 Worklist.push_back({{*InitialV, getCtxI()}, AA::AnyScope}); 11395 11396 int Iteration = 0; 11397 do { 11398 ItemInfo II = Worklist.pop_back_val(); 11399 Value *V = II.I.getValue(); 11400 assert(V); 11401 const Instruction *CtxI = II.I.getCtxI(); 11402 AA::ValueScope S = II.S; 11403 11404 // Check if we should process the current value. To prevent endless 11405 // recursion keep a record of the values we followed! 11406 if (!Visited.insert(II).second) 11407 continue; 11408 11409 // Make sure we limit the compile time for complex expressions. 11410 if (Iteration++ >= MaxPotentialValuesIterations) { 11411 LLVM_DEBUG(dbgs() << "Generic value traversal reached iteration limit: " 11412 << Iteration << "!\n"); 11413 addValue(A, getState(), *V, CtxI, S, getAnchorScope()); 11414 continue; 11415 } 11416 11417 // Explicitly look through calls with a "returned" attribute if we do 11418 // not have a pointer as stripPointerCasts only works on them. 11419 Value *NewV = nullptr; 11420 if (V->getType()->isPointerTy()) { 11421 NewV = AA::getWithType(*V->stripPointerCasts(), *V->getType()); 11422 } else { 11423 if (auto *CB = dyn_cast<CallBase>(V)) 11424 if (auto *Callee = 11425 dyn_cast_if_present<Function>(CB->getCalledOperand())) { 11426 for (Argument &Arg : Callee->args()) 11427 if (Arg.hasReturnedAttr()) { 11428 NewV = CB->getArgOperand(Arg.getArgNo()); 11429 break; 11430 } 11431 } 11432 } 11433 if (NewV && NewV != V) { 11434 Worklist.push_back({{*NewV, CtxI}, S}); 11435 continue; 11436 } 11437 11438 if (auto *I = dyn_cast<Instruction>(V)) { 11439 if (simplifyInstruction(A, *I, II, Worklist, LivenessAAs)) 11440 continue; 11441 } 11442 11443 if (V != InitialV || isa<Argument>(V)) 11444 if (recurseForValue(A, IRPosition::value(*V), II.S)) 11445 continue; 11446 11447 // If we haven't stripped anything we give up. 11448 if (V == InitialV && CtxI == getCtxI()) { 11449 indicatePessimisticFixpoint(); 11450 return; 11451 } 11452 11453 addValue(A, getState(), *V, CtxI, S, getAnchorScope()); 11454 } while (!Worklist.empty()); 11455 11456 // If we actually used liveness information so we have to record a 11457 // dependence. 11458 for (auto &It : LivenessAAs) 11459 if (It.second.AnyDead) 11460 A.recordDependence(*It.second.LivenessAA, *this, DepClassTy::OPTIONAL); 11461 } 11462 11463 /// See AbstractAttribute::trackStatistics() 11464 void trackStatistics() const override { 11465 STATS_DECLTRACK_FLOATING_ATTR(potential_values) 11466 } 11467 }; 11468 11469 struct AAPotentialValuesArgument final : AAPotentialValuesImpl { 11470 using Base = AAPotentialValuesImpl; 11471 AAPotentialValuesArgument(const IRPosition &IRP, Attributor &A) 11472 : Base(IRP, A) {} 11473 11474 /// See AbstractAttribute::initialize(..). 11475 void initialize(Attributor &A) override { 11476 auto &Arg = cast<Argument>(getAssociatedValue()); 11477 if (Arg.hasPointeeInMemoryValueAttr()) 11478 indicatePessimisticFixpoint(); 11479 } 11480 11481 /// See AbstractAttribute::updateImpl(...). 11482 ChangeStatus updateImpl(Attributor &A) override { 11483 auto AssumedBefore = getAssumed(); 11484 11485 unsigned ArgNo = getCalleeArgNo(); 11486 11487 bool UsedAssumedInformation = false; 11488 SmallVector<AA::ValueAndContext> Values; 11489 auto CallSitePred = [&](AbstractCallSite ACS) { 11490 const auto CSArgIRP = IRPosition::callsite_argument(ACS, ArgNo); 11491 if (CSArgIRP.getPositionKind() == IRP_INVALID) 11492 return false; 11493 11494 if (!A.getAssumedSimplifiedValues(CSArgIRP, this, Values, 11495 AA::Interprocedural, 11496 UsedAssumedInformation)) 11497 return false; 11498 11499 return isValidState(); 11500 }; 11501 11502 if (!A.checkForAllCallSites(CallSitePred, *this, 11503 /* RequireAllCallSites */ true, 11504 UsedAssumedInformation)) 11505 return indicatePessimisticFixpoint(); 11506 11507 Function *Fn = getAssociatedFunction(); 11508 bool AnyNonLocal = false; 11509 for (auto &It : Values) { 11510 if (isa<Constant>(It.getValue())) { 11511 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope, 11512 getAnchorScope()); 11513 continue; 11514 } 11515 if (!AA::isDynamicallyUnique(A, *this, *It.getValue())) 11516 return indicatePessimisticFixpoint(); 11517 11518 if (auto *Arg = dyn_cast<Argument>(It.getValue())) 11519 if (Arg->getParent() == Fn) { 11520 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope, 11521 getAnchorScope()); 11522 continue; 11523 } 11524 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::Interprocedural, 11525 getAnchorScope()); 11526 AnyNonLocal = true; 11527 } 11528 assert(!undefIsContained() && "Undef should be an explicit value!"); 11529 if (AnyNonLocal) 11530 giveUpOnIntraprocedural(A); 11531 11532 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED 11533 : ChangeStatus::CHANGED; 11534 } 11535 11536 /// See AbstractAttribute::trackStatistics() 11537 void trackStatistics() const override { 11538 STATS_DECLTRACK_ARG_ATTR(potential_values) 11539 } 11540 }; 11541 11542 struct AAPotentialValuesReturned : public AAPotentialValuesFloating { 11543 using Base = AAPotentialValuesFloating; 11544 AAPotentialValuesReturned(const IRPosition &IRP, Attributor &A) 11545 : Base(IRP, A) {} 11546 11547 /// See AbstractAttribute::initialize(..). 11548 void initialize(Attributor &A) override { 11549 Function *F = getAssociatedFunction(); 11550 if (!F || F->isDeclaration() || F->getReturnType()->isVoidTy()) { 11551 indicatePessimisticFixpoint(); 11552 return; 11553 } 11554 11555 for (Argument &Arg : F->args()) 11556 if (Arg.hasReturnedAttr()) { 11557 addValue(A, getState(), Arg, nullptr, AA::AnyScope, F); 11558 ReturnedArg = &Arg; 11559 break; 11560 } 11561 if (!A.isFunctionIPOAmendable(*F) || 11562 A.hasSimplificationCallback(getIRPosition())) { 11563 if (!ReturnedArg) 11564 indicatePessimisticFixpoint(); 11565 else 11566 indicateOptimisticFixpoint(); 11567 } 11568 } 11569 11570 /// See AbstractAttribute::updateImpl(...). 11571 ChangeStatus updateImpl(Attributor &A) override { 11572 auto AssumedBefore = getAssumed(); 11573 bool UsedAssumedInformation = false; 11574 11575 SmallVector<AA::ValueAndContext> Values; 11576 Function *AnchorScope = getAnchorScope(); 11577 auto HandleReturnedValue = [&](Value &V, Instruction *CtxI, 11578 bool AddValues) { 11579 for (AA::ValueScope S : {AA::Interprocedural, AA::Intraprocedural}) { 11580 Values.clear(); 11581 if (!A.getAssumedSimplifiedValues(IRPosition::value(V), this, Values, S, 11582 UsedAssumedInformation, 11583 /* RecurseForSelectAndPHI */ true)) 11584 return false; 11585 if (!AddValues) 11586 continue; 11587 11588 bool AllInterAreIntra = false; 11589 if (S == AA::Interprocedural) 11590 AllInterAreIntra = 11591 llvm::all_of(Values, [&](const AA::ValueAndContext &VAC) { 11592 return AA::isValidInScope(*VAC.getValue(), AnchorScope); 11593 }); 11594 11595 for (const AA::ValueAndContext &VAC : Values) { 11596 addValue(A, getState(), *VAC.getValue(), 11597 VAC.getCtxI() ? VAC.getCtxI() : CtxI, 11598 AllInterAreIntra ? AA::AnyScope : S, AnchorScope); 11599 } 11600 if (AllInterAreIntra) 11601 break; 11602 } 11603 return true; 11604 }; 11605 11606 if (ReturnedArg) { 11607 HandleReturnedValue(*ReturnedArg, nullptr, true); 11608 } else { 11609 auto RetInstPred = [&](Instruction &RetI) { 11610 bool AddValues = true; 11611 if (isa<PHINode>(RetI.getOperand(0)) || 11612 isa<SelectInst>(RetI.getOperand(0))) { 11613 addValue(A, getState(), *RetI.getOperand(0), &RetI, AA::AnyScope, 11614 AnchorScope); 11615 AddValues = false; 11616 } 11617 return HandleReturnedValue(*RetI.getOperand(0), &RetI, AddValues); 11618 }; 11619 11620 if (!A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret}, 11621 UsedAssumedInformation, 11622 /* CheckBBLivenessOnly */ true)) 11623 return indicatePessimisticFixpoint(); 11624 } 11625 11626 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED 11627 : ChangeStatus::CHANGED; 11628 } 11629 11630 ChangeStatus manifest(Attributor &A) override { 11631 if (ReturnedArg) 11632 return ChangeStatus::UNCHANGED; 11633 SmallVector<AA::ValueAndContext> Values; 11634 if (!getAssumedSimplifiedValues(A, Values, AA::ValueScope::Intraprocedural, 11635 /* RecurseForSelectAndPHI */ true)) 11636 return ChangeStatus::UNCHANGED; 11637 Value *NewVal = getSingleValue(A, *this, getIRPosition(), Values); 11638 if (!NewVal) 11639 return ChangeStatus::UNCHANGED; 11640 11641 ChangeStatus Changed = ChangeStatus::UNCHANGED; 11642 if (auto *Arg = dyn_cast<Argument>(NewVal)) { 11643 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn, 11644 "Number of function with unique return"); 11645 Changed |= A.manifestAttrs( 11646 IRPosition::argument(*Arg), 11647 {Attribute::get(Arg->getContext(), Attribute::Returned)}); 11648 STATS_DECLTRACK_ARG_ATTR(returned); 11649 } 11650 11651 auto RetInstPred = [&](Instruction &RetI) { 11652 Value *RetOp = RetI.getOperand(0); 11653 if (isa<UndefValue>(RetOp) || RetOp == NewVal) 11654 return true; 11655 if (AA::isValidAtPosition({*NewVal, RetI}, A.getInfoCache())) 11656 if (A.changeUseAfterManifest(RetI.getOperandUse(0), *NewVal)) 11657 Changed = ChangeStatus::CHANGED; 11658 return true; 11659 }; 11660 bool UsedAssumedInformation = false; 11661 (void)A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret}, 11662 UsedAssumedInformation, 11663 /* CheckBBLivenessOnly */ true); 11664 return Changed; 11665 } 11666 11667 ChangeStatus indicatePessimisticFixpoint() override { 11668 return AAPotentialValues::indicatePessimisticFixpoint(); 11669 } 11670 11671 /// See AbstractAttribute::trackStatistics() 11672 void trackStatistics() const override{ 11673 STATS_DECLTRACK_FNRET_ATTR(potential_values)} 11674 11675 /// The argumented with an existing `returned` attribute. 11676 Argument *ReturnedArg = nullptr; 11677 }; 11678 11679 struct AAPotentialValuesFunction : AAPotentialValuesImpl { 11680 AAPotentialValuesFunction(const IRPosition &IRP, Attributor &A) 11681 : AAPotentialValuesImpl(IRP, A) {} 11682 11683 /// See AbstractAttribute::updateImpl(...). 11684 ChangeStatus updateImpl(Attributor &A) override { 11685 llvm_unreachable("AAPotentialValues(Function|CallSite)::updateImpl will " 11686 "not be called"); 11687 } 11688 11689 /// See AbstractAttribute::trackStatistics() 11690 void trackStatistics() const override { 11691 STATS_DECLTRACK_FN_ATTR(potential_values) 11692 } 11693 }; 11694 11695 struct AAPotentialValuesCallSite : AAPotentialValuesFunction { 11696 AAPotentialValuesCallSite(const IRPosition &IRP, Attributor &A) 11697 : AAPotentialValuesFunction(IRP, A) {} 11698 11699 /// See AbstractAttribute::trackStatistics() 11700 void trackStatistics() const override { 11701 STATS_DECLTRACK_CS_ATTR(potential_values) 11702 } 11703 }; 11704 11705 struct AAPotentialValuesCallSiteReturned : AAPotentialValuesImpl { 11706 AAPotentialValuesCallSiteReturned(const IRPosition &IRP, Attributor &A) 11707 : AAPotentialValuesImpl(IRP, A) {} 11708 11709 /// See AbstractAttribute::updateImpl(...). 11710 ChangeStatus updateImpl(Attributor &A) override { 11711 auto AssumedBefore = getAssumed(); 11712 11713 Function *Callee = getAssociatedFunction(); 11714 if (!Callee) 11715 return indicatePessimisticFixpoint(); 11716 11717 bool UsedAssumedInformation = false; 11718 auto *CB = cast<CallBase>(getCtxI()); 11719 if (CB->isMustTailCall() && 11720 !A.isAssumedDead(IRPosition::inst(*CB), this, nullptr, 11721 UsedAssumedInformation)) 11722 return indicatePessimisticFixpoint(); 11723 11724 Function *Caller = CB->getCaller(); 11725 11726 auto AddScope = [&](AA::ValueScope S) { 11727 SmallVector<AA::ValueAndContext> Values; 11728 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this, 11729 Values, S, UsedAssumedInformation)) 11730 return false; 11731 11732 for (auto &It : Values) { 11733 Value *V = It.getValue(); 11734 std::optional<Value *> CallerV = A.translateArgumentToCallSiteContent( 11735 V, *CB, *this, UsedAssumedInformation); 11736 if (!CallerV.has_value()) { 11737 // Nothing to do as long as no value was determined. 11738 continue; 11739 } 11740 V = *CallerV ? *CallerV : V; 11741 if (*CallerV && AA::isDynamicallyUnique(A, *this, *V)) { 11742 if (recurseForValue(A, IRPosition::value(*V), S)) 11743 continue; 11744 } 11745 if (S == AA::Intraprocedural && !AA::isValidInScope(*V, Caller)) { 11746 giveUpOnIntraprocedural(A); 11747 return true; 11748 } 11749 addValue(A, getState(), *V, CB, S, getAnchorScope()); 11750 } 11751 return true; 11752 }; 11753 if (!AddScope(AA::Intraprocedural)) 11754 return indicatePessimisticFixpoint(); 11755 if (!AddScope(AA::Interprocedural)) 11756 return indicatePessimisticFixpoint(); 11757 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED 11758 : ChangeStatus::CHANGED; 11759 } 11760 11761 ChangeStatus indicatePessimisticFixpoint() override { 11762 return AAPotentialValues::indicatePessimisticFixpoint(); 11763 } 11764 11765 /// See AbstractAttribute::trackStatistics() 11766 void trackStatistics() const override { 11767 STATS_DECLTRACK_CSRET_ATTR(potential_values) 11768 } 11769 }; 11770 11771 struct AAPotentialValuesCallSiteArgument : AAPotentialValuesFloating { 11772 AAPotentialValuesCallSiteArgument(const IRPosition &IRP, Attributor &A) 11773 : AAPotentialValuesFloating(IRP, A) {} 11774 11775 /// See AbstractAttribute::trackStatistics() 11776 void trackStatistics() const override { 11777 STATS_DECLTRACK_CSARG_ATTR(potential_values) 11778 } 11779 }; 11780 } // namespace 11781 11782 /// ---------------------- Assumption Propagation ------------------------------ 11783 namespace { 11784 struct AAAssumptionInfoImpl : public AAAssumptionInfo { 11785 AAAssumptionInfoImpl(const IRPosition &IRP, Attributor &A, 11786 const DenseSet<StringRef> &Known) 11787 : AAAssumptionInfo(IRP, A, Known) {} 11788 11789 /// See AbstractAttribute::manifest(...). 11790 ChangeStatus manifest(Attributor &A) override { 11791 // Don't manifest a universal set if it somehow made it here. 11792 if (getKnown().isUniversal()) 11793 return ChangeStatus::UNCHANGED; 11794 11795 const IRPosition &IRP = getIRPosition(); 11796 SmallVector<StringRef, 0> Set(getAssumed().getSet().begin(), 11797 getAssumed().getSet().end()); 11798 llvm::sort(Set); 11799 return A.manifestAttrs(IRP, 11800 Attribute::get(IRP.getAnchorValue().getContext(), 11801 AssumptionAttrKey, 11802 llvm::join(Set, ",")), 11803 /*ForceReplace=*/true); 11804 } 11805 11806 bool hasAssumption(const StringRef Assumption) const override { 11807 return isValidState() && setContains(Assumption); 11808 } 11809 11810 /// See AbstractAttribute::getAsStr() 11811 const std::string getAsStr(Attributor *A) const override { 11812 const SetContents &Known = getKnown(); 11813 const SetContents &Assumed = getAssumed(); 11814 11815 SmallVector<StringRef, 0> Set(Known.getSet().begin(), Known.getSet().end()); 11816 llvm::sort(Set); 11817 const std::string KnownStr = llvm::join(Set, ","); 11818 11819 std::string AssumedStr = "Universal"; 11820 if (!Assumed.isUniversal()) { 11821 Set.assign(Assumed.getSet().begin(), Assumed.getSet().end()); 11822 AssumedStr = llvm::join(Set, ","); 11823 } 11824 return "Known [" + KnownStr + "]," + " Assumed [" + AssumedStr + "]"; 11825 } 11826 }; 11827 11828 /// Propagates assumption information from parent functions to all of their 11829 /// successors. An assumption can be propagated if the containing function 11830 /// dominates the called function. 11831 /// 11832 /// We start with a "known" set of assumptions already valid for the associated 11833 /// function and an "assumed" set that initially contains all possible 11834 /// assumptions. The assumed set is inter-procedurally updated by narrowing its 11835 /// contents as concrete values are known. The concrete values are seeded by the 11836 /// first nodes that are either entries into the call graph, or contains no 11837 /// assumptions. Each node is updated as the intersection of the assumed state 11838 /// with all of its predecessors. 11839 struct AAAssumptionInfoFunction final : AAAssumptionInfoImpl { 11840 AAAssumptionInfoFunction(const IRPosition &IRP, Attributor &A) 11841 : AAAssumptionInfoImpl(IRP, A, 11842 getAssumptions(*IRP.getAssociatedFunction())) {} 11843 11844 /// See AbstractAttribute::updateImpl(...). 11845 ChangeStatus updateImpl(Attributor &A) override { 11846 bool Changed = false; 11847 11848 auto CallSitePred = [&](AbstractCallSite ACS) { 11849 const auto *AssumptionAA = A.getAAFor<AAAssumptionInfo>( 11850 *this, IRPosition::callsite_function(*ACS.getInstruction()), 11851 DepClassTy::REQUIRED); 11852 if (!AssumptionAA) 11853 return false; 11854 // Get the set of assumptions shared by all of this function's callers. 11855 Changed |= getIntersection(AssumptionAA->getAssumed()); 11856 return !getAssumed().empty() || !getKnown().empty(); 11857 }; 11858 11859 bool UsedAssumedInformation = false; 11860 // Get the intersection of all assumptions held by this node's predecessors. 11861 // If we don't know all the call sites then this is either an entry into the 11862 // call graph or an empty node. This node is known to only contain its own 11863 // assumptions and can be propagated to its successors. 11864 if (!A.checkForAllCallSites(CallSitePred, *this, true, 11865 UsedAssumedInformation)) 11866 return indicatePessimisticFixpoint(); 11867 11868 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 11869 } 11870 11871 void trackStatistics() const override {} 11872 }; 11873 11874 /// Assumption Info defined for call sites. 11875 struct AAAssumptionInfoCallSite final : AAAssumptionInfoImpl { 11876 11877 AAAssumptionInfoCallSite(const IRPosition &IRP, Attributor &A) 11878 : AAAssumptionInfoImpl(IRP, A, getInitialAssumptions(IRP)) {} 11879 11880 /// See AbstractAttribute::initialize(...). 11881 void initialize(Attributor &A) override { 11882 const IRPosition &FnPos = IRPosition::function(*getAnchorScope()); 11883 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED); 11884 } 11885 11886 /// See AbstractAttribute::updateImpl(...). 11887 ChangeStatus updateImpl(Attributor &A) override { 11888 const IRPosition &FnPos = IRPosition::function(*getAnchorScope()); 11889 auto *AssumptionAA = 11890 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED); 11891 if (!AssumptionAA) 11892 return indicatePessimisticFixpoint(); 11893 bool Changed = getIntersection(AssumptionAA->getAssumed()); 11894 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 11895 } 11896 11897 /// See AbstractAttribute::trackStatistics() 11898 void trackStatistics() const override {} 11899 11900 private: 11901 /// Helper to initialized the known set as all the assumptions this call and 11902 /// the callee contain. 11903 DenseSet<StringRef> getInitialAssumptions(const IRPosition &IRP) { 11904 const CallBase &CB = cast<CallBase>(IRP.getAssociatedValue()); 11905 auto Assumptions = getAssumptions(CB); 11906 if (const Function *F = CB.getCaller()) 11907 set_union(Assumptions, getAssumptions(*F)); 11908 if (Function *F = IRP.getAssociatedFunction()) 11909 set_union(Assumptions, getAssumptions(*F)); 11910 return Assumptions; 11911 } 11912 }; 11913 } // namespace 11914 11915 AACallGraphNode *AACallEdgeIterator::operator*() const { 11916 return static_cast<AACallGraphNode *>(const_cast<AACallEdges *>( 11917 A.getOrCreateAAFor<AACallEdges>(IRPosition::function(**I)))); 11918 } 11919 11920 void AttributorCallGraph::print() { llvm::WriteGraph(outs(), this); } 11921 11922 /// ------------------------ UnderlyingObjects --------------------------------- 11923 11924 namespace { 11925 struct AAUnderlyingObjectsImpl 11926 : StateWrapper<BooleanState, AAUnderlyingObjects> { 11927 using BaseTy = StateWrapper<BooleanState, AAUnderlyingObjects>; 11928 AAUnderlyingObjectsImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {} 11929 11930 /// See AbstractAttribute::getAsStr(). 11931 const std::string getAsStr(Attributor *A) const override { 11932 if (!isValidState()) 11933 return "<invalid>"; 11934 std::string Str; 11935 llvm::raw_string_ostream OS(Str); 11936 OS << "underlying objects: inter " << InterAssumedUnderlyingObjects.size() 11937 << " objects, intra " << IntraAssumedUnderlyingObjects.size() 11938 << " objects.\n"; 11939 if (!InterAssumedUnderlyingObjects.empty()) { 11940 OS << "inter objects:\n"; 11941 for (auto *Obj : InterAssumedUnderlyingObjects) 11942 OS << *Obj << '\n'; 11943 } 11944 if (!IntraAssumedUnderlyingObjects.empty()) { 11945 OS << "intra objects:\n"; 11946 for (auto *Obj : IntraAssumedUnderlyingObjects) 11947 OS << *Obj << '\n'; 11948 } 11949 return Str; 11950 } 11951 11952 /// See AbstractAttribute::trackStatistics() 11953 void trackStatistics() const override {} 11954 11955 /// See AbstractAttribute::updateImpl(...). 11956 ChangeStatus updateImpl(Attributor &A) override { 11957 auto &Ptr = getAssociatedValue(); 11958 11959 bool UsedAssumedInformation = false; 11960 auto DoUpdate = [&](SmallSetVector<Value *, 8> &UnderlyingObjects, 11961 AA::ValueScope Scope) { 11962 SmallPtrSet<Value *, 8> SeenObjects; 11963 SmallVector<AA::ValueAndContext> Values; 11964 11965 if (!A.getAssumedSimplifiedValues(IRPosition::value(Ptr), *this, Values, 11966 Scope, UsedAssumedInformation)) 11967 return UnderlyingObjects.insert(&Ptr); 11968 11969 bool Changed = false; 11970 11971 for (unsigned I = 0; I < Values.size(); ++I) { 11972 auto &VAC = Values[I]; 11973 auto *Obj = VAC.getValue(); 11974 Value *UO = getUnderlyingObject(Obj); 11975 if (!SeenObjects.insert(UO ? UO : Obj).second) 11976 continue; 11977 if (UO && UO != Obj) { 11978 if (isa<AllocaInst>(UO) || isa<GlobalValue>(UO)) { 11979 Changed |= UnderlyingObjects.insert(UO); 11980 continue; 11981 } 11982 11983 const auto *OtherAA = A.getAAFor<AAUnderlyingObjects>( 11984 *this, IRPosition::value(*UO), DepClassTy::OPTIONAL); 11985 auto Pred = [&](Value &V) { 11986 if (&V == UO) 11987 Changed |= UnderlyingObjects.insert(UO); 11988 else 11989 Values.emplace_back(V, nullptr); 11990 return true; 11991 }; 11992 11993 if (!OtherAA || !OtherAA->forallUnderlyingObjects(Pred, Scope)) 11994 llvm_unreachable( 11995 "The forall call should not return false at this position"); 11996 UsedAssumedInformation |= !OtherAA->getState().isAtFixpoint(); 11997 continue; 11998 } 11999 12000 if (isa<SelectInst>(Obj)) { 12001 Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope, 12002 UsedAssumedInformation); 12003 continue; 12004 } 12005 if (auto *PHI = dyn_cast<PHINode>(Obj)) { 12006 // Explicitly look through PHIs as we do not care about dynamically 12007 // uniqueness. 12008 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) { 12009 Changed |= 12010 handleIndirect(A, *PHI->getIncomingValue(u), UnderlyingObjects, 12011 Scope, UsedAssumedInformation); 12012 } 12013 continue; 12014 } 12015 12016 Changed |= UnderlyingObjects.insert(Obj); 12017 } 12018 12019 return Changed; 12020 }; 12021 12022 bool Changed = false; 12023 Changed |= DoUpdate(IntraAssumedUnderlyingObjects, AA::Intraprocedural); 12024 Changed |= DoUpdate(InterAssumedUnderlyingObjects, AA::Interprocedural); 12025 if (!UsedAssumedInformation) 12026 indicateOptimisticFixpoint(); 12027 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 12028 } 12029 12030 bool forallUnderlyingObjects( 12031 function_ref<bool(Value &)> Pred, 12032 AA::ValueScope Scope = AA::Interprocedural) const override { 12033 if (!isValidState()) 12034 return Pred(getAssociatedValue()); 12035 12036 auto &AssumedUnderlyingObjects = Scope == AA::Intraprocedural 12037 ? IntraAssumedUnderlyingObjects 12038 : InterAssumedUnderlyingObjects; 12039 for (Value *Obj : AssumedUnderlyingObjects) 12040 if (!Pred(*Obj)) 12041 return false; 12042 12043 return true; 12044 } 12045 12046 private: 12047 /// Handle the case where the value is not the actual underlying value, such 12048 /// as a phi node or a select instruction. 12049 bool handleIndirect(Attributor &A, Value &V, 12050 SmallSetVector<Value *, 8> &UnderlyingObjects, 12051 AA::ValueScope Scope, bool &UsedAssumedInformation) { 12052 bool Changed = false; 12053 const auto *AA = A.getAAFor<AAUnderlyingObjects>( 12054 *this, IRPosition::value(V), DepClassTy::OPTIONAL); 12055 auto Pred = [&](Value &V) { 12056 Changed |= UnderlyingObjects.insert(&V); 12057 return true; 12058 }; 12059 if (!AA || !AA->forallUnderlyingObjects(Pred, Scope)) 12060 llvm_unreachable( 12061 "The forall call should not return false at this position"); 12062 UsedAssumedInformation |= !AA->getState().isAtFixpoint(); 12063 return Changed; 12064 } 12065 12066 /// All the underlying objects collected so far via intra procedural scope. 12067 SmallSetVector<Value *, 8> IntraAssumedUnderlyingObjects; 12068 /// All the underlying objects collected so far via inter procedural scope. 12069 SmallSetVector<Value *, 8> InterAssumedUnderlyingObjects; 12070 }; 12071 12072 struct AAUnderlyingObjectsFloating final : AAUnderlyingObjectsImpl { 12073 AAUnderlyingObjectsFloating(const IRPosition &IRP, Attributor &A) 12074 : AAUnderlyingObjectsImpl(IRP, A) {} 12075 }; 12076 12077 struct AAUnderlyingObjectsArgument final : AAUnderlyingObjectsImpl { 12078 AAUnderlyingObjectsArgument(const IRPosition &IRP, Attributor &A) 12079 : AAUnderlyingObjectsImpl(IRP, A) {} 12080 }; 12081 12082 struct AAUnderlyingObjectsCallSite final : AAUnderlyingObjectsImpl { 12083 AAUnderlyingObjectsCallSite(const IRPosition &IRP, Attributor &A) 12084 : AAUnderlyingObjectsImpl(IRP, A) {} 12085 }; 12086 12087 struct AAUnderlyingObjectsCallSiteArgument final : AAUnderlyingObjectsImpl { 12088 AAUnderlyingObjectsCallSiteArgument(const IRPosition &IRP, Attributor &A) 12089 : AAUnderlyingObjectsImpl(IRP, A) {} 12090 }; 12091 12092 struct AAUnderlyingObjectsReturned final : AAUnderlyingObjectsImpl { 12093 AAUnderlyingObjectsReturned(const IRPosition &IRP, Attributor &A) 12094 : AAUnderlyingObjectsImpl(IRP, A) {} 12095 }; 12096 12097 struct AAUnderlyingObjectsCallSiteReturned final : AAUnderlyingObjectsImpl { 12098 AAUnderlyingObjectsCallSiteReturned(const IRPosition &IRP, Attributor &A) 12099 : AAUnderlyingObjectsImpl(IRP, A) {} 12100 }; 12101 12102 struct AAUnderlyingObjectsFunction final : AAUnderlyingObjectsImpl { 12103 AAUnderlyingObjectsFunction(const IRPosition &IRP, Attributor &A) 12104 : AAUnderlyingObjectsImpl(IRP, A) {} 12105 }; 12106 } // namespace 12107 12108 /// ------------------------ Global Value Info ------------------------------- 12109 namespace { 12110 struct AAGlobalValueInfoFloating : public AAGlobalValueInfo { 12111 AAGlobalValueInfoFloating(const IRPosition &IRP, Attributor &A) 12112 : AAGlobalValueInfo(IRP, A) {} 12113 12114 /// See AbstractAttribute::initialize(...). 12115 void initialize(Attributor &A) override {} 12116 12117 bool checkUse(Attributor &A, const Use &U, bool &Follow, 12118 SmallVectorImpl<const Value *> &Worklist) { 12119 Instruction *UInst = dyn_cast<Instruction>(U.getUser()); 12120 if (!UInst) { 12121 Follow = true; 12122 return true; 12123 } 12124 12125 LLVM_DEBUG(dbgs() << "[AAGlobalValueInfo] Check use: " << *U.get() << " in " 12126 << *UInst << "\n"); 12127 12128 if (auto *Cmp = dyn_cast<ICmpInst>(U.getUser())) { 12129 int Idx = &Cmp->getOperandUse(0) == &U; 12130 if (isa<Constant>(Cmp->getOperand(Idx))) 12131 return true; 12132 return U == &getAnchorValue(); 12133 } 12134 12135 // Explicitly catch return instructions. 12136 if (isa<ReturnInst>(UInst)) { 12137 auto CallSitePred = [&](AbstractCallSite ACS) { 12138 Worklist.push_back(ACS.getInstruction()); 12139 return true; 12140 }; 12141 bool UsedAssumedInformation = false; 12142 // TODO: We should traverse the uses or add a "non-call-site" CB. 12143 if (!A.checkForAllCallSites(CallSitePred, *UInst->getFunction(), 12144 /*RequireAllCallSites=*/true, this, 12145 UsedAssumedInformation)) 12146 return false; 12147 return true; 12148 } 12149 12150 // For now we only use special logic for call sites. However, the tracker 12151 // itself knows about a lot of other non-capturing cases already. 12152 auto *CB = dyn_cast<CallBase>(UInst); 12153 if (!CB) 12154 return false; 12155 // Direct calls are OK uses. 12156 if (CB->isCallee(&U)) 12157 return true; 12158 // Non-argument uses are scary. 12159 if (!CB->isArgOperand(&U)) 12160 return false; 12161 // TODO: Iterate callees. 12162 auto *Fn = dyn_cast<Function>(CB->getCalledOperand()); 12163 if (!Fn || !A.isFunctionIPOAmendable(*Fn)) 12164 return false; 12165 12166 unsigned ArgNo = CB->getArgOperandNo(&U); 12167 Worklist.push_back(Fn->getArg(ArgNo)); 12168 return true; 12169 } 12170 12171 ChangeStatus updateImpl(Attributor &A) override { 12172 unsigned NumUsesBefore = Uses.size(); 12173 12174 SmallPtrSet<const Value *, 8> Visited; 12175 SmallVector<const Value *> Worklist; 12176 Worklist.push_back(&getAnchorValue()); 12177 12178 auto UsePred = [&](const Use &U, bool &Follow) -> bool { 12179 Uses.insert(&U); 12180 // TODO(captures): Make this more precise. 12181 UseCaptureInfo CI = DetermineUseCaptureKind(U, /*Base=*/nullptr); 12182 if (CI.isPassthrough()) { 12183 Follow = true; 12184 return true; 12185 } 12186 return checkUse(A, U, Follow, Worklist); 12187 }; 12188 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) { 12189 Uses.insert(&OldU); 12190 return true; 12191 }; 12192 12193 while (!Worklist.empty()) { 12194 const Value *V = Worklist.pop_back_val(); 12195 if (!Visited.insert(V).second) 12196 continue; 12197 if (!A.checkForAllUses(UsePred, *this, *V, 12198 /* CheckBBLivenessOnly */ true, 12199 DepClassTy::OPTIONAL, 12200 /* IgnoreDroppableUses */ true, EquivalentUseCB)) { 12201 return indicatePessimisticFixpoint(); 12202 } 12203 } 12204 12205 return Uses.size() == NumUsesBefore ? ChangeStatus::UNCHANGED 12206 : ChangeStatus::CHANGED; 12207 } 12208 12209 bool isPotentialUse(const Use &U) const override { 12210 return !isValidState() || Uses.contains(&U); 12211 } 12212 12213 /// See AbstractAttribute::manifest(...). 12214 ChangeStatus manifest(Attributor &A) override { 12215 return ChangeStatus::UNCHANGED; 12216 } 12217 12218 /// See AbstractAttribute::getAsStr(). 12219 const std::string getAsStr(Attributor *A) const override { 12220 return "[" + std::to_string(Uses.size()) + " uses]"; 12221 } 12222 12223 void trackStatistics() const override { 12224 STATS_DECLTRACK_FLOATING_ATTR(GlobalValuesTracked); 12225 } 12226 12227 private: 12228 /// Set of (transitive) uses of this GlobalValue. 12229 SmallPtrSet<const Use *, 8> Uses; 12230 }; 12231 } // namespace 12232 12233 /// ------------------------ Indirect Call Info ------------------------------- 12234 namespace { 12235 struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo { 12236 AAIndirectCallInfoCallSite(const IRPosition &IRP, Attributor &A) 12237 : AAIndirectCallInfo(IRP, A) {} 12238 12239 /// See AbstractAttribute::initialize(...). 12240 void initialize(Attributor &A) override { 12241 auto *MD = getCtxI()->getMetadata(LLVMContext::MD_callees); 12242 if (!MD && !A.isClosedWorldModule()) 12243 return; 12244 12245 if (MD) { 12246 for (const auto &Op : MD->operands()) 12247 if (Function *Callee = mdconst::dyn_extract_or_null<Function>(Op)) 12248 PotentialCallees.insert(Callee); 12249 } else if (A.isClosedWorldModule()) { 12250 ArrayRef<Function *> IndirectlyCallableFunctions = 12251 A.getInfoCache().getIndirectlyCallableFunctions(A); 12252 PotentialCallees.insert_range(IndirectlyCallableFunctions); 12253 } 12254 12255 if (PotentialCallees.empty()) 12256 indicateOptimisticFixpoint(); 12257 } 12258 12259 ChangeStatus updateImpl(Attributor &A) override { 12260 CallBase *CB = cast<CallBase>(getCtxI()); 12261 const Use &CalleeUse = CB->getCalledOperandUse(); 12262 Value *FP = CB->getCalledOperand(); 12263 12264 SmallSetVector<Function *, 4> AssumedCalleesNow; 12265 bool AllCalleesKnownNow = AllCalleesKnown; 12266 12267 auto CheckPotentialCalleeUse = [&](Function &PotentialCallee, 12268 bool &UsedAssumedInformation) { 12269 const auto *GIAA = A.getAAFor<AAGlobalValueInfo>( 12270 *this, IRPosition::value(PotentialCallee), DepClassTy::OPTIONAL); 12271 if (!GIAA || GIAA->isPotentialUse(CalleeUse)) 12272 return true; 12273 UsedAssumedInformation = !GIAA->isAtFixpoint(); 12274 return false; 12275 }; 12276 12277 auto AddPotentialCallees = [&]() { 12278 for (auto *PotentialCallee : PotentialCallees) { 12279 bool UsedAssumedInformation = false; 12280 if (CheckPotentialCalleeUse(*PotentialCallee, UsedAssumedInformation)) 12281 AssumedCalleesNow.insert(PotentialCallee); 12282 } 12283 }; 12284 12285 // Use simplification to find potential callees, if !callees was present, 12286 // fallback to that set if necessary. 12287 bool UsedAssumedInformation = false; 12288 SmallVector<AA::ValueAndContext> Values; 12289 if (!A.getAssumedSimplifiedValues(IRPosition::value(*FP), this, Values, 12290 AA::ValueScope::AnyScope, 12291 UsedAssumedInformation)) { 12292 if (PotentialCallees.empty()) 12293 return indicatePessimisticFixpoint(); 12294 AddPotentialCallees(); 12295 } 12296 12297 // Try to find a reason for \p Fn not to be a potential callee. If none was 12298 // found, add it to the assumed callees set. 12299 auto CheckPotentialCallee = [&](Function &Fn) { 12300 if (!PotentialCallees.empty() && !PotentialCallees.count(&Fn)) 12301 return false; 12302 12303 auto &CachedResult = FilterResults[&Fn]; 12304 if (CachedResult.has_value()) 12305 return CachedResult.value(); 12306 12307 bool UsedAssumedInformation = false; 12308 if (!CheckPotentialCalleeUse(Fn, UsedAssumedInformation)) { 12309 if (!UsedAssumedInformation) 12310 CachedResult = false; 12311 return false; 12312 } 12313 12314 int NumFnArgs = Fn.arg_size(); 12315 int NumCBArgs = CB->arg_size(); 12316 12317 // Check if any excess argument (which we fill up with poison) is known to 12318 // be UB on undef. 12319 for (int I = NumCBArgs; I < NumFnArgs; ++I) { 12320 bool IsKnown = false; 12321 if (AA::hasAssumedIRAttr<Attribute::NoUndef>( 12322 A, this, IRPosition::argument(*Fn.getArg(I)), 12323 DepClassTy::OPTIONAL, IsKnown)) { 12324 if (IsKnown) 12325 CachedResult = false; 12326 return false; 12327 } 12328 } 12329 12330 CachedResult = true; 12331 return true; 12332 }; 12333 12334 // Check simplification result, prune known UB callees, also restrict it to 12335 // the !callees set, if present. 12336 for (auto &VAC : Values) { 12337 if (isa<UndefValue>(VAC.getValue())) 12338 continue; 12339 if (isa<ConstantPointerNull>(VAC.getValue()) && 12340 VAC.getValue()->getType()->getPointerAddressSpace() == 0) 12341 continue; 12342 // TODO: Check for known UB, e.g., poison + noundef. 12343 if (auto *VACFn = dyn_cast<Function>(VAC.getValue())) { 12344 if (CheckPotentialCallee(*VACFn)) 12345 AssumedCalleesNow.insert(VACFn); 12346 continue; 12347 } 12348 if (!PotentialCallees.empty()) { 12349 AddPotentialCallees(); 12350 break; 12351 } 12352 AllCalleesKnownNow = false; 12353 } 12354 12355 if (AssumedCalleesNow == AssumedCallees && 12356 AllCalleesKnown == AllCalleesKnownNow) 12357 return ChangeStatus::UNCHANGED; 12358 12359 std::swap(AssumedCallees, AssumedCalleesNow); 12360 AllCalleesKnown = AllCalleesKnownNow; 12361 return ChangeStatus::CHANGED; 12362 } 12363 12364 /// See AbstractAttribute::manifest(...). 12365 ChangeStatus manifest(Attributor &A) override { 12366 // If we can't specialize at all, give up now. 12367 if (!AllCalleesKnown && AssumedCallees.empty()) 12368 return ChangeStatus::UNCHANGED; 12369 12370 CallBase *CB = cast<CallBase>(getCtxI()); 12371 bool UsedAssumedInformation = false; 12372 if (A.isAssumedDead(*CB, this, /*LivenessAA=*/nullptr, 12373 UsedAssumedInformation)) 12374 return ChangeStatus::UNCHANGED; 12375 12376 ChangeStatus Changed = ChangeStatus::UNCHANGED; 12377 Value *FP = CB->getCalledOperand(); 12378 if (FP->getType()->getPointerAddressSpace()) 12379 FP = new AddrSpaceCastInst(FP, PointerType::get(FP->getContext(), 0), 12380 FP->getName() + ".as0", CB->getIterator()); 12381 12382 bool CBIsVoid = CB->getType()->isVoidTy(); 12383 BasicBlock::iterator IP = CB->getIterator(); 12384 FunctionType *CSFT = CB->getFunctionType(); 12385 SmallVector<Value *> CSArgs(CB->args()); 12386 12387 // If we know all callees and there are none, the call site is (effectively) 12388 // dead (or UB). 12389 if (AssumedCallees.empty()) { 12390 assert(AllCalleesKnown && 12391 "Expected all callees to be known if there are none."); 12392 A.changeToUnreachableAfterManifest(CB); 12393 return ChangeStatus::CHANGED; 12394 } 12395 12396 // Special handling for the single callee case. 12397 if (AllCalleesKnown && AssumedCallees.size() == 1) { 12398 auto *NewCallee = AssumedCallees.front(); 12399 if (isLegalToPromote(*CB, NewCallee)) { 12400 promoteCall(*CB, NewCallee, nullptr); 12401 NumIndirectCallsPromoted++; 12402 return ChangeStatus::CHANGED; 12403 } 12404 Instruction *NewCall = 12405 CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs, 12406 CB->getName(), CB->getIterator()); 12407 if (!CBIsVoid) 12408 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *NewCall); 12409 A.deleteAfterManifest(*CB); 12410 return ChangeStatus::CHANGED; 12411 } 12412 12413 // For each potential value we create a conditional 12414 // 12415 // ``` 12416 // if (ptr == value) value(args); 12417 // else ... 12418 // ``` 12419 // 12420 bool SpecializedForAnyCallees = false; 12421 bool SpecializedForAllCallees = AllCalleesKnown; 12422 ICmpInst *LastCmp = nullptr; 12423 SmallVector<Function *, 8> SkippedAssumedCallees; 12424 SmallVector<std::pair<CallInst *, Instruction *>> NewCalls; 12425 for (Function *NewCallee : AssumedCallees) { 12426 if (!A.shouldSpecializeCallSiteForCallee(*this, *CB, *NewCallee, 12427 AssumedCallees.size())) { 12428 SkippedAssumedCallees.push_back(NewCallee); 12429 SpecializedForAllCallees = false; 12430 continue; 12431 } 12432 SpecializedForAnyCallees = true; 12433 12434 LastCmp = new ICmpInst(IP, llvm::CmpInst::ICMP_EQ, FP, NewCallee); 12435 Instruction *ThenTI = 12436 SplitBlockAndInsertIfThen(LastCmp, IP, /* Unreachable */ false); 12437 BasicBlock *CBBB = CB->getParent(); 12438 A.registerManifestAddedBasicBlock(*ThenTI->getParent()); 12439 A.registerManifestAddedBasicBlock(*IP->getParent()); 12440 auto *SplitTI = cast<BranchInst>(LastCmp->getNextNode()); 12441 BasicBlock *ElseBB; 12442 if (&*IP == CB) { 12443 ElseBB = BasicBlock::Create(ThenTI->getContext(), "", 12444 ThenTI->getFunction(), CBBB); 12445 A.registerManifestAddedBasicBlock(*ElseBB); 12446 IP = BranchInst::Create(CBBB, ElseBB)->getIterator(); 12447 SplitTI->replaceUsesOfWith(CBBB, ElseBB); 12448 } else { 12449 ElseBB = IP->getParent(); 12450 ThenTI->replaceUsesOfWith(ElseBB, CBBB); 12451 } 12452 CastInst *RetBC = nullptr; 12453 CallInst *NewCall = nullptr; 12454 if (isLegalToPromote(*CB, NewCallee)) { 12455 auto *CBClone = cast<CallBase>(CB->clone()); 12456 CBClone->insertBefore(ThenTI->getIterator()); 12457 NewCall = &cast<CallInst>(promoteCall(*CBClone, NewCallee, &RetBC)); 12458 NumIndirectCallsPromoted++; 12459 } else { 12460 NewCall = CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs, 12461 CB->getName(), ThenTI->getIterator()); 12462 } 12463 NewCalls.push_back({NewCall, RetBC}); 12464 } 12465 12466 auto AttachCalleeMetadata = [&](CallBase &IndirectCB) { 12467 if (!AllCalleesKnown) 12468 return ChangeStatus::UNCHANGED; 12469 MDBuilder MDB(IndirectCB.getContext()); 12470 MDNode *Callees = MDB.createCallees(SkippedAssumedCallees); 12471 IndirectCB.setMetadata(LLVMContext::MD_callees, Callees); 12472 return ChangeStatus::CHANGED; 12473 }; 12474 12475 if (!SpecializedForAnyCallees) 12476 return AttachCalleeMetadata(*CB); 12477 12478 // Check if we need the fallback indirect call still. 12479 if (SpecializedForAllCallees) { 12480 LastCmp->replaceAllUsesWith(ConstantInt::getTrue(LastCmp->getContext())); 12481 LastCmp->eraseFromParent(); 12482 new UnreachableInst(IP->getContext(), IP); 12483 IP->eraseFromParent(); 12484 } else { 12485 auto *CBClone = cast<CallInst>(CB->clone()); 12486 CBClone->setName(CB->getName()); 12487 CBClone->insertBefore(*IP->getParent(), IP); 12488 NewCalls.push_back({CBClone, nullptr}); 12489 AttachCalleeMetadata(*CBClone); 12490 } 12491 12492 // Check if we need a PHI to merge the results. 12493 if (!CBIsVoid) { 12494 auto *PHI = PHINode::Create(CB->getType(), NewCalls.size(), 12495 CB->getName() + ".phi", 12496 CB->getParent()->getFirstInsertionPt()); 12497 for (auto &It : NewCalls) { 12498 CallBase *NewCall = It.first; 12499 Instruction *CallRet = It.second ? It.second : It.first; 12500 if (CallRet->getType() == CB->getType()) 12501 PHI->addIncoming(CallRet, CallRet->getParent()); 12502 else if (NewCall->getType()->isVoidTy()) 12503 PHI->addIncoming(PoisonValue::get(CB->getType()), 12504 NewCall->getParent()); 12505 else 12506 llvm_unreachable("Call return should match or be void!"); 12507 } 12508 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *PHI); 12509 } 12510 12511 A.deleteAfterManifest(*CB); 12512 Changed = ChangeStatus::CHANGED; 12513 12514 return Changed; 12515 } 12516 12517 /// See AbstractAttribute::getAsStr(). 12518 const std::string getAsStr(Attributor *A) const override { 12519 return std::string(AllCalleesKnown ? "eliminate" : "specialize") + 12520 " indirect call site with " + std::to_string(AssumedCallees.size()) + 12521 " functions"; 12522 } 12523 12524 void trackStatistics() const override { 12525 if (AllCalleesKnown) { 12526 STATS_DECLTRACK( 12527 Eliminated, CallSites, 12528 "Number of indirect call sites eliminated via specialization") 12529 } else { 12530 STATS_DECLTRACK(Specialized, CallSites, 12531 "Number of indirect call sites specialized") 12532 } 12533 } 12534 12535 bool foreachCallee(function_ref<bool(Function *)> CB) const override { 12536 return isValidState() && AllCalleesKnown && all_of(AssumedCallees, CB); 12537 } 12538 12539 private: 12540 /// Map to remember filter results. 12541 DenseMap<Function *, std::optional<bool>> FilterResults; 12542 12543 /// If the !callee metadata was present, this set will contain all potential 12544 /// callees (superset). 12545 SmallSetVector<Function *, 4> PotentialCallees; 12546 12547 /// This set contains all currently assumed calllees, which might grow over 12548 /// time. 12549 SmallSetVector<Function *, 4> AssumedCallees; 12550 12551 /// Flag to indicate if all possible callees are in the AssumedCallees set or 12552 /// if there could be others. 12553 bool AllCalleesKnown = true; 12554 }; 12555 } // namespace 12556 12557 /// --------------------- Invariant Load Pointer ------------------------------- 12558 namespace { 12559 12560 struct AAInvariantLoadPointerImpl 12561 : public StateWrapper<BitIntegerState<uint8_t, 15>, 12562 AAInvariantLoadPointer> { 12563 12564 enum { 12565 // pointer does not alias within the bounds of the function 12566 IS_NOALIAS = 1 << 0, 12567 // pointer is not involved in any effectful instructions within the bounds 12568 // of the function 12569 IS_NOEFFECT = 1 << 1, 12570 // loads are invariant within the bounds of the function 12571 IS_LOCALLY_INVARIANT = 1 << 2, 12572 // memory lifetime is constrained within the bounds of the function 12573 IS_LOCALLY_CONSTRAINED = 1 << 3, 12574 12575 IS_BEST_STATE = IS_NOALIAS | IS_NOEFFECT | IS_LOCALLY_INVARIANT | 12576 IS_LOCALLY_CONSTRAINED, 12577 }; 12578 static_assert(getBestState() == IS_BEST_STATE, "Unexpected best state"); 12579 12580 using Base = 12581 StateWrapper<BitIntegerState<uint8_t, 15>, AAInvariantLoadPointer>; 12582 12583 // the BitIntegerState is optimistic about IS_NOALIAS and IS_NOEFFECT, but 12584 // pessimistic about IS_KNOWN_INVARIANT 12585 AAInvariantLoadPointerImpl(const IRPosition &IRP, Attributor &A) 12586 : Base(IRP) {} 12587 12588 bool isKnownInvariant() const final { 12589 return isKnownLocallyInvariant() && isKnown(IS_LOCALLY_CONSTRAINED); 12590 } 12591 12592 bool isKnownLocallyInvariant() const final { 12593 if (isKnown(IS_LOCALLY_INVARIANT)) 12594 return true; 12595 return isKnown(IS_NOALIAS | IS_NOEFFECT); 12596 } 12597 12598 bool isAssumedInvariant() const final { 12599 return isAssumedLocallyInvariant() && isAssumed(IS_LOCALLY_CONSTRAINED); 12600 } 12601 12602 bool isAssumedLocallyInvariant() const final { 12603 if (isAssumed(IS_LOCALLY_INVARIANT)) 12604 return true; 12605 return isAssumed(IS_NOALIAS | IS_NOEFFECT); 12606 } 12607 12608 ChangeStatus updateImpl(Attributor &A) override { 12609 ChangeStatus Changed = ChangeStatus::UNCHANGED; 12610 12611 Changed |= updateNoAlias(A); 12612 if (requiresNoAlias() && !isAssumed(IS_NOALIAS)) 12613 return indicatePessimisticFixpoint(); 12614 12615 Changed |= updateNoEffect(A); 12616 12617 Changed |= updateLocalInvariance(A); 12618 12619 return Changed; 12620 } 12621 12622 ChangeStatus manifest(Attributor &A) override { 12623 if (!isKnownInvariant()) 12624 return ChangeStatus::UNCHANGED; 12625 12626 ChangeStatus Changed = ChangeStatus::UNCHANGED; 12627 const Value *Ptr = &getAssociatedValue(); 12628 const auto TagInvariantLoads = [&](const Use &U, bool &) { 12629 if (U.get() != Ptr) 12630 return true; 12631 auto *I = dyn_cast<Instruction>(U.getUser()); 12632 if (!I) 12633 return true; 12634 12635 // Ensure that we are only changing uses from the corresponding callgraph 12636 // SSC in the case that the AA isn't run on the entire module 12637 if (!A.isRunOn(I->getFunction())) 12638 return true; 12639 12640 if (I->hasMetadata(LLVMContext::MD_invariant_load)) 12641 return true; 12642 12643 if (auto *LI = dyn_cast<LoadInst>(I)) { 12644 LI->setMetadata(LLVMContext::MD_invariant_load, 12645 MDNode::get(LI->getContext(), {})); 12646 Changed = ChangeStatus::CHANGED; 12647 } 12648 return true; 12649 }; 12650 12651 (void)A.checkForAllUses(TagInvariantLoads, *this, *Ptr); 12652 return Changed; 12653 } 12654 12655 /// See AbstractAttribute::getAsStr(). 12656 const std::string getAsStr(Attributor *) const override { 12657 if (isKnownInvariant()) 12658 return "load-invariant pointer"; 12659 return "non-invariant pointer"; 12660 } 12661 12662 /// See AbstractAttribute::trackStatistics(). 12663 void trackStatistics() const override {} 12664 12665 private: 12666 /// Indicate that noalias is required for the pointer to be invariant. 12667 bool requiresNoAlias() const { 12668 switch (getPositionKind()) { 12669 default: 12670 // Conservatively default to require noalias. 12671 return true; 12672 case IRP_FLOAT: 12673 case IRP_RETURNED: 12674 case IRP_CALL_SITE: 12675 return false; 12676 case IRP_CALL_SITE_RETURNED: { 12677 const auto &CB = cast<CallBase>(getAnchorValue()); 12678 return !isIntrinsicReturningPointerAliasingArgumentWithoutCapturing( 12679 &CB, /*MustPreserveNullness=*/false); 12680 } 12681 case IRP_ARGUMENT: { 12682 const Function *F = getAssociatedFunction(); 12683 assert(F && "no associated function for argument"); 12684 return !isCallableCC(F->getCallingConv()); 12685 } 12686 } 12687 } 12688 12689 bool isExternal() const { 12690 const Function *F = getAssociatedFunction(); 12691 if (!F) 12692 return true; 12693 return isCallableCC(F->getCallingConv()) && 12694 getPositionKind() != IRP_CALL_SITE_RETURNED; 12695 } 12696 12697 ChangeStatus updateNoAlias(Attributor &A) { 12698 if (isKnown(IS_NOALIAS) || !isAssumed(IS_NOALIAS)) 12699 return ChangeStatus::UNCHANGED; 12700 12701 // Try to use AANoAlias. 12702 if (const auto *ANoAlias = A.getOrCreateAAFor<AANoAlias>( 12703 getIRPosition(), this, DepClassTy::REQUIRED)) { 12704 if (ANoAlias->isKnownNoAlias()) { 12705 addKnownBits(IS_NOALIAS); 12706 return ChangeStatus::CHANGED; 12707 } 12708 12709 if (!ANoAlias->isAssumedNoAlias()) { 12710 removeAssumedBits(IS_NOALIAS); 12711 return ChangeStatus::CHANGED; 12712 } 12713 12714 return ChangeStatus::UNCHANGED; 12715 } 12716 12717 // Try to infer noalias from argument attribute, since it is applicable for 12718 // the duration of the function. 12719 if (const Argument *Arg = getAssociatedArgument()) { 12720 if (Arg->hasNoAliasAttr()) { 12721 addKnownBits(IS_NOALIAS); 12722 return ChangeStatus::UNCHANGED; 12723 } 12724 12725 // Noalias information is not provided, and cannot be inferred, 12726 // so we conservatively assume the pointer aliases. 12727 removeAssumedBits(IS_NOALIAS); 12728 return ChangeStatus::CHANGED; 12729 } 12730 12731 return ChangeStatus::UNCHANGED; 12732 } 12733 12734 ChangeStatus updateNoEffect(Attributor &A) { 12735 if (isKnown(IS_NOEFFECT) || !isAssumed(IS_NOEFFECT)) 12736 return ChangeStatus::UNCHANGED; 12737 12738 if (!getAssociatedFunction()) 12739 return indicatePessimisticFixpoint(); 12740 12741 if (isa<AllocaInst>(&getAssociatedValue())) 12742 return indicatePessimisticFixpoint(); 12743 12744 const auto HasNoEffectLoads = [&](const Use &U, bool &) { 12745 const auto *LI = dyn_cast<LoadInst>(U.getUser()); 12746 return !LI || !LI->mayHaveSideEffects(); 12747 }; 12748 if (!A.checkForAllUses(HasNoEffectLoads, *this, getAssociatedValue())) 12749 return indicatePessimisticFixpoint(); 12750 12751 if (const auto *AMemoryBehavior = A.getOrCreateAAFor<AAMemoryBehavior>( 12752 getIRPosition(), this, DepClassTy::REQUIRED)) { 12753 // For non-instructions, try to use AAMemoryBehavior to infer the readonly 12754 // attribute 12755 if (!AMemoryBehavior->isAssumedReadOnly()) 12756 return indicatePessimisticFixpoint(); 12757 12758 if (AMemoryBehavior->isKnownReadOnly()) { 12759 addKnownBits(IS_NOEFFECT); 12760 return ChangeStatus::UNCHANGED; 12761 } 12762 12763 return ChangeStatus::UNCHANGED; 12764 } 12765 12766 if (const Argument *Arg = getAssociatedArgument()) { 12767 if (Arg->onlyReadsMemory()) { 12768 addKnownBits(IS_NOEFFECT); 12769 return ChangeStatus::UNCHANGED; 12770 } 12771 12772 // Readonly information is not provided, and cannot be inferred from 12773 // AAMemoryBehavior. 12774 return indicatePessimisticFixpoint(); 12775 } 12776 12777 return ChangeStatus::UNCHANGED; 12778 } 12779 12780 ChangeStatus updateLocalInvariance(Attributor &A) { 12781 if (isKnown(IS_LOCALLY_INVARIANT) || !isAssumed(IS_LOCALLY_INVARIANT)) 12782 return ChangeStatus::UNCHANGED; 12783 12784 // try to infer invariance from underlying objects 12785 const auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>( 12786 getIRPosition(), this, DepClassTy::REQUIRED); 12787 if (!AUO) 12788 return ChangeStatus::UNCHANGED; 12789 12790 bool UsedAssumedInformation = false; 12791 const auto IsLocallyInvariantLoadIfPointer = [&](const Value &V) { 12792 if (!V.getType()->isPointerTy()) 12793 return true; 12794 const auto *IsInvariantLoadPointer = 12795 A.getOrCreateAAFor<AAInvariantLoadPointer>(IRPosition::value(V), this, 12796 DepClassTy::REQUIRED); 12797 // Conservatively fail if invariance cannot be inferred. 12798 if (!IsInvariantLoadPointer) 12799 return false; 12800 12801 if (IsInvariantLoadPointer->isKnownLocallyInvariant()) 12802 return true; 12803 if (!IsInvariantLoadPointer->isAssumedLocallyInvariant()) 12804 return false; 12805 12806 UsedAssumedInformation = true; 12807 return true; 12808 }; 12809 if (!AUO->forallUnderlyingObjects(IsLocallyInvariantLoadIfPointer)) 12810 return indicatePessimisticFixpoint(); 12811 12812 if (const auto *CB = dyn_cast<CallBase>(&getAnchorValue())) { 12813 if (isIntrinsicReturningPointerAliasingArgumentWithoutCapturing( 12814 CB, /*MustPreserveNullness=*/false)) { 12815 for (const Value *Arg : CB->args()) { 12816 if (!IsLocallyInvariantLoadIfPointer(*Arg)) 12817 return indicatePessimisticFixpoint(); 12818 } 12819 } 12820 } 12821 12822 if (!UsedAssumedInformation) { 12823 // Pointer is known and not just assumed to be locally invariant. 12824 addKnownBits(IS_LOCALLY_INVARIANT); 12825 return ChangeStatus::CHANGED; 12826 } 12827 12828 return ChangeStatus::UNCHANGED; 12829 } 12830 }; 12831 12832 struct AAInvariantLoadPointerFloating final : AAInvariantLoadPointerImpl { 12833 AAInvariantLoadPointerFloating(const IRPosition &IRP, Attributor &A) 12834 : AAInvariantLoadPointerImpl(IRP, A) {} 12835 }; 12836 12837 struct AAInvariantLoadPointerReturned final : AAInvariantLoadPointerImpl { 12838 AAInvariantLoadPointerReturned(const IRPosition &IRP, Attributor &A) 12839 : AAInvariantLoadPointerImpl(IRP, A) {} 12840 12841 void initialize(Attributor &) override { 12842 removeAssumedBits(IS_LOCALLY_CONSTRAINED); 12843 } 12844 }; 12845 12846 struct AAInvariantLoadPointerCallSiteReturned final 12847 : AAInvariantLoadPointerImpl { 12848 AAInvariantLoadPointerCallSiteReturned(const IRPosition &IRP, Attributor &A) 12849 : AAInvariantLoadPointerImpl(IRP, A) {} 12850 12851 void initialize(Attributor &A) override { 12852 const Function *F = getAssociatedFunction(); 12853 assert(F && "no associated function for return from call"); 12854 12855 if (!F->isDeclaration() && !F->isIntrinsic()) 12856 return AAInvariantLoadPointerImpl::initialize(A); 12857 12858 const auto &CB = cast<CallBase>(getAnchorValue()); 12859 if (isIntrinsicReturningPointerAliasingArgumentWithoutCapturing( 12860 &CB, /*MustPreserveNullness=*/false)) 12861 return AAInvariantLoadPointerImpl::initialize(A); 12862 12863 if (F->onlyReadsMemory() && F->hasNoSync()) 12864 return AAInvariantLoadPointerImpl::initialize(A); 12865 12866 // At this point, the function is opaque, so we conservatively assume 12867 // non-invariance. 12868 indicatePessimisticFixpoint(); 12869 } 12870 }; 12871 12872 struct AAInvariantLoadPointerArgument final : AAInvariantLoadPointerImpl { 12873 AAInvariantLoadPointerArgument(const IRPosition &IRP, Attributor &A) 12874 : AAInvariantLoadPointerImpl(IRP, A) {} 12875 12876 void initialize(Attributor &) override { 12877 const Function *F = getAssociatedFunction(); 12878 assert(F && "no associated function for argument"); 12879 12880 if (!isCallableCC(F->getCallingConv())) { 12881 addKnownBits(IS_LOCALLY_CONSTRAINED); 12882 return; 12883 } 12884 12885 if (!F->hasLocalLinkage()) 12886 removeAssumedBits(IS_LOCALLY_CONSTRAINED); 12887 } 12888 }; 12889 12890 struct AAInvariantLoadPointerCallSiteArgument final 12891 : AAInvariantLoadPointerImpl { 12892 AAInvariantLoadPointerCallSiteArgument(const IRPosition &IRP, Attributor &A) 12893 : AAInvariantLoadPointerImpl(IRP, A) {} 12894 }; 12895 } // namespace 12896 12897 /// ------------------------ Address Space ------------------------------------ 12898 namespace { 12899 12900 template <typename InstType> 12901 static bool makeChange(Attributor &A, InstType *MemInst, const Use &U, 12902 Value *OriginalValue, PointerType *NewPtrTy, 12903 bool UseOriginalValue) { 12904 if (U.getOperandNo() != InstType::getPointerOperandIndex()) 12905 return false; 12906 12907 if (MemInst->isVolatile()) { 12908 auto *TTI = A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>( 12909 *MemInst->getFunction()); 12910 unsigned NewAS = NewPtrTy->getPointerAddressSpace(); 12911 if (!TTI || !TTI->hasVolatileVariant(MemInst, NewAS)) 12912 return false; 12913 } 12914 12915 if (UseOriginalValue) { 12916 A.changeUseAfterManifest(const_cast<Use &>(U), *OriginalValue); 12917 return true; 12918 } 12919 12920 Instruction *CastInst = new AddrSpaceCastInst(OriginalValue, NewPtrTy); 12921 CastInst->insertBefore(MemInst->getIterator()); 12922 A.changeUseAfterManifest(const_cast<Use &>(U), *CastInst); 12923 return true; 12924 } 12925 12926 struct AAAddressSpaceImpl : public AAAddressSpace { 12927 AAAddressSpaceImpl(const IRPosition &IRP, Attributor &A) 12928 : AAAddressSpace(IRP, A) {} 12929 12930 uint32_t getAddressSpace() const override { 12931 assert(isValidState() && "the AA is invalid"); 12932 return AssumedAddressSpace; 12933 } 12934 12935 /// See AbstractAttribute::initialize(...). 12936 void initialize(Attributor &A) override { 12937 assert(getAssociatedType()->isPtrOrPtrVectorTy() && 12938 "Associated value is not a pointer"); 12939 12940 if (!A.getInfoCache().getFlatAddressSpace().has_value()) { 12941 indicatePessimisticFixpoint(); 12942 return; 12943 } 12944 12945 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value(); 12946 unsigned AS = getAssociatedType()->getPointerAddressSpace(); 12947 if (AS != FlatAS) { 12948 [[maybe_unused]] bool R = takeAddressSpace(AS); 12949 assert(R && "The take should happen"); 12950 indicateOptimisticFixpoint(); 12951 } 12952 } 12953 12954 ChangeStatus updateImpl(Attributor &A) override { 12955 uint32_t OldAddressSpace = AssumedAddressSpace; 12956 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value(); 12957 12958 auto CheckAddressSpace = [&](Value &Obj) { 12959 // Ignore undef. 12960 if (isa<UndefValue>(&Obj)) 12961 return true; 12962 12963 // If the object already has a non-flat address space, we simply take it. 12964 unsigned ObjAS = Obj.getType()->getPointerAddressSpace(); 12965 if (ObjAS != FlatAS) 12966 return takeAddressSpace(ObjAS); 12967 12968 // At this point, we know Obj is in the flat address space. For a final 12969 // attempt, we want to use getAssumedAddrSpace, but first we must get the 12970 // associated function, if possible. 12971 Function *F = nullptr; 12972 if (auto *Arg = dyn_cast<Argument>(&Obj)) 12973 F = Arg->getParent(); 12974 else if (auto *I = dyn_cast<Instruction>(&Obj)) 12975 F = I->getFunction(); 12976 12977 // Use getAssumedAddrSpace if the associated function exists. 12978 if (F) { 12979 auto *TTI = 12980 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(*F); 12981 unsigned AssumedAS = TTI->getAssumedAddrSpace(&Obj); 12982 if (AssumedAS != ~0U) 12983 return takeAddressSpace(AssumedAS); 12984 } 12985 12986 // Now we can't do anything else but to take the flat AS. 12987 return takeAddressSpace(FlatAS); 12988 }; 12989 12990 auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this, 12991 DepClassTy::REQUIRED); 12992 if (!AUO->forallUnderlyingObjects(CheckAddressSpace)) 12993 return indicatePessimisticFixpoint(); 12994 12995 return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED 12996 : ChangeStatus::CHANGED; 12997 } 12998 12999 /// See AbstractAttribute::manifest(...). 13000 ChangeStatus manifest(Attributor &A) override { 13001 unsigned NewAS = getAddressSpace(); 13002 13003 if (NewAS == InvalidAddressSpace || 13004 NewAS == getAssociatedType()->getPointerAddressSpace()) 13005 return ChangeStatus::UNCHANGED; 13006 13007 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value(); 13008 13009 Value *AssociatedValue = &getAssociatedValue(); 13010 Value *OriginalValue = peelAddrspacecast(AssociatedValue, FlatAS); 13011 13012 PointerType *NewPtrTy = 13013 PointerType::get(getAssociatedType()->getContext(), NewAS); 13014 bool UseOriginalValue = 13015 OriginalValue->getType()->getPointerAddressSpace() == NewAS; 13016 13017 bool Changed = false; 13018 13019 auto Pred = [&](const Use &U, bool &) { 13020 if (U.get() != AssociatedValue) 13021 return true; 13022 auto *Inst = dyn_cast<Instruction>(U.getUser()); 13023 if (!Inst) 13024 return true; 13025 // This is a WA to make sure we only change uses from the corresponding 13026 // CGSCC if the AA is run on CGSCC instead of the entire module. 13027 if (!A.isRunOn(Inst->getFunction())) 13028 return true; 13029 if (auto *LI = dyn_cast<LoadInst>(Inst)) { 13030 Changed |= 13031 makeChange(A, LI, U, OriginalValue, NewPtrTy, UseOriginalValue); 13032 } else if (auto *SI = dyn_cast<StoreInst>(Inst)) { 13033 Changed |= 13034 makeChange(A, SI, U, OriginalValue, NewPtrTy, UseOriginalValue); 13035 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(Inst)) { 13036 Changed |= 13037 makeChange(A, RMW, U, OriginalValue, NewPtrTy, UseOriginalValue); 13038 } else if (auto *CmpX = dyn_cast<AtomicCmpXchgInst>(Inst)) { 13039 Changed |= 13040 makeChange(A, CmpX, U, OriginalValue, NewPtrTy, UseOriginalValue); 13041 } 13042 return true; 13043 }; 13044 13045 // It doesn't matter if we can't check all uses as we can simply 13046 // conservatively ignore those that can not be visited. 13047 (void)A.checkForAllUses(Pred, *this, getAssociatedValue(), 13048 /* CheckBBLivenessOnly */ true); 13049 13050 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 13051 } 13052 13053 /// See AbstractAttribute::getAsStr(). 13054 const std::string getAsStr(Attributor *A) const override { 13055 if (!isValidState()) 13056 return "addrspace(<invalid>)"; 13057 return "addrspace(" + 13058 (AssumedAddressSpace == InvalidAddressSpace 13059 ? "none" 13060 : std::to_string(AssumedAddressSpace)) + 13061 ")"; 13062 } 13063 13064 private: 13065 uint32_t AssumedAddressSpace = InvalidAddressSpace; 13066 13067 bool takeAddressSpace(uint32_t AS) { 13068 if (AssumedAddressSpace == InvalidAddressSpace) { 13069 AssumedAddressSpace = AS; 13070 return true; 13071 } 13072 return AssumedAddressSpace == AS; 13073 } 13074 13075 static Value *peelAddrspacecast(Value *V, unsigned FlatAS) { 13076 if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) { 13077 assert(I->getSrcAddressSpace() != FlatAS && 13078 "there should not be flat AS -> non-flat AS"); 13079 return I->getPointerOperand(); 13080 } 13081 if (auto *C = dyn_cast<ConstantExpr>(V)) 13082 if (C->getOpcode() == Instruction::AddrSpaceCast) { 13083 assert(C->getOperand(0)->getType()->getPointerAddressSpace() != 13084 FlatAS && 13085 "there should not be flat AS -> non-flat AS X"); 13086 return C->getOperand(0); 13087 } 13088 return V; 13089 } 13090 }; 13091 13092 struct AAAddressSpaceFloating final : AAAddressSpaceImpl { 13093 AAAddressSpaceFloating(const IRPosition &IRP, Attributor &A) 13094 : AAAddressSpaceImpl(IRP, A) {} 13095 13096 void trackStatistics() const override { 13097 STATS_DECLTRACK_FLOATING_ATTR(addrspace); 13098 } 13099 }; 13100 13101 struct AAAddressSpaceReturned final : AAAddressSpaceImpl { 13102 AAAddressSpaceReturned(const IRPosition &IRP, Attributor &A) 13103 : AAAddressSpaceImpl(IRP, A) {} 13104 13105 /// See AbstractAttribute::initialize(...). 13106 void initialize(Attributor &A) override { 13107 // TODO: we don't rewrite function argument for now because it will need to 13108 // rewrite the function signature and all call sites. 13109 (void)indicatePessimisticFixpoint(); 13110 } 13111 13112 void trackStatistics() const override { 13113 STATS_DECLTRACK_FNRET_ATTR(addrspace); 13114 } 13115 }; 13116 13117 struct AAAddressSpaceCallSiteReturned final : AAAddressSpaceImpl { 13118 AAAddressSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A) 13119 : AAAddressSpaceImpl(IRP, A) {} 13120 13121 void trackStatistics() const override { 13122 STATS_DECLTRACK_CSRET_ATTR(addrspace); 13123 } 13124 }; 13125 13126 struct AAAddressSpaceArgument final : AAAddressSpaceImpl { 13127 AAAddressSpaceArgument(const IRPosition &IRP, Attributor &A) 13128 : AAAddressSpaceImpl(IRP, A) {} 13129 13130 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(addrspace); } 13131 }; 13132 13133 struct AAAddressSpaceCallSiteArgument final : AAAddressSpaceImpl { 13134 AAAddressSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A) 13135 : AAAddressSpaceImpl(IRP, A) {} 13136 13137 /// See AbstractAttribute::initialize(...). 13138 void initialize(Attributor &A) override { 13139 // TODO: we don't rewrite call site argument for now because it will need to 13140 // rewrite the function signature of the callee. 13141 (void)indicatePessimisticFixpoint(); 13142 } 13143 13144 void trackStatistics() const override { 13145 STATS_DECLTRACK_CSARG_ATTR(addrspace); 13146 } 13147 }; 13148 } // namespace 13149 13150 /// ------------------------ No Alias Address Space --------------------------- 13151 // This attribute assumes flat address space can alias all other address space 13152 13153 // TODO: this is similar to AAAddressSpace, most of the code should be merged. 13154 // But merging it created failing cased on gateway test that cannot be 13155 // reproduced locally. So should open a seperated PR to hande the merge of 13156 // AANoAliasAddrSpace and AAAddressSpace attribute 13157 13158 namespace { 13159 struct AANoAliasAddrSpaceImpl : public AANoAliasAddrSpace { 13160 AANoAliasAddrSpaceImpl(const IRPosition &IRP, Attributor &A) 13161 : AANoAliasAddrSpace(IRP, A) {} 13162 13163 void initialize(Attributor &A) override { 13164 assert(getAssociatedType()->isPtrOrPtrVectorTy() && 13165 "Associated value is not a pointer"); 13166 13167 resetASRanges(A); 13168 13169 std::optional<unsigned> FlatAS = A.getInfoCache().getFlatAddressSpace(); 13170 if (!FlatAS.has_value()) { 13171 indicatePessimisticFixpoint(); 13172 return; 13173 } 13174 13175 removeAS(*FlatAS); 13176 13177 unsigned AS = getAssociatedType()->getPointerAddressSpace(); 13178 if (AS != *FlatAS) { 13179 removeAS(AS); 13180 indicateOptimisticFixpoint(); 13181 } 13182 } 13183 13184 ChangeStatus updateImpl(Attributor &A) override { 13185 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value(); 13186 uint32_t OldAssumed = getAssumed(); 13187 13188 auto CheckAddressSpace = [&](Value &Obj) { 13189 if (isa<PoisonValue>(&Obj)) 13190 return true; 13191 13192 unsigned AS = Obj.getType()->getPointerAddressSpace(); 13193 if (AS == FlatAS) 13194 return false; 13195 13196 removeAS(Obj.getType()->getPointerAddressSpace()); 13197 return true; 13198 }; 13199 13200 const AAUnderlyingObjects *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>( 13201 getIRPosition(), this, DepClassTy::REQUIRED); 13202 if (!AUO->forallUnderlyingObjects(CheckAddressSpace)) 13203 return indicatePessimisticFixpoint(); 13204 13205 return OldAssumed == getAssumed() ? ChangeStatus::UNCHANGED 13206 : ChangeStatus::CHANGED; 13207 } 13208 13209 /// See AbstractAttribute::manifest(...). 13210 ChangeStatus manifest(Attributor &A) override { 13211 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value(); 13212 13213 unsigned AS = getAssociatedType()->getPointerAddressSpace(); 13214 if (AS != FlatAS || Map.empty()) 13215 return ChangeStatus::UNCHANGED; 13216 13217 LLVMContext &Ctx = getAssociatedValue().getContext(); 13218 MDNode *NoAliasASNode = nullptr; 13219 MDBuilder MDB(Ctx); 13220 // Has to use iterator to get the range info. 13221 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) { 13222 if (!I.value()) 13223 continue; 13224 unsigned Upper = I.stop(); 13225 unsigned Lower = I.start(); 13226 if (!NoAliasASNode) { 13227 NoAliasASNode = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1)); 13228 continue; 13229 } 13230 MDNode *ASRange = MDB.createRange(APInt(32, Lower), APInt(32, Upper + 1)); 13231 NoAliasASNode = MDNode::getMostGenericRange(NoAliasASNode, ASRange); 13232 } 13233 13234 Value *AssociatedValue = &getAssociatedValue(); 13235 bool Changed = false; 13236 13237 auto AddNoAliasAttr = [&](const Use &U, bool &) { 13238 if (U.get() != AssociatedValue) 13239 return true; 13240 Instruction *Inst = dyn_cast<Instruction>(U.getUser()); 13241 if (!Inst || Inst->hasMetadata(LLVMContext::MD_noalias_addrspace)) 13242 return true; 13243 if (!isa<LoadInst>(Inst) && !isa<StoreInst>(Inst) && 13244 !isa<AtomicCmpXchgInst>(Inst) && !isa<AtomicRMWInst>(Inst)) 13245 return true; 13246 if (!A.isRunOn(Inst->getFunction())) 13247 return true; 13248 Inst->setMetadata(LLVMContext::MD_noalias_addrspace, NoAliasASNode); 13249 Changed = true; 13250 return true; 13251 }; 13252 (void)A.checkForAllUses(AddNoAliasAttr, *this, *AssociatedValue, 13253 /*CheckBBLivenessOnly=*/true); 13254 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 13255 } 13256 13257 /// See AbstractAttribute::getAsStr(). 13258 const std::string getAsStr(Attributor *A) const override { 13259 if (!isValidState()) 13260 return "<invalid>"; 13261 std::string Str; 13262 raw_string_ostream OS(Str); 13263 OS << "CanNotBeAddrSpace("; 13264 for (RangeMap::const_iterator I = Map.begin(); I != Map.end(); I++) { 13265 unsigned Upper = I.stop(); 13266 unsigned Lower = I.start(); 13267 OS << ' ' << '[' << Upper << ',' << Lower + 1 << ')'; 13268 } 13269 OS << " )"; 13270 return OS.str(); 13271 } 13272 13273 private: 13274 void removeAS(unsigned AS) { 13275 RangeMap::iterator I = Map.find(AS); 13276 13277 if (I != Map.end()) { 13278 unsigned Upper = I.stop(); 13279 unsigned Lower = I.start(); 13280 I.erase(); 13281 if (Upper == Lower) 13282 return; 13283 if (AS != ~((unsigned)0) && AS + 1 <= Upper) 13284 Map.insert(AS + 1, Upper, /*what ever this variable name is=*/true); 13285 if (AS != 0 && Lower <= AS - 1) 13286 Map.insert(Lower, AS - 1, true); 13287 } 13288 } 13289 13290 void resetASRanges(Attributor &A) { 13291 Map.clear(); 13292 Map.insert(0, A.getInfoCache().getMaxAddrSpace(), true); 13293 } 13294 }; 13295 13296 struct AANoAliasAddrSpaceFloating final : AANoAliasAddrSpaceImpl { 13297 AANoAliasAddrSpaceFloating(const IRPosition &IRP, Attributor &A) 13298 : AANoAliasAddrSpaceImpl(IRP, A) {} 13299 13300 void trackStatistics() const override { 13301 STATS_DECLTRACK_FLOATING_ATTR(noaliasaddrspace); 13302 } 13303 }; 13304 13305 struct AANoAliasAddrSpaceReturned final : AANoAliasAddrSpaceImpl { 13306 AANoAliasAddrSpaceReturned(const IRPosition &IRP, Attributor &A) 13307 : AANoAliasAddrSpaceImpl(IRP, A) {} 13308 13309 void trackStatistics() const override { 13310 STATS_DECLTRACK_FNRET_ATTR(noaliasaddrspace); 13311 } 13312 }; 13313 13314 struct AANoAliasAddrSpaceCallSiteReturned final : AANoAliasAddrSpaceImpl { 13315 AANoAliasAddrSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A) 13316 : AANoAliasAddrSpaceImpl(IRP, A) {} 13317 13318 void trackStatistics() const override { 13319 STATS_DECLTRACK_CSRET_ATTR(noaliasaddrspace); 13320 } 13321 }; 13322 13323 struct AANoAliasAddrSpaceArgument final : AANoAliasAddrSpaceImpl { 13324 AANoAliasAddrSpaceArgument(const IRPosition &IRP, Attributor &A) 13325 : AANoAliasAddrSpaceImpl(IRP, A) {} 13326 13327 void trackStatistics() const override { 13328 STATS_DECLTRACK_ARG_ATTR(noaliasaddrspace); 13329 } 13330 }; 13331 13332 struct AANoAliasAddrSpaceCallSiteArgument final : AANoAliasAddrSpaceImpl { 13333 AANoAliasAddrSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A) 13334 : AANoAliasAddrSpaceImpl(IRP, A) {} 13335 13336 void trackStatistics() const override { 13337 STATS_DECLTRACK_CSARG_ATTR(noaliasaddrspace); 13338 } 13339 }; 13340 } // namespace 13341 /// ----------- Allocation Info ---------- 13342 namespace { 13343 struct AAAllocationInfoImpl : public AAAllocationInfo { 13344 AAAllocationInfoImpl(const IRPosition &IRP, Attributor &A) 13345 : AAAllocationInfo(IRP, A) {} 13346 13347 std::optional<TypeSize> getAllocatedSize() const override { 13348 assert(isValidState() && "the AA is invalid"); 13349 return AssumedAllocatedSize; 13350 } 13351 13352 std::optional<TypeSize> findInitialAllocationSize(Instruction *I, 13353 const DataLayout &DL) { 13354 13355 // TODO: implement case for malloc like instructions 13356 switch (I->getOpcode()) { 13357 case Instruction::Alloca: { 13358 AllocaInst *AI = cast<AllocaInst>(I); 13359 return AI->getAllocationSize(DL); 13360 } 13361 default: 13362 return std::nullopt; 13363 } 13364 } 13365 13366 ChangeStatus updateImpl(Attributor &A) override { 13367 13368 const IRPosition &IRP = getIRPosition(); 13369 Instruction *I = IRP.getCtxI(); 13370 13371 // TODO: update check for malloc like calls 13372 if (!isa<AllocaInst>(I)) 13373 return indicatePessimisticFixpoint(); 13374 13375 bool IsKnownNoCapture; 13376 if (!AA::hasAssumedIRAttr<Attribute::Captures>( 13377 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture)) 13378 return indicatePessimisticFixpoint(); 13379 13380 const AAPointerInfo *PI = 13381 A.getOrCreateAAFor<AAPointerInfo>(IRP, *this, DepClassTy::REQUIRED); 13382 13383 if (!PI) 13384 return indicatePessimisticFixpoint(); 13385 13386 if (!PI->getState().isValidState() || PI->reachesReturn()) 13387 return indicatePessimisticFixpoint(); 13388 13389 const DataLayout &DL = A.getDataLayout(); 13390 const auto AllocationSize = findInitialAllocationSize(I, DL); 13391 13392 // If allocation size is nullopt, we give up. 13393 if (!AllocationSize) 13394 return indicatePessimisticFixpoint(); 13395 13396 // For zero sized allocations, we give up. 13397 // Since we can't reduce further 13398 if (*AllocationSize == 0) 13399 return indicatePessimisticFixpoint(); 13400 13401 int64_t BinSize = PI->numOffsetBins(); 13402 13403 // TODO: implement for multiple bins 13404 if (BinSize > 1) 13405 return indicatePessimisticFixpoint(); 13406 13407 if (BinSize == 0) { 13408 auto NewAllocationSize = std::optional<TypeSize>(TypeSize(0, false)); 13409 if (!changeAllocationSize(NewAllocationSize)) 13410 return ChangeStatus::UNCHANGED; 13411 return ChangeStatus::CHANGED; 13412 } 13413 13414 // TODO: refactor this to be part of multiple bin case 13415 const auto &It = PI->begin(); 13416 13417 // TODO: handle if Offset is not zero 13418 if (It->first.Offset != 0) 13419 return indicatePessimisticFixpoint(); 13420 13421 uint64_t SizeOfBin = It->first.Offset + It->first.Size; 13422 13423 if (SizeOfBin >= *AllocationSize) 13424 return indicatePessimisticFixpoint(); 13425 13426 auto NewAllocationSize = 13427 std::optional<TypeSize>(TypeSize(SizeOfBin * 8, false)); 13428 13429 if (!changeAllocationSize(NewAllocationSize)) 13430 return ChangeStatus::UNCHANGED; 13431 13432 return ChangeStatus::CHANGED; 13433 } 13434 13435 /// See AbstractAttribute::manifest(...). 13436 ChangeStatus manifest(Attributor &A) override { 13437 13438 assert(isValidState() && 13439 "Manifest should only be called if the state is valid."); 13440 13441 Instruction *I = getIRPosition().getCtxI(); 13442 13443 auto FixedAllocatedSizeInBits = getAllocatedSize()->getFixedValue(); 13444 13445 unsigned long NumBytesToAllocate = (FixedAllocatedSizeInBits + 7) / 8; 13446 13447 switch (I->getOpcode()) { 13448 // TODO: add case for malloc like calls 13449 case Instruction::Alloca: { 13450 13451 AllocaInst *AI = cast<AllocaInst>(I); 13452 13453 Type *CharType = Type::getInt8Ty(I->getContext()); 13454 13455 auto *NumBytesToValue = 13456 ConstantInt::get(I->getContext(), APInt(32, NumBytesToAllocate)); 13457 13458 BasicBlock::iterator insertPt = AI->getIterator(); 13459 insertPt = std::next(insertPt); 13460 AllocaInst *NewAllocaInst = 13461 new AllocaInst(CharType, AI->getAddressSpace(), NumBytesToValue, 13462 AI->getAlign(), AI->getName(), insertPt); 13463 13464 if (A.changeAfterManifest(IRPosition::inst(*AI), *NewAllocaInst)) 13465 return ChangeStatus::CHANGED; 13466 13467 break; 13468 } 13469 default: 13470 break; 13471 } 13472 13473 return ChangeStatus::UNCHANGED; 13474 } 13475 13476 /// See AbstractAttribute::getAsStr(). 13477 const std::string getAsStr(Attributor *A) const override { 13478 if (!isValidState()) 13479 return "allocationinfo(<invalid>)"; 13480 return "allocationinfo(" + 13481 (AssumedAllocatedSize == HasNoAllocationSize 13482 ? "none" 13483 : std::to_string(AssumedAllocatedSize->getFixedValue())) + 13484 ")"; 13485 } 13486 13487 private: 13488 std::optional<TypeSize> AssumedAllocatedSize = HasNoAllocationSize; 13489 13490 // Maintain the computed allocation size of the object. 13491 // Returns (bool) weather the size of the allocation was modified or not. 13492 bool changeAllocationSize(std::optional<TypeSize> Size) { 13493 if (AssumedAllocatedSize == HasNoAllocationSize || 13494 AssumedAllocatedSize != Size) { 13495 AssumedAllocatedSize = Size; 13496 return true; 13497 } 13498 return false; 13499 } 13500 }; 13501 13502 struct AAAllocationInfoFloating : AAAllocationInfoImpl { 13503 AAAllocationInfoFloating(const IRPosition &IRP, Attributor &A) 13504 : AAAllocationInfoImpl(IRP, A) {} 13505 13506 void trackStatistics() const override { 13507 STATS_DECLTRACK_FLOATING_ATTR(allocationinfo); 13508 } 13509 }; 13510 13511 struct AAAllocationInfoReturned : AAAllocationInfoImpl { 13512 AAAllocationInfoReturned(const IRPosition &IRP, Attributor &A) 13513 : AAAllocationInfoImpl(IRP, A) {} 13514 13515 /// See AbstractAttribute::initialize(...). 13516 void initialize(Attributor &A) override { 13517 // TODO: we don't rewrite function argument for now because it will need to 13518 // rewrite the function signature and all call sites 13519 (void)indicatePessimisticFixpoint(); 13520 } 13521 13522 void trackStatistics() const override { 13523 STATS_DECLTRACK_FNRET_ATTR(allocationinfo); 13524 } 13525 }; 13526 13527 struct AAAllocationInfoCallSiteReturned : AAAllocationInfoImpl { 13528 AAAllocationInfoCallSiteReturned(const IRPosition &IRP, Attributor &A) 13529 : AAAllocationInfoImpl(IRP, A) {} 13530 13531 void trackStatistics() const override { 13532 STATS_DECLTRACK_CSRET_ATTR(allocationinfo); 13533 } 13534 }; 13535 13536 struct AAAllocationInfoArgument : AAAllocationInfoImpl { 13537 AAAllocationInfoArgument(const IRPosition &IRP, Attributor &A) 13538 : AAAllocationInfoImpl(IRP, A) {} 13539 13540 void trackStatistics() const override { 13541 STATS_DECLTRACK_ARG_ATTR(allocationinfo); 13542 } 13543 }; 13544 13545 struct AAAllocationInfoCallSiteArgument : AAAllocationInfoImpl { 13546 AAAllocationInfoCallSiteArgument(const IRPosition &IRP, Attributor &A) 13547 : AAAllocationInfoImpl(IRP, A) {} 13548 13549 /// See AbstractAttribute::initialize(...). 13550 void initialize(Attributor &A) override { 13551 13552 (void)indicatePessimisticFixpoint(); 13553 } 13554 13555 void trackStatistics() const override { 13556 STATS_DECLTRACK_CSARG_ATTR(allocationinfo); 13557 } 13558 }; 13559 } // namespace 13560 13561 const char AANoUnwind::ID = 0; 13562 const char AANoSync::ID = 0; 13563 const char AANoFree::ID = 0; 13564 const char AANonNull::ID = 0; 13565 const char AAMustProgress::ID = 0; 13566 const char AANoRecurse::ID = 0; 13567 const char AANonConvergent::ID = 0; 13568 const char AAWillReturn::ID = 0; 13569 const char AAUndefinedBehavior::ID = 0; 13570 const char AANoAlias::ID = 0; 13571 const char AAIntraFnReachability::ID = 0; 13572 const char AANoReturn::ID = 0; 13573 const char AAIsDead::ID = 0; 13574 const char AADereferenceable::ID = 0; 13575 const char AAAlign::ID = 0; 13576 const char AAInstanceInfo::ID = 0; 13577 const char AANoCapture::ID = 0; 13578 const char AAValueSimplify::ID = 0; 13579 const char AAHeapToStack::ID = 0; 13580 const char AAPrivatizablePtr::ID = 0; 13581 const char AAMemoryBehavior::ID = 0; 13582 const char AAMemoryLocation::ID = 0; 13583 const char AAValueConstantRange::ID = 0; 13584 const char AAPotentialConstantValues::ID = 0; 13585 const char AAPotentialValues::ID = 0; 13586 const char AANoUndef::ID = 0; 13587 const char AANoFPClass::ID = 0; 13588 const char AACallEdges::ID = 0; 13589 const char AAInterFnReachability::ID = 0; 13590 const char AAPointerInfo::ID = 0; 13591 const char AAAssumptionInfo::ID = 0; 13592 const char AAUnderlyingObjects::ID = 0; 13593 const char AAInvariantLoadPointer::ID = 0; 13594 const char AAAddressSpace::ID = 0; 13595 const char AANoAliasAddrSpace::ID = 0; 13596 const char AAAllocationInfo::ID = 0; 13597 const char AAIndirectCallInfo::ID = 0; 13598 const char AAGlobalValueInfo::ID = 0; 13599 const char AADenormalFPMath::ID = 0; 13600 13601 // Macro magic to create the static generator function for attributes that 13602 // follow the naming scheme. 13603 13604 #define SWITCH_PK_INV(CLASS, PK, POS_NAME) \ 13605 case IRPosition::PK: \ 13606 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!"); 13607 13608 #define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \ 13609 case IRPosition::PK: \ 13610 AA = new (A.Allocator) CLASS##SUFFIX(IRP, A); \ 13611 ++NumAAs; \ 13612 break; 13613 13614 #define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \ 13615 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 13616 CLASS *AA = nullptr; \ 13617 switch (IRP.getPositionKind()) { \ 13618 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \ 13619 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \ 13620 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \ 13621 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \ 13622 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \ 13623 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \ 13624 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \ 13625 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \ 13626 } \ 13627 return *AA; \ 13628 } 13629 13630 #define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \ 13631 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 13632 CLASS *AA = nullptr; \ 13633 switch (IRP.getPositionKind()) { \ 13634 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \ 13635 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \ 13636 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \ 13637 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \ 13638 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \ 13639 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \ 13640 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \ 13641 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \ 13642 } \ 13643 return *AA; \ 13644 } 13645 13646 #define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS) \ 13647 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 13648 CLASS *AA = nullptr; \ 13649 switch (IRP.getPositionKind()) { \ 13650 SWITCH_PK_CREATE(CLASS, IRP, POS, SUFFIX) \ 13651 default: \ 13652 llvm_unreachable("Cannot create " #CLASS " for position otherthan " #POS \ 13653 " position!"); \ 13654 } \ 13655 return *AA; \ 13656 } 13657 13658 #define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \ 13659 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 13660 CLASS *AA = nullptr; \ 13661 switch (IRP.getPositionKind()) { \ 13662 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \ 13663 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \ 13664 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \ 13665 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \ 13666 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \ 13667 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \ 13668 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \ 13669 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \ 13670 } \ 13671 return *AA; \ 13672 } 13673 13674 #define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \ 13675 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 13676 CLASS *AA = nullptr; \ 13677 switch (IRP.getPositionKind()) { \ 13678 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \ 13679 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \ 13680 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \ 13681 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \ 13682 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \ 13683 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \ 13684 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \ 13685 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \ 13686 } \ 13687 return *AA; \ 13688 } 13689 13690 #define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \ 13691 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 13692 CLASS *AA = nullptr; \ 13693 switch (IRP.getPositionKind()) { \ 13694 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \ 13695 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \ 13696 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \ 13697 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \ 13698 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \ 13699 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \ 13700 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \ 13701 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \ 13702 } \ 13703 return *AA; \ 13704 } 13705 13706 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUnwind) 13707 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoSync) 13708 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoRecurse) 13709 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAWillReturn) 13710 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoReturn) 13711 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryLocation) 13712 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AACallEdges) 13713 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAssumptionInfo) 13714 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMustProgress) 13715 13716 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonNull) 13717 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoAlias) 13718 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPrivatizablePtr) 13719 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADereferenceable) 13720 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAlign) 13721 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAInstanceInfo) 13722 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoCapture) 13723 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueConstantRange) 13724 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPotentialConstantValues) 13725 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPotentialValues) 13726 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUndef) 13727 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFPClass) 13728 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPointerInfo) 13729 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAInvariantLoadPointer) 13730 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAddressSpace) 13731 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoAliasAddrSpace) 13732 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAllocationInfo) 13733 13734 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify) 13735 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIsDead) 13736 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree) 13737 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAUnderlyingObjects) 13738 13739 CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(IRP_CALL_SITE, CallSite, 13740 AAIndirectCallInfo) 13741 CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(IRP_FLOAT, Floating, 13742 AAGlobalValueInfo) 13743 13744 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAHeapToStack) 13745 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAUndefinedBehavior) 13746 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonConvergent) 13747 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIntraFnReachability) 13748 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAInterFnReachability) 13749 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADenormalFPMath) 13750 13751 CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryBehavior) 13752 13753 #undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION 13754 #undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION 13755 #undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION 13756 #undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION 13757 #undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION 13758 #undef CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION 13759 #undef SWITCH_PK_CREATE 13760 #undef SWITCH_PK_INV 13761