1 //===- AttributorAttributes.cpp - Attributes for Attributor deduction -----===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // See the Attributor.h file comment and the class descriptions in that file for 10 // more information. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Transforms/IPO/Attributor.h" 15 16 #include "llvm/ADT/APInt.h" 17 #include "llvm/ADT/ArrayRef.h" 18 #include "llvm/ADT/DenseMapInfo.h" 19 #include "llvm/ADT/MapVector.h" 20 #include "llvm/ADT/SCCIterator.h" 21 #include "llvm/ADT/STLExtras.h" 22 #include "llvm/ADT/SetOperations.h" 23 #include "llvm/ADT/SetVector.h" 24 #include "llvm/ADT/SmallPtrSet.h" 25 #include "llvm/ADT/SmallVector.h" 26 #include "llvm/ADT/Statistic.h" 27 #include "llvm/ADT/StringExtras.h" 28 #include "llvm/Analysis/AliasAnalysis.h" 29 #include "llvm/Analysis/AssumeBundleQueries.h" 30 #include "llvm/Analysis/AssumptionCache.h" 31 #include "llvm/Analysis/CaptureTracking.h" 32 #include "llvm/Analysis/CycleAnalysis.h" 33 #include "llvm/Analysis/InstructionSimplify.h" 34 #include "llvm/Analysis/LazyValueInfo.h" 35 #include "llvm/Analysis/MemoryBuiltins.h" 36 #include "llvm/Analysis/OptimizationRemarkEmitter.h" 37 #include "llvm/Analysis/ScalarEvolution.h" 38 #include "llvm/Analysis/TargetTransformInfo.h" 39 #include "llvm/Analysis/ValueTracking.h" 40 #include "llvm/IR/Argument.h" 41 #include "llvm/IR/Assumptions.h" 42 #include "llvm/IR/Attributes.h" 43 #include "llvm/IR/BasicBlock.h" 44 #include "llvm/IR/Constant.h" 45 #include "llvm/IR/Constants.h" 46 #include "llvm/IR/DataLayout.h" 47 #include "llvm/IR/DerivedTypes.h" 48 #include "llvm/IR/GlobalValue.h" 49 #include "llvm/IR/IRBuilder.h" 50 #include "llvm/IR/InlineAsm.h" 51 #include "llvm/IR/InstrTypes.h" 52 #include "llvm/IR/Instruction.h" 53 #include "llvm/IR/Instructions.h" 54 #include "llvm/IR/IntrinsicInst.h" 55 #include "llvm/IR/IntrinsicsAMDGPU.h" 56 #include "llvm/IR/IntrinsicsNVPTX.h" 57 #include "llvm/IR/LLVMContext.h" 58 #include "llvm/IR/MDBuilder.h" 59 #include "llvm/IR/NoFolder.h" 60 #include "llvm/IR/Value.h" 61 #include "llvm/IR/ValueHandle.h" 62 #include "llvm/Support/Alignment.h" 63 #include "llvm/Support/Casting.h" 64 #include "llvm/Support/CommandLine.h" 65 #include "llvm/Support/ErrorHandling.h" 66 #include "llvm/Support/GraphWriter.h" 67 #include "llvm/Support/MathExtras.h" 68 #include "llvm/Support/TypeSize.h" 69 #include "llvm/Support/raw_ostream.h" 70 #include "llvm/Transforms/Utils/BasicBlockUtils.h" 71 #include "llvm/Transforms/Utils/CallPromotionUtils.h" 72 #include "llvm/Transforms/Utils/Local.h" 73 #include "llvm/Transforms/Utils/ValueMapper.h" 74 #include <cassert> 75 #include <numeric> 76 #include <optional> 77 #include <string> 78 79 using namespace llvm; 80 81 #define DEBUG_TYPE "attributor" 82 83 static cl::opt<bool> ManifestInternal( 84 "attributor-manifest-internal", cl::Hidden, 85 cl::desc("Manifest Attributor internal string attributes."), 86 cl::init(false)); 87 88 static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128), 89 cl::Hidden); 90 91 template <> 92 unsigned llvm::PotentialConstantIntValuesState::MaxPotentialValues = 0; 93 94 template <> unsigned llvm::PotentialLLVMValuesState::MaxPotentialValues = -1; 95 96 static cl::opt<unsigned, true> MaxPotentialValues( 97 "attributor-max-potential-values", cl::Hidden, 98 cl::desc("Maximum number of potential values to be " 99 "tracked for each position."), 100 cl::location(llvm::PotentialConstantIntValuesState::MaxPotentialValues), 101 cl::init(7)); 102 103 static cl::opt<int> MaxPotentialValuesIterations( 104 "attributor-max-potential-values-iterations", cl::Hidden, 105 cl::desc( 106 "Maximum number of iterations we keep dismantling potential values."), 107 cl::init(64)); 108 109 STATISTIC(NumAAs, "Number of abstract attributes created"); 110 111 // Some helper macros to deal with statistics tracking. 112 // 113 // Usage: 114 // For simple IR attribute tracking overload trackStatistics in the abstract 115 // attribute and choose the right STATS_DECLTRACK_********* macro, 116 // e.g.,: 117 // void trackStatistics() const override { 118 // STATS_DECLTRACK_ARG_ATTR(returned) 119 // } 120 // If there is a single "increment" side one can use the macro 121 // STATS_DECLTRACK with a custom message. If there are multiple increment 122 // sides, STATS_DECL and STATS_TRACK can also be used separately. 123 // 124 #define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \ 125 ("Number of " #TYPE " marked '" #NAME "'") 126 #define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME 127 #define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG); 128 #define STATS_DECL(NAME, TYPE, MSG) \ 129 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG); 130 #define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE)); 131 #define STATS_DECLTRACK(NAME, TYPE, MSG) \ 132 { \ 133 STATS_DECL(NAME, TYPE, MSG) \ 134 STATS_TRACK(NAME, TYPE) \ 135 } 136 #define STATS_DECLTRACK_ARG_ATTR(NAME) \ 137 STATS_DECLTRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME)) 138 #define STATS_DECLTRACK_CSARG_ATTR(NAME) \ 139 STATS_DECLTRACK(NAME, CSArguments, \ 140 BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME)) 141 #define STATS_DECLTRACK_FN_ATTR(NAME) \ 142 STATS_DECLTRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME)) 143 #define STATS_DECLTRACK_CS_ATTR(NAME) \ 144 STATS_DECLTRACK(NAME, CS, BUILD_STAT_MSG_IR_ATTR(call site, NAME)) 145 #define STATS_DECLTRACK_FNRET_ATTR(NAME) \ 146 STATS_DECLTRACK(NAME, FunctionReturn, \ 147 BUILD_STAT_MSG_IR_ATTR(function returns, NAME)) 148 #define STATS_DECLTRACK_CSRET_ATTR(NAME) \ 149 STATS_DECLTRACK(NAME, CSReturn, \ 150 BUILD_STAT_MSG_IR_ATTR(call site returns, NAME)) 151 #define STATS_DECLTRACK_FLOATING_ATTR(NAME) \ 152 STATS_DECLTRACK(NAME, Floating, \ 153 ("Number of floating values known to be '" #NAME "'")) 154 155 // Specialization of the operator<< for abstract attributes subclasses. This 156 // disambiguates situations where multiple operators are applicable. 157 namespace llvm { 158 #define PIPE_OPERATOR(CLASS) \ 159 raw_ostream &operator<<(raw_ostream &OS, const CLASS &AA) { \ 160 return OS << static_cast<const AbstractAttribute &>(AA); \ 161 } 162 163 PIPE_OPERATOR(AAIsDead) 164 PIPE_OPERATOR(AANoUnwind) 165 PIPE_OPERATOR(AANoSync) 166 PIPE_OPERATOR(AANoRecurse) 167 PIPE_OPERATOR(AANonConvergent) 168 PIPE_OPERATOR(AAWillReturn) 169 PIPE_OPERATOR(AANoReturn) 170 PIPE_OPERATOR(AANonNull) 171 PIPE_OPERATOR(AAMustProgress) 172 PIPE_OPERATOR(AANoAlias) 173 PIPE_OPERATOR(AADereferenceable) 174 PIPE_OPERATOR(AAAlign) 175 PIPE_OPERATOR(AAInstanceInfo) 176 PIPE_OPERATOR(AANoCapture) 177 PIPE_OPERATOR(AAValueSimplify) 178 PIPE_OPERATOR(AANoFree) 179 PIPE_OPERATOR(AAHeapToStack) 180 PIPE_OPERATOR(AAIntraFnReachability) 181 PIPE_OPERATOR(AAMemoryBehavior) 182 PIPE_OPERATOR(AAMemoryLocation) 183 PIPE_OPERATOR(AAValueConstantRange) 184 PIPE_OPERATOR(AAPrivatizablePtr) 185 PIPE_OPERATOR(AAUndefinedBehavior) 186 PIPE_OPERATOR(AAPotentialConstantValues) 187 PIPE_OPERATOR(AAPotentialValues) 188 PIPE_OPERATOR(AANoUndef) 189 PIPE_OPERATOR(AANoFPClass) 190 PIPE_OPERATOR(AACallEdges) 191 PIPE_OPERATOR(AAInterFnReachability) 192 PIPE_OPERATOR(AAPointerInfo) 193 PIPE_OPERATOR(AAAssumptionInfo) 194 PIPE_OPERATOR(AAUnderlyingObjects) 195 PIPE_OPERATOR(AAAddressSpace) 196 PIPE_OPERATOR(AAAllocationInfo) 197 PIPE_OPERATOR(AAIndirectCallInfo) 198 PIPE_OPERATOR(AAGlobalValueInfo) 199 PIPE_OPERATOR(AADenormalFPMath) 200 201 #undef PIPE_OPERATOR 202 203 template <> 204 ChangeStatus clampStateAndIndicateChange<DerefState>(DerefState &S, 205 const DerefState &R) { 206 ChangeStatus CS0 = 207 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState); 208 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState); 209 return CS0 | CS1; 210 } 211 212 } // namespace llvm 213 214 static bool mayBeInCycle(const CycleInfo *CI, const Instruction *I, 215 bool HeaderOnly, Cycle **CPtr = nullptr) { 216 if (!CI) 217 return true; 218 auto *BB = I->getParent(); 219 auto *C = CI->getCycle(BB); 220 if (!C) 221 return false; 222 if (CPtr) 223 *CPtr = C; 224 return !HeaderOnly || BB == C->getHeader(); 225 } 226 227 /// Checks if a type could have padding bytes. 228 static bool isDenselyPacked(Type *Ty, const DataLayout &DL) { 229 // There is no size information, so be conservative. 230 if (!Ty->isSized()) 231 return false; 232 233 // If the alloc size is not equal to the storage size, then there are padding 234 // bytes. For x86_fp80 on x86-64, size: 80 alloc size: 128. 235 if (DL.getTypeSizeInBits(Ty) != DL.getTypeAllocSizeInBits(Ty)) 236 return false; 237 238 // FIXME: This isn't the right way to check for padding in vectors with 239 // non-byte-size elements. 240 if (VectorType *SeqTy = dyn_cast<VectorType>(Ty)) 241 return isDenselyPacked(SeqTy->getElementType(), DL); 242 243 // For array types, check for padding within members. 244 if (ArrayType *SeqTy = dyn_cast<ArrayType>(Ty)) 245 return isDenselyPacked(SeqTy->getElementType(), DL); 246 247 if (!isa<StructType>(Ty)) 248 return true; 249 250 // Check for padding within and between elements of a struct. 251 StructType *StructTy = cast<StructType>(Ty); 252 const StructLayout *Layout = DL.getStructLayout(StructTy); 253 uint64_t StartPos = 0; 254 for (unsigned I = 0, E = StructTy->getNumElements(); I < E; ++I) { 255 Type *ElTy = StructTy->getElementType(I); 256 if (!isDenselyPacked(ElTy, DL)) 257 return false; 258 if (StartPos != Layout->getElementOffsetInBits(I)) 259 return false; 260 StartPos += DL.getTypeAllocSizeInBits(ElTy); 261 } 262 263 return true; 264 } 265 266 /// Get pointer operand of memory accessing instruction. If \p I is 267 /// not a memory accessing instruction, return nullptr. If \p AllowVolatile, 268 /// is set to false and the instruction is volatile, return nullptr. 269 static const Value *getPointerOperand(const Instruction *I, 270 bool AllowVolatile) { 271 if (!AllowVolatile && I->isVolatile()) 272 return nullptr; 273 274 if (auto *LI = dyn_cast<LoadInst>(I)) { 275 return LI->getPointerOperand(); 276 } 277 278 if (auto *SI = dyn_cast<StoreInst>(I)) { 279 return SI->getPointerOperand(); 280 } 281 282 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(I)) { 283 return CXI->getPointerOperand(); 284 } 285 286 if (auto *RMWI = dyn_cast<AtomicRMWInst>(I)) { 287 return RMWI->getPointerOperand(); 288 } 289 290 return nullptr; 291 } 292 293 /// Helper function to create a pointer based on \p Ptr, and advanced by \p 294 /// Offset bytes. 295 static Value *constructPointer(Value *Ptr, int64_t Offset, 296 IRBuilder<NoFolder> &IRB) { 297 LLVM_DEBUG(dbgs() << "Construct pointer: " << *Ptr << " + " << Offset 298 << "-bytes\n"); 299 300 if (Offset) 301 Ptr = IRB.CreatePtrAdd(Ptr, IRB.getInt64(Offset), 302 Ptr->getName() + ".b" + Twine(Offset)); 303 return Ptr; 304 } 305 306 static const Value * 307 stripAndAccumulateOffsets(Attributor &A, const AbstractAttribute &QueryingAA, 308 const Value *Val, const DataLayout &DL, APInt &Offset, 309 bool GetMinOffset, bool AllowNonInbounds, 310 bool UseAssumed = false) { 311 312 auto AttributorAnalysis = [&](Value &V, APInt &ROffset) -> bool { 313 const IRPosition &Pos = IRPosition::value(V); 314 // Only track dependence if we are going to use the assumed info. 315 const AAValueConstantRange *ValueConstantRangeAA = 316 A.getAAFor<AAValueConstantRange>(QueryingAA, Pos, 317 UseAssumed ? DepClassTy::OPTIONAL 318 : DepClassTy::NONE); 319 if (!ValueConstantRangeAA) 320 return false; 321 ConstantRange Range = UseAssumed ? ValueConstantRangeAA->getAssumed() 322 : ValueConstantRangeAA->getKnown(); 323 if (Range.isFullSet()) 324 return false; 325 326 // We can only use the lower part of the range because the upper part can 327 // be higher than what the value can really be. 328 if (GetMinOffset) 329 ROffset = Range.getSignedMin(); 330 else 331 ROffset = Range.getSignedMax(); 332 return true; 333 }; 334 335 return Val->stripAndAccumulateConstantOffsets(DL, Offset, AllowNonInbounds, 336 /* AllowInvariant */ true, 337 AttributorAnalysis); 338 } 339 340 static const Value * 341 getMinimalBaseOfPointer(Attributor &A, const AbstractAttribute &QueryingAA, 342 const Value *Ptr, int64_t &BytesOffset, 343 const DataLayout &DL, bool AllowNonInbounds = false) { 344 APInt OffsetAPInt(DL.getIndexTypeSizeInBits(Ptr->getType()), 0); 345 const Value *Base = 346 stripAndAccumulateOffsets(A, QueryingAA, Ptr, DL, OffsetAPInt, 347 /* GetMinOffset */ true, AllowNonInbounds); 348 349 BytesOffset = OffsetAPInt.getSExtValue(); 350 return Base; 351 } 352 353 /// Clamp the information known for all returned values of a function 354 /// (identified by \p QueryingAA) into \p S. 355 template <typename AAType, typename StateType = typename AAType::StateType, 356 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind, 357 bool RecurseForSelectAndPHI = true> 358 static void clampReturnedValueStates( 359 Attributor &A, const AAType &QueryingAA, StateType &S, 360 const IRPosition::CallBaseContext *CBContext = nullptr) { 361 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for " 362 << QueryingAA << " into " << S << "\n"); 363 364 assert((QueryingAA.getIRPosition().getPositionKind() == 365 IRPosition::IRP_RETURNED || 366 QueryingAA.getIRPosition().getPositionKind() == 367 IRPosition::IRP_CALL_SITE_RETURNED) && 368 "Can only clamp returned value states for a function returned or call " 369 "site returned position!"); 370 371 // Use an optional state as there might not be any return values and we want 372 // to join (IntegerState::operator&) the state of all there are. 373 std::optional<StateType> T; 374 375 // Callback for each possibly returned value. 376 auto CheckReturnValue = [&](Value &RV) -> bool { 377 const IRPosition &RVPos = IRPosition::value(RV, CBContext); 378 // If possible, use the hasAssumedIRAttr interface. 379 if (Attribute::isEnumAttrKind(IRAttributeKind)) { 380 bool IsKnown; 381 return AA::hasAssumedIRAttr<IRAttributeKind>( 382 A, &QueryingAA, RVPos, DepClassTy::REQUIRED, IsKnown); 383 } 384 385 const AAType *AA = 386 A.getAAFor<AAType>(QueryingAA, RVPos, DepClassTy::REQUIRED); 387 if (!AA) 388 return false; 389 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV 390 << " AA: " << AA->getAsStr(&A) << " @ " << RVPos << "\n"); 391 const StateType &AAS = AA->getState(); 392 if (!T) 393 T = StateType::getBestState(AAS); 394 *T &= AAS; 395 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T 396 << "\n"); 397 return T->isValidState(); 398 }; 399 400 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA, 401 AA::ValueScope::Intraprocedural, 402 RecurseForSelectAndPHI)) 403 S.indicatePessimisticFixpoint(); 404 else if (T) 405 S ^= *T; 406 } 407 408 namespace { 409 /// Helper class for generic deduction: return value -> returned position. 410 template <typename AAType, typename BaseType, 411 typename StateType = typename BaseType::StateType, 412 bool PropagateCallBaseContext = false, 413 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind, 414 bool RecurseForSelectAndPHI = true> 415 struct AAReturnedFromReturnedValues : public BaseType { 416 AAReturnedFromReturnedValues(const IRPosition &IRP, Attributor &A) 417 : BaseType(IRP, A) {} 418 419 /// See AbstractAttribute::updateImpl(...). 420 ChangeStatus updateImpl(Attributor &A) override { 421 StateType S(StateType::getBestState(this->getState())); 422 clampReturnedValueStates<AAType, StateType, IRAttributeKind, 423 RecurseForSelectAndPHI>( 424 A, *this, S, 425 PropagateCallBaseContext ? this->getCallBaseContext() : nullptr); 426 // TODO: If we know we visited all returned values, thus no are assumed 427 // dead, we can take the known information from the state T. 428 return clampStateAndIndicateChange<StateType>(this->getState(), S); 429 } 430 }; 431 432 /// Clamp the information known at all call sites for a given argument 433 /// (identified by \p QueryingAA) into \p S. 434 template <typename AAType, typename StateType = typename AAType::StateType, 435 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind> 436 static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA, 437 StateType &S) { 438 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for " 439 << QueryingAA << " into " << S << "\n"); 440 441 assert(QueryingAA.getIRPosition().getPositionKind() == 442 IRPosition::IRP_ARGUMENT && 443 "Can only clamp call site argument states for an argument position!"); 444 445 // Use an optional state as there might not be any return values and we want 446 // to join (IntegerState::operator&) the state of all there are. 447 std::optional<StateType> T; 448 449 // The argument number which is also the call site argument number. 450 unsigned ArgNo = QueryingAA.getIRPosition().getCallSiteArgNo(); 451 452 auto CallSiteCheck = [&](AbstractCallSite ACS) { 453 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo); 454 // Check if a coresponding argument was found or if it is on not associated 455 // (which can happen for callback calls). 456 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID) 457 return false; 458 459 // If possible, use the hasAssumedIRAttr interface. 460 if (Attribute::isEnumAttrKind(IRAttributeKind)) { 461 bool IsKnown; 462 return AA::hasAssumedIRAttr<IRAttributeKind>( 463 A, &QueryingAA, ACSArgPos, DepClassTy::REQUIRED, IsKnown); 464 } 465 466 const AAType *AA = 467 A.getAAFor<AAType>(QueryingAA, ACSArgPos, DepClassTy::REQUIRED); 468 if (!AA) 469 return false; 470 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction() 471 << " AA: " << AA->getAsStr(&A) << " @" << ACSArgPos 472 << "\n"); 473 const StateType &AAS = AA->getState(); 474 if (!T) 475 T = StateType::getBestState(AAS); 476 *T &= AAS; 477 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T 478 << "\n"); 479 return T->isValidState(); 480 }; 481 482 bool UsedAssumedInformation = false; 483 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true, 484 UsedAssumedInformation)) 485 S.indicatePessimisticFixpoint(); 486 else if (T) 487 S ^= *T; 488 } 489 490 /// This function is the bridge between argument position and the call base 491 /// context. 492 template <typename AAType, typename BaseType, 493 typename StateType = typename AAType::StateType, 494 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind> 495 bool getArgumentStateFromCallBaseContext(Attributor &A, 496 BaseType &QueryingAttribute, 497 IRPosition &Pos, StateType &State) { 498 assert((Pos.getPositionKind() == IRPosition::IRP_ARGUMENT) && 499 "Expected an 'argument' position !"); 500 const CallBase *CBContext = Pos.getCallBaseContext(); 501 if (!CBContext) 502 return false; 503 504 int ArgNo = Pos.getCallSiteArgNo(); 505 assert(ArgNo >= 0 && "Invalid Arg No!"); 506 const IRPosition CBArgPos = IRPosition::callsite_argument(*CBContext, ArgNo); 507 508 // If possible, use the hasAssumedIRAttr interface. 509 if (Attribute::isEnumAttrKind(IRAttributeKind)) { 510 bool IsKnown; 511 return AA::hasAssumedIRAttr<IRAttributeKind>( 512 A, &QueryingAttribute, CBArgPos, DepClassTy::REQUIRED, IsKnown); 513 } 514 515 const auto *AA = 516 A.getAAFor<AAType>(QueryingAttribute, CBArgPos, DepClassTy::REQUIRED); 517 if (!AA) 518 return false; 519 const StateType &CBArgumentState = 520 static_cast<const StateType &>(AA->getState()); 521 522 LLVM_DEBUG(dbgs() << "[Attributor] Briding Call site context to argument" 523 << "Position:" << Pos << "CB Arg state:" << CBArgumentState 524 << "\n"); 525 526 // NOTE: If we want to do call site grouping it should happen here. 527 State ^= CBArgumentState; 528 return true; 529 } 530 531 /// Helper class for generic deduction: call site argument -> argument position. 532 template <typename AAType, typename BaseType, 533 typename StateType = typename AAType::StateType, 534 bool BridgeCallBaseContext = false, 535 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind> 536 struct AAArgumentFromCallSiteArguments : public BaseType { 537 AAArgumentFromCallSiteArguments(const IRPosition &IRP, Attributor &A) 538 : BaseType(IRP, A) {} 539 540 /// See AbstractAttribute::updateImpl(...). 541 ChangeStatus updateImpl(Attributor &A) override { 542 StateType S = StateType::getBestState(this->getState()); 543 544 if (BridgeCallBaseContext) { 545 bool Success = 546 getArgumentStateFromCallBaseContext<AAType, BaseType, StateType, 547 IRAttributeKind>( 548 A, *this, this->getIRPosition(), S); 549 if (Success) 550 return clampStateAndIndicateChange<StateType>(this->getState(), S); 551 } 552 clampCallSiteArgumentStates<AAType, StateType, IRAttributeKind>(A, *this, 553 S); 554 555 // TODO: If we know we visited all incoming values, thus no are assumed 556 // dead, we can take the known information from the state T. 557 return clampStateAndIndicateChange<StateType>(this->getState(), S); 558 } 559 }; 560 561 /// Helper class for generic replication: function returned -> cs returned. 562 template <typename AAType, typename BaseType, 563 typename StateType = typename BaseType::StateType, 564 bool IntroduceCallBaseContext = false, 565 Attribute::AttrKind IRAttributeKind = AAType::IRAttributeKind> 566 struct AACalleeToCallSite : public BaseType { 567 AACalleeToCallSite(const IRPosition &IRP, Attributor &A) : BaseType(IRP, A) {} 568 569 /// See AbstractAttribute::updateImpl(...). 570 ChangeStatus updateImpl(Attributor &A) override { 571 auto IRPKind = this->getIRPosition().getPositionKind(); 572 assert((IRPKind == IRPosition::IRP_CALL_SITE_RETURNED || 573 IRPKind == IRPosition::IRP_CALL_SITE) && 574 "Can only wrap function returned positions for call site " 575 "returned positions!"); 576 auto &S = this->getState(); 577 578 CallBase &CB = cast<CallBase>(this->getAnchorValue()); 579 if (IntroduceCallBaseContext) 580 LLVM_DEBUG(dbgs() << "[Attributor] Introducing call base context:" << CB 581 << "\n"); 582 583 ChangeStatus Changed = ChangeStatus::UNCHANGED; 584 auto CalleePred = [&](ArrayRef<const Function *> Callees) { 585 for (const Function *Callee : Callees) { 586 IRPosition FnPos = 587 IRPKind == llvm::IRPosition::IRP_CALL_SITE_RETURNED 588 ? IRPosition::returned(*Callee, 589 IntroduceCallBaseContext ? &CB : nullptr) 590 : IRPosition::function( 591 *Callee, IntroduceCallBaseContext ? &CB : nullptr); 592 // If possible, use the hasAssumedIRAttr interface. 593 if (Attribute::isEnumAttrKind(IRAttributeKind)) { 594 bool IsKnown; 595 if (!AA::hasAssumedIRAttr<IRAttributeKind>( 596 A, this, FnPos, DepClassTy::REQUIRED, IsKnown)) 597 return false; 598 continue; 599 } 600 601 const AAType *AA = 602 A.getAAFor<AAType>(*this, FnPos, DepClassTy::REQUIRED); 603 if (!AA) 604 return false; 605 Changed |= clampStateAndIndicateChange(S, AA->getState()); 606 if (S.isAtFixpoint()) 607 return S.isValidState(); 608 } 609 return true; 610 }; 611 if (!A.checkForAllCallees(CalleePred, *this, CB)) 612 return S.indicatePessimisticFixpoint(); 613 return Changed; 614 } 615 }; 616 617 /// Helper function to accumulate uses. 618 template <class AAType, typename StateType = typename AAType::StateType> 619 static void followUsesInContext(AAType &AA, Attributor &A, 620 MustBeExecutedContextExplorer &Explorer, 621 const Instruction *CtxI, 622 SetVector<const Use *> &Uses, 623 StateType &State) { 624 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI); 625 for (unsigned u = 0; u < Uses.size(); ++u) { 626 const Use *U = Uses[u]; 627 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) { 628 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd); 629 if (Found && AA.followUseInMBEC(A, U, UserI, State)) 630 for (const Use &Us : UserI->uses()) 631 Uses.insert(&Us); 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 MustBeExecutedContextExplorer *Explorer = 649 A.getInfoCache().getMustBeExecutedContextExplorer(); 650 if (!Explorer) 651 return; 652 653 // Container for (transitive) uses of the associated value. 654 SetVector<const Use *> Uses; 655 for (const Use &U : AA.getIRPosition().getAssociatedValue().uses()) 656 Uses.insert(&U); 657 658 followUsesInContext<AAType>(AA, A, *Explorer, &CtxI, Uses, S); 659 660 if (S.isAtFixpoint()) 661 return; 662 663 SmallVector<const BranchInst *, 4> BrInsts; 664 auto Pred = [&](const Instruction *I) { 665 if (const BranchInst *Br = dyn_cast<BranchInst>(I)) 666 if (Br->isConditional()) 667 BrInsts.push_back(Br); 668 return true; 669 }; 670 671 // Here, accumulate conditional branch instructions in the context. We 672 // explore the child paths and collect the known states. The disjunction of 673 // those states can be merged to its own state. Let ParentState_i be a state 674 // to indicate the known information for an i-th branch instruction in the 675 // context. ChildStates are created for its successors respectively. 676 // 677 // ParentS_1 = ChildS_{1, 1} /\ ChildS_{1, 2} /\ ... /\ ChildS_{1, n_1} 678 // ParentS_2 = ChildS_{2, 1} /\ ChildS_{2, 2} /\ ... /\ ChildS_{2, n_2} 679 // ... 680 // ParentS_m = ChildS_{m, 1} /\ ChildS_{m, 2} /\ ... /\ ChildS_{m, n_m} 681 // 682 // Known State |= ParentS_1 \/ ParentS_2 \/... \/ ParentS_m 683 // 684 // FIXME: Currently, recursive branches are not handled. For example, we 685 // can't deduce that ptr must be dereferenced in below function. 686 // 687 // void f(int a, int c, int *ptr) { 688 // if(a) 689 // if (b) { 690 // *ptr = 0; 691 // } else { 692 // *ptr = 1; 693 // } 694 // else { 695 // if (b) { 696 // *ptr = 0; 697 // } else { 698 // *ptr = 1; 699 // } 700 // } 701 // } 702 703 Explorer->checkForAllContext(&CtxI, Pred); 704 for (const BranchInst *Br : BrInsts) { 705 StateType ParentState; 706 707 // The known state of the parent state is a conjunction of children's 708 // known states so it is initialized with a best state. 709 ParentState.indicateOptimisticFixpoint(); 710 711 for (const BasicBlock *BB : Br->successors()) { 712 StateType ChildState; 713 714 size_t BeforeSize = Uses.size(); 715 followUsesInContext(AA, A, *Explorer, &BB->front(), Uses, ChildState); 716 717 // Erase uses which only appear in the child. 718 for (auto It = Uses.begin() + BeforeSize; It != Uses.end();) 719 It = Uses.erase(It); 720 721 ParentState &= ChildState; 722 } 723 724 // Use only known state. 725 S += ParentState; 726 } 727 } 728 } // namespace 729 730 /// ------------------------ PointerInfo --------------------------------------- 731 732 namespace llvm { 733 namespace AA { 734 namespace PointerInfo { 735 736 struct State; 737 738 } // namespace PointerInfo 739 } // namespace AA 740 741 /// Helper for AA::PointerInfo::Access DenseMap/Set usage. 742 template <> 743 struct DenseMapInfo<AAPointerInfo::Access> : DenseMapInfo<Instruction *> { 744 using Access = AAPointerInfo::Access; 745 static inline Access getEmptyKey(); 746 static inline Access getTombstoneKey(); 747 static unsigned getHashValue(const Access &A); 748 static bool isEqual(const Access &LHS, const Access &RHS); 749 }; 750 751 /// Helper that allows RangeTy as a key in a DenseMap. 752 template <> struct DenseMapInfo<AA::RangeTy> { 753 static inline AA::RangeTy getEmptyKey() { 754 auto EmptyKey = DenseMapInfo<int64_t>::getEmptyKey(); 755 return AA::RangeTy{EmptyKey, EmptyKey}; 756 } 757 758 static inline AA::RangeTy getTombstoneKey() { 759 auto TombstoneKey = DenseMapInfo<int64_t>::getTombstoneKey(); 760 return AA::RangeTy{TombstoneKey, TombstoneKey}; 761 } 762 763 static unsigned getHashValue(const AA::RangeTy &Range) { 764 return detail::combineHashValue( 765 DenseMapInfo<int64_t>::getHashValue(Range.Offset), 766 DenseMapInfo<int64_t>::getHashValue(Range.Size)); 767 } 768 769 static bool isEqual(const AA::RangeTy &A, const AA::RangeTy B) { 770 return A == B; 771 } 772 }; 773 774 /// Helper for AA::PointerInfo::Access DenseMap/Set usage ignoring everythign 775 /// but the instruction 776 struct AccessAsInstructionInfo : DenseMapInfo<Instruction *> { 777 using Base = DenseMapInfo<Instruction *>; 778 using Access = AAPointerInfo::Access; 779 static inline Access getEmptyKey(); 780 static inline Access getTombstoneKey(); 781 static unsigned getHashValue(const Access &A); 782 static bool isEqual(const Access &LHS, const Access &RHS); 783 }; 784 785 } // namespace llvm 786 787 /// A type to track pointer/struct usage and accesses for AAPointerInfo. 788 struct AA::PointerInfo::State : public AbstractState { 789 /// Return the best possible representable state. 790 static State getBestState(const State &SIS) { return State(); } 791 792 /// Return the worst possible representable state. 793 static State getWorstState(const State &SIS) { 794 State R; 795 R.indicatePessimisticFixpoint(); 796 return R; 797 } 798 799 State() = default; 800 State(State &&SIS) = default; 801 802 const State &getAssumed() const { return *this; } 803 804 /// See AbstractState::isValidState(). 805 bool isValidState() const override { return BS.isValidState(); } 806 807 /// See AbstractState::isAtFixpoint(). 808 bool isAtFixpoint() const override { return BS.isAtFixpoint(); } 809 810 /// See AbstractState::indicateOptimisticFixpoint(). 811 ChangeStatus indicateOptimisticFixpoint() override { 812 BS.indicateOptimisticFixpoint(); 813 return ChangeStatus::UNCHANGED; 814 } 815 816 /// See AbstractState::indicatePessimisticFixpoint(). 817 ChangeStatus indicatePessimisticFixpoint() override { 818 BS.indicatePessimisticFixpoint(); 819 return ChangeStatus::CHANGED; 820 } 821 822 State &operator=(const State &R) { 823 if (this == &R) 824 return *this; 825 BS = R.BS; 826 AccessList = R.AccessList; 827 OffsetBins = R.OffsetBins; 828 RemoteIMap = R.RemoteIMap; 829 return *this; 830 } 831 832 State &operator=(State &&R) { 833 if (this == &R) 834 return *this; 835 std::swap(BS, R.BS); 836 std::swap(AccessList, R.AccessList); 837 std::swap(OffsetBins, R.OffsetBins); 838 std::swap(RemoteIMap, R.RemoteIMap); 839 return *this; 840 } 841 842 /// Add a new Access to the state at offset \p Offset and with size \p Size. 843 /// The access is associated with \p I, writes \p Content (if anything), and 844 /// is of kind \p Kind. If an Access already exists for the same \p I and same 845 /// \p RemoteI, the two are combined, potentially losing information about 846 /// offset and size. The resulting access must now be moved from its original 847 /// OffsetBin to the bin for its new offset. 848 /// 849 /// \Returns CHANGED, if the state changed, UNCHANGED otherwise. 850 ChangeStatus addAccess(Attributor &A, const AAPointerInfo::RangeList &Ranges, 851 Instruction &I, std::optional<Value *> Content, 852 AAPointerInfo::AccessKind Kind, Type *Ty, 853 Instruction *RemoteI = nullptr); 854 855 AAPointerInfo::const_bin_iterator begin() const { return OffsetBins.begin(); } 856 AAPointerInfo::const_bin_iterator end() const { return OffsetBins.end(); } 857 int64_t numOffsetBins() const { return OffsetBins.size(); } 858 859 const AAPointerInfo::Access &getAccess(unsigned Index) const { 860 return AccessList[Index]; 861 } 862 863 protected: 864 // Every memory instruction results in an Access object. We maintain a list of 865 // all Access objects that we own, along with the following maps: 866 // 867 // - OffsetBins: RangeTy -> { Access } 868 // - RemoteIMap: RemoteI x LocalI -> Access 869 // 870 // A RemoteI is any instruction that accesses memory. RemoteI is different 871 // from LocalI if and only if LocalI is a call; then RemoteI is some 872 // instruction in the callgraph starting from LocalI. Multiple paths in the 873 // callgraph from LocalI to RemoteI may produce multiple accesses, but these 874 // are all combined into a single Access object. This may result in loss of 875 // information in RangeTy in the Access object. 876 SmallVector<AAPointerInfo::Access> AccessList; 877 AAPointerInfo::OffsetBinsTy OffsetBins; 878 DenseMap<const Instruction *, SmallVector<unsigned>> RemoteIMap; 879 880 /// See AAPointerInfo::forallInterferingAccesses. 881 bool forallInterferingAccesses( 882 AA::RangeTy Range, 883 function_ref<bool(const AAPointerInfo::Access &, bool)> CB) const { 884 if (!isValidState()) 885 return false; 886 887 for (const auto &It : OffsetBins) { 888 AA::RangeTy ItRange = It.getFirst(); 889 if (!Range.mayOverlap(ItRange)) 890 continue; 891 bool IsExact = Range == ItRange && !Range.offsetOrSizeAreUnknown(); 892 for (auto Index : It.getSecond()) { 893 auto &Access = AccessList[Index]; 894 if (!CB(Access, IsExact)) 895 return false; 896 } 897 } 898 return true; 899 } 900 901 /// See AAPointerInfo::forallInterferingAccesses. 902 bool forallInterferingAccesses( 903 Instruction &I, 904 function_ref<bool(const AAPointerInfo::Access &, bool)> CB, 905 AA::RangeTy &Range) const { 906 if (!isValidState()) 907 return false; 908 909 auto LocalList = RemoteIMap.find(&I); 910 if (LocalList == RemoteIMap.end()) { 911 return true; 912 } 913 914 for (unsigned Index : LocalList->getSecond()) { 915 for (auto &R : AccessList[Index]) { 916 Range &= R; 917 if (Range.offsetAndSizeAreUnknown()) 918 break; 919 } 920 } 921 return forallInterferingAccesses(Range, CB); 922 } 923 924 private: 925 /// State to track fixpoint and validity. 926 BooleanState BS; 927 }; 928 929 ChangeStatus AA::PointerInfo::State::addAccess( 930 Attributor &A, const AAPointerInfo::RangeList &Ranges, Instruction &I, 931 std::optional<Value *> Content, AAPointerInfo::AccessKind Kind, Type *Ty, 932 Instruction *RemoteI) { 933 RemoteI = RemoteI ? RemoteI : &I; 934 935 // Check if we have an access for this instruction, if not, simply add it. 936 auto &LocalList = RemoteIMap[RemoteI]; 937 bool AccExists = false; 938 unsigned AccIndex = AccessList.size(); 939 for (auto Index : LocalList) { 940 auto &A = AccessList[Index]; 941 if (A.getLocalInst() == &I) { 942 AccExists = true; 943 AccIndex = Index; 944 break; 945 } 946 } 947 948 auto AddToBins = [&](const AAPointerInfo::RangeList &ToAdd) { 949 LLVM_DEBUG(if (ToAdd.size()) dbgs() 950 << "[AAPointerInfo] Inserting access in new offset bins\n";); 951 952 for (auto Key : ToAdd) { 953 LLVM_DEBUG(dbgs() << " key " << Key << "\n"); 954 OffsetBins[Key].insert(AccIndex); 955 } 956 }; 957 958 if (!AccExists) { 959 AccessList.emplace_back(&I, RemoteI, Ranges, Content, Kind, Ty); 960 assert((AccessList.size() == AccIndex + 1) && 961 "New Access should have been at AccIndex"); 962 LocalList.push_back(AccIndex); 963 AddToBins(AccessList[AccIndex].getRanges()); 964 return ChangeStatus::CHANGED; 965 } 966 967 // Combine the new Access with the existing Access, and then update the 968 // mapping in the offset bins. 969 AAPointerInfo::Access Acc(&I, RemoteI, Ranges, Content, Kind, Ty); 970 auto &Current = AccessList[AccIndex]; 971 auto Before = Current; 972 Current &= Acc; 973 if (Current == Before) 974 return ChangeStatus::UNCHANGED; 975 976 auto &ExistingRanges = Before.getRanges(); 977 auto &NewRanges = Current.getRanges(); 978 979 // Ranges that are in the old access but not the new access need to be removed 980 // from the offset bins. 981 AAPointerInfo::RangeList ToRemove; 982 AAPointerInfo::RangeList::set_difference(ExistingRanges, NewRanges, ToRemove); 983 LLVM_DEBUG(if (ToRemove.size()) dbgs() 984 << "[AAPointerInfo] Removing access from old offset bins\n";); 985 986 for (auto Key : ToRemove) { 987 LLVM_DEBUG(dbgs() << " key " << Key << "\n"); 988 assert(OffsetBins.count(Key) && "Existing Access must be in some bin."); 989 auto &Bin = OffsetBins[Key]; 990 assert(Bin.count(AccIndex) && 991 "Expected bin to actually contain the Access."); 992 Bin.erase(AccIndex); 993 } 994 995 // Ranges that are in the new access but not the old access need to be added 996 // to the offset bins. 997 AAPointerInfo::RangeList ToAdd; 998 AAPointerInfo::RangeList::set_difference(NewRanges, ExistingRanges, ToAdd); 999 AddToBins(ToAdd); 1000 return ChangeStatus::CHANGED; 1001 } 1002 1003 namespace { 1004 1005 /// A helper containing a list of offsets computed for a Use. Ideally this 1006 /// list should be strictly ascending, but we ensure that only when we 1007 /// actually translate the list of offsets to a RangeList. 1008 struct OffsetInfo { 1009 using VecTy = SmallVector<int64_t>; 1010 using const_iterator = VecTy::const_iterator; 1011 VecTy Offsets; 1012 1013 const_iterator begin() const { return Offsets.begin(); } 1014 const_iterator end() const { return Offsets.end(); } 1015 1016 bool operator==(const OffsetInfo &RHS) const { 1017 return Offsets == RHS.Offsets; 1018 } 1019 1020 bool operator!=(const OffsetInfo &RHS) const { return !(*this == RHS); } 1021 1022 void insert(int64_t Offset) { Offsets.push_back(Offset); } 1023 bool isUnassigned() const { return Offsets.size() == 0; } 1024 1025 bool isUnknown() const { 1026 if (isUnassigned()) 1027 return false; 1028 if (Offsets.size() == 1) 1029 return Offsets.front() == AA::RangeTy::Unknown; 1030 return false; 1031 } 1032 1033 void setUnknown() { 1034 Offsets.clear(); 1035 Offsets.push_back(AA::RangeTy::Unknown); 1036 } 1037 1038 void addToAll(int64_t Inc) { 1039 for (auto &Offset : Offsets) { 1040 Offset += Inc; 1041 } 1042 } 1043 1044 /// Copy offsets from \p R into the current list. 1045 /// 1046 /// Ideally all lists should be strictly ascending, but we defer that to the 1047 /// actual use of the list. So we just blindly append here. 1048 void merge(const OffsetInfo &R) { Offsets.append(R.Offsets); } 1049 }; 1050 1051 #ifndef NDEBUG 1052 static raw_ostream &operator<<(raw_ostream &OS, const OffsetInfo &OI) { 1053 ListSeparator LS; 1054 OS << "["; 1055 for (auto Offset : OI) { 1056 OS << LS << Offset; 1057 } 1058 OS << "]"; 1059 return OS; 1060 } 1061 #endif // NDEBUG 1062 1063 struct AAPointerInfoImpl 1064 : public StateWrapper<AA::PointerInfo::State, AAPointerInfo> { 1065 using BaseTy = StateWrapper<AA::PointerInfo::State, AAPointerInfo>; 1066 AAPointerInfoImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {} 1067 1068 /// See AbstractAttribute::getAsStr(). 1069 const std::string getAsStr(Attributor *A) const override { 1070 return std::string("PointerInfo ") + 1071 (isValidState() ? (std::string("#") + 1072 std::to_string(OffsetBins.size()) + " bins") 1073 : "<invalid>"); 1074 } 1075 1076 /// See AbstractAttribute::manifest(...). 1077 ChangeStatus manifest(Attributor &A) override { 1078 return AAPointerInfo::manifest(A); 1079 } 1080 1081 virtual const_bin_iterator begin() const override { return State::begin(); } 1082 virtual const_bin_iterator end() const override { return State::end(); } 1083 virtual int64_t numOffsetBins() const override { 1084 return State::numOffsetBins(); 1085 } 1086 1087 bool forallInterferingAccesses( 1088 AA::RangeTy Range, 1089 function_ref<bool(const AAPointerInfo::Access &, bool)> CB) 1090 const override { 1091 return State::forallInterferingAccesses(Range, CB); 1092 } 1093 1094 bool forallInterferingAccesses( 1095 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I, 1096 bool FindInterferingWrites, bool FindInterferingReads, 1097 function_ref<bool(const Access &, bool)> UserCB, bool &HasBeenWrittenTo, 1098 AA::RangeTy &Range, 1099 function_ref<bool(const Access &)> SkipCB) const override { 1100 HasBeenWrittenTo = false; 1101 1102 SmallPtrSet<const Access *, 8> DominatingWrites; 1103 SmallVector<std::pair<const Access *, bool>, 8> InterferingAccesses; 1104 1105 Function &Scope = *I.getFunction(); 1106 bool IsKnownNoSync; 1107 bool IsAssumedNoSync = AA::hasAssumedIRAttr<Attribute::NoSync>( 1108 A, &QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL, 1109 IsKnownNoSync); 1110 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>( 1111 IRPosition::function(Scope), &QueryingAA, DepClassTy::NONE); 1112 bool AllInSameNoSyncFn = IsAssumedNoSync; 1113 bool InstIsExecutedByInitialThreadOnly = 1114 ExecDomainAA && ExecDomainAA->isExecutedByInitialThreadOnly(I); 1115 1116 // If the function is not ending in aligned barriers, we need the stores to 1117 // be in aligned barriers. The load being in one is not sufficient since the 1118 // store might be executed by a thread that disappears after, causing the 1119 // aligned barrier guarding the load to unblock and the load to read a value 1120 // that has no CFG path to the load. 1121 bool InstIsExecutedInAlignedRegion = 1122 FindInterferingReads && ExecDomainAA && 1123 ExecDomainAA->isExecutedInAlignedRegion(A, I); 1124 1125 if (InstIsExecutedInAlignedRegion || InstIsExecutedByInitialThreadOnly) 1126 A.recordDependence(*ExecDomainAA, QueryingAA, DepClassTy::OPTIONAL); 1127 1128 InformationCache &InfoCache = A.getInfoCache(); 1129 bool IsThreadLocalObj = 1130 AA::isAssumedThreadLocalObject(A, getAssociatedValue(), *this); 1131 1132 // Helper to determine if we need to consider threading, which we cannot 1133 // right now. However, if the function is (assumed) nosync or the thread 1134 // executing all instructions is the main thread only we can ignore 1135 // threading. Also, thread-local objects do not require threading reasoning. 1136 // Finally, we can ignore threading if either access is executed in an 1137 // aligned region. 1138 auto CanIgnoreThreadingForInst = [&](const Instruction &I) -> bool { 1139 if (IsThreadLocalObj || AllInSameNoSyncFn) 1140 return true; 1141 const auto *FnExecDomainAA = 1142 I.getFunction() == &Scope 1143 ? ExecDomainAA 1144 : A.lookupAAFor<AAExecutionDomain>( 1145 IRPosition::function(*I.getFunction()), &QueryingAA, 1146 DepClassTy::NONE); 1147 if (!FnExecDomainAA) 1148 return false; 1149 if (InstIsExecutedInAlignedRegion || 1150 (FindInterferingWrites && 1151 FnExecDomainAA->isExecutedInAlignedRegion(A, I))) { 1152 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL); 1153 return true; 1154 } 1155 if (InstIsExecutedByInitialThreadOnly && 1156 FnExecDomainAA->isExecutedByInitialThreadOnly(I)) { 1157 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL); 1158 return true; 1159 } 1160 return false; 1161 }; 1162 1163 // Helper to determine if the access is executed by the same thread as the 1164 // given instruction, for now it is sufficient to avoid any potential 1165 // threading effects as we cannot deal with them anyway. 1166 auto CanIgnoreThreading = [&](const Access &Acc) -> bool { 1167 return CanIgnoreThreadingForInst(*Acc.getRemoteInst()) || 1168 (Acc.getRemoteInst() != Acc.getLocalInst() && 1169 CanIgnoreThreadingForInst(*Acc.getLocalInst())); 1170 }; 1171 1172 // TODO: Use inter-procedural reachability and dominance. 1173 bool IsKnownNoRecurse; 1174 AA::hasAssumedIRAttr<Attribute::NoRecurse>( 1175 A, this, IRPosition::function(Scope), DepClassTy::OPTIONAL, 1176 IsKnownNoRecurse); 1177 1178 // TODO: Use reaching kernels from AAKernelInfo (or move it to 1179 // AAExecutionDomain) such that we allow scopes other than kernels as long 1180 // as the reaching kernels are disjoint. 1181 bool InstInKernel = Scope.hasFnAttribute("kernel"); 1182 bool ObjHasKernelLifetime = false; 1183 const bool UseDominanceReasoning = 1184 FindInterferingWrites && IsKnownNoRecurse; 1185 const DominatorTree *DT = 1186 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(Scope); 1187 1188 // Helper to check if a value has "kernel lifetime", that is it will not 1189 // outlive a GPU kernel. This is true for shared, constant, and local 1190 // globals on AMD and NVIDIA GPUs. 1191 auto HasKernelLifetime = [&](Value *V, Module &M) { 1192 if (!AA::isGPU(M)) 1193 return false; 1194 switch (AA::GPUAddressSpace(V->getType()->getPointerAddressSpace())) { 1195 case AA::GPUAddressSpace::Shared: 1196 case AA::GPUAddressSpace::Constant: 1197 case AA::GPUAddressSpace::Local: 1198 return true; 1199 default: 1200 return false; 1201 }; 1202 }; 1203 1204 // The IsLiveInCalleeCB will be used by the AA::isPotentiallyReachable query 1205 // to determine if we should look at reachability from the callee. For 1206 // certain pointers we know the lifetime and we do not have to step into the 1207 // callee to determine reachability as the pointer would be dead in the 1208 // callee. See the conditional initialization below. 1209 std::function<bool(const Function &)> IsLiveInCalleeCB; 1210 1211 if (auto *AI = dyn_cast<AllocaInst>(&getAssociatedValue())) { 1212 // If the alloca containing function is not recursive the alloca 1213 // must be dead in the callee. 1214 const Function *AIFn = AI->getFunction(); 1215 ObjHasKernelLifetime = AIFn->hasFnAttribute("kernel"); 1216 bool IsKnownNoRecurse; 1217 if (AA::hasAssumedIRAttr<Attribute::NoRecurse>( 1218 A, this, IRPosition::function(*AIFn), DepClassTy::OPTIONAL, 1219 IsKnownNoRecurse)) { 1220 IsLiveInCalleeCB = [AIFn](const Function &Fn) { return AIFn != &Fn; }; 1221 } 1222 } else if (auto *GV = dyn_cast<GlobalValue>(&getAssociatedValue())) { 1223 // If the global has kernel lifetime we can stop if we reach a kernel 1224 // as it is "dead" in the (unknown) callees. 1225 ObjHasKernelLifetime = HasKernelLifetime(GV, *GV->getParent()); 1226 if (ObjHasKernelLifetime) 1227 IsLiveInCalleeCB = [](const Function &Fn) { 1228 return !Fn.hasFnAttribute("kernel"); 1229 }; 1230 } 1231 1232 // Set of accesses/instructions that will overwrite the result and are 1233 // therefore blockers in the reachability traversal. 1234 AA::InstExclusionSetTy ExclusionSet; 1235 1236 auto AccessCB = [&](const Access &Acc, bool Exact) { 1237 Function *AccScope = Acc.getRemoteInst()->getFunction(); 1238 bool AccInSameScope = AccScope == &Scope; 1239 1240 // If the object has kernel lifetime we can ignore accesses only reachable 1241 // by other kernels. For now we only skip accesses *in* other kernels. 1242 if (InstInKernel && ObjHasKernelLifetime && !AccInSameScope && 1243 AccScope->hasFnAttribute("kernel")) 1244 return true; 1245 1246 if (Exact && Acc.isMustAccess() && Acc.getRemoteInst() != &I) { 1247 if (Acc.isWrite() || (isa<LoadInst>(I) && Acc.isWriteOrAssumption())) 1248 ExclusionSet.insert(Acc.getRemoteInst()); 1249 } 1250 1251 if ((!FindInterferingWrites || !Acc.isWriteOrAssumption()) && 1252 (!FindInterferingReads || !Acc.isRead())) 1253 return true; 1254 1255 bool Dominates = FindInterferingWrites && DT && Exact && 1256 Acc.isMustAccess() && AccInSameScope && 1257 DT->dominates(Acc.getRemoteInst(), &I); 1258 if (Dominates) 1259 DominatingWrites.insert(&Acc); 1260 1261 // Track if all interesting accesses are in the same `nosync` function as 1262 // the given instruction. 1263 AllInSameNoSyncFn &= Acc.getRemoteInst()->getFunction() == &Scope; 1264 1265 InterferingAccesses.push_back({&Acc, Exact}); 1266 return true; 1267 }; 1268 if (!State::forallInterferingAccesses(I, AccessCB, Range)) 1269 return false; 1270 1271 HasBeenWrittenTo = !DominatingWrites.empty(); 1272 1273 // Dominating writes form a chain, find the least/lowest member. 1274 Instruction *LeastDominatingWriteInst = nullptr; 1275 for (const Access *Acc : DominatingWrites) { 1276 if (!LeastDominatingWriteInst) { 1277 LeastDominatingWriteInst = Acc->getRemoteInst(); 1278 } else if (DT->dominates(LeastDominatingWriteInst, 1279 Acc->getRemoteInst())) { 1280 LeastDominatingWriteInst = Acc->getRemoteInst(); 1281 } 1282 } 1283 1284 // Helper to determine if we can skip a specific write access. 1285 auto CanSkipAccess = [&](const Access &Acc, bool Exact) { 1286 if (SkipCB && SkipCB(Acc)) 1287 return true; 1288 if (!CanIgnoreThreading(Acc)) 1289 return false; 1290 1291 // Check read (RAW) dependences and write (WAR) dependences as necessary. 1292 // If we successfully excluded all effects we are interested in, the 1293 // access can be skipped. 1294 bool ReadChecked = !FindInterferingReads; 1295 bool WriteChecked = !FindInterferingWrites; 1296 1297 // If the instruction cannot reach the access, the former does not 1298 // interfere with what the access reads. 1299 if (!ReadChecked) { 1300 if (!AA::isPotentiallyReachable(A, I, *Acc.getRemoteInst(), QueryingAA, 1301 &ExclusionSet, IsLiveInCalleeCB)) 1302 ReadChecked = true; 1303 } 1304 // If the instruction cannot be reach from the access, the latter does not 1305 // interfere with what the instruction reads. 1306 if (!WriteChecked) { 1307 if (!AA::isPotentiallyReachable(A, *Acc.getRemoteInst(), I, QueryingAA, 1308 &ExclusionSet, IsLiveInCalleeCB)) 1309 WriteChecked = true; 1310 } 1311 1312 // If we still might be affected by the write of the access but there are 1313 // dominating writes in the function of the instruction 1314 // (HasBeenWrittenTo), we can try to reason that the access is overwritten 1315 // by them. This would have happend above if they are all in the same 1316 // function, so we only check the inter-procedural case. Effectively, we 1317 // want to show that there is no call after the dominting write that might 1318 // reach the access, and when it returns reach the instruction with the 1319 // updated value. To this end, we iterate all call sites, check if they 1320 // might reach the instruction without going through another access 1321 // (ExclusionSet) and at the same time might reach the access. However, 1322 // that is all part of AAInterFnReachability. 1323 if (!WriteChecked && HasBeenWrittenTo && 1324 Acc.getRemoteInst()->getFunction() != &Scope) { 1325 1326 const auto *FnReachabilityAA = A.getAAFor<AAInterFnReachability>( 1327 QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL); 1328 1329 // Without going backwards in the call tree, can we reach the access 1330 // from the least dominating write. Do not allow to pass the instruction 1331 // itself either. 1332 bool Inserted = ExclusionSet.insert(&I).second; 1333 1334 if (!FnReachabilityAA || 1335 !FnReachabilityAA->instructionCanReach( 1336 A, *LeastDominatingWriteInst, 1337 *Acc.getRemoteInst()->getFunction(), &ExclusionSet)) 1338 WriteChecked = true; 1339 1340 if (Inserted) 1341 ExclusionSet.erase(&I); 1342 } 1343 1344 if (ReadChecked && WriteChecked) 1345 return true; 1346 1347 if (!DT || !UseDominanceReasoning) 1348 return false; 1349 if (!DominatingWrites.count(&Acc)) 1350 return false; 1351 return LeastDominatingWriteInst != Acc.getRemoteInst(); 1352 }; 1353 1354 // Run the user callback on all accesses we cannot skip and return if 1355 // that succeeded for all or not. 1356 for (auto &It : InterferingAccesses) { 1357 if ((!AllInSameNoSyncFn && !IsThreadLocalObj && !ExecDomainAA) || 1358 !CanSkipAccess(*It.first, It.second)) { 1359 if (!UserCB(*It.first, It.second)) 1360 return false; 1361 } 1362 } 1363 return true; 1364 } 1365 1366 ChangeStatus translateAndAddStateFromCallee(Attributor &A, 1367 const AAPointerInfo &OtherAA, 1368 CallBase &CB) { 1369 using namespace AA::PointerInfo; 1370 if (!OtherAA.getState().isValidState() || !isValidState()) 1371 return indicatePessimisticFixpoint(); 1372 1373 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA); 1374 bool IsByval = OtherAAImpl.getAssociatedArgument()->hasByValAttr(); 1375 1376 // Combine the accesses bin by bin. 1377 ChangeStatus Changed = ChangeStatus::UNCHANGED; 1378 const auto &State = OtherAAImpl.getState(); 1379 for (const auto &It : State) { 1380 for (auto Index : It.getSecond()) { 1381 const auto &RAcc = State.getAccess(Index); 1382 if (IsByval && !RAcc.isRead()) 1383 continue; 1384 bool UsedAssumedInformation = false; 1385 AccessKind AK = RAcc.getKind(); 1386 auto Content = A.translateArgumentToCallSiteContent( 1387 RAcc.getContent(), CB, *this, UsedAssumedInformation); 1388 AK = AccessKind(AK & (IsByval ? AccessKind::AK_R : AccessKind::AK_RW)); 1389 AK = AccessKind(AK | (RAcc.isMayAccess() ? AK_MAY : AK_MUST)); 1390 1391 Changed |= addAccess(A, RAcc.getRanges(), CB, Content, AK, 1392 RAcc.getType(), RAcc.getRemoteInst()); 1393 } 1394 } 1395 return Changed; 1396 } 1397 1398 ChangeStatus translateAndAddState(Attributor &A, const AAPointerInfo &OtherAA, 1399 const OffsetInfo &Offsets, CallBase &CB) { 1400 using namespace AA::PointerInfo; 1401 if (!OtherAA.getState().isValidState() || !isValidState()) 1402 return indicatePessimisticFixpoint(); 1403 1404 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA); 1405 1406 // Combine the accesses bin by bin. 1407 ChangeStatus Changed = ChangeStatus::UNCHANGED; 1408 const auto &State = OtherAAImpl.getState(); 1409 for (const auto &It : State) { 1410 for (auto Index : It.getSecond()) { 1411 const auto &RAcc = State.getAccess(Index); 1412 for (auto Offset : Offsets) { 1413 auto NewRanges = Offset == AA::RangeTy::Unknown 1414 ? AA::RangeTy::getUnknown() 1415 : RAcc.getRanges(); 1416 if (!NewRanges.isUnknown()) { 1417 NewRanges.addToAllOffsets(Offset); 1418 } 1419 Changed |= 1420 addAccess(A, NewRanges, CB, RAcc.getContent(), RAcc.getKind(), 1421 RAcc.getType(), RAcc.getRemoteInst()); 1422 } 1423 } 1424 } 1425 return Changed; 1426 } 1427 1428 /// Statistic tracking for all AAPointerInfo implementations. 1429 /// See AbstractAttribute::trackStatistics(). 1430 void trackPointerInfoStatistics(const IRPosition &IRP) const {} 1431 1432 /// Dump the state into \p O. 1433 void dumpState(raw_ostream &O) { 1434 for (auto &It : OffsetBins) { 1435 O << "[" << It.first.Offset << "-" << It.first.Offset + It.first.Size 1436 << "] : " << It.getSecond().size() << "\n"; 1437 for (auto AccIndex : It.getSecond()) { 1438 auto &Acc = AccessList[AccIndex]; 1439 O << " - " << Acc.getKind() << " - " << *Acc.getLocalInst() << "\n"; 1440 if (Acc.getLocalInst() != Acc.getRemoteInst()) 1441 O << " --> " << *Acc.getRemoteInst() 1442 << "\n"; 1443 if (!Acc.isWrittenValueYetUndetermined()) { 1444 if (isa_and_nonnull<Function>(Acc.getWrittenValue())) 1445 O << " - c: func " << Acc.getWrittenValue()->getName() 1446 << "\n"; 1447 else if (Acc.getWrittenValue()) 1448 O << " - c: " << *Acc.getWrittenValue() << "\n"; 1449 else 1450 O << " - c: <unknown>\n"; 1451 } 1452 } 1453 } 1454 } 1455 }; 1456 1457 struct AAPointerInfoFloating : public AAPointerInfoImpl { 1458 using AccessKind = AAPointerInfo::AccessKind; 1459 AAPointerInfoFloating(const IRPosition &IRP, Attributor &A) 1460 : AAPointerInfoImpl(IRP, A) {} 1461 1462 /// Deal with an access and signal if it was handled successfully. 1463 bool handleAccess(Attributor &A, Instruction &I, 1464 std::optional<Value *> Content, AccessKind Kind, 1465 SmallVectorImpl<int64_t> &Offsets, ChangeStatus &Changed, 1466 Type &Ty) { 1467 using namespace AA::PointerInfo; 1468 auto Size = AA::RangeTy::Unknown; 1469 const DataLayout &DL = A.getDataLayout(); 1470 TypeSize AccessSize = DL.getTypeStoreSize(&Ty); 1471 if (!AccessSize.isScalable()) 1472 Size = AccessSize.getFixedValue(); 1473 1474 // Make a strictly ascending list of offsets as required by addAccess() 1475 llvm::sort(Offsets); 1476 auto *Last = llvm::unique(Offsets); 1477 Offsets.erase(Last, Offsets.end()); 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 = Changed | addAccess(A, {Offsets, Size}, I, Content, Kind, &Ty); 1485 } else { 1486 // Handle vector stores with constant content element-wise. 1487 // TODO: We could look for the elements or create instructions 1488 // representing them. 1489 // TODO: We need to push the Content into the range abstraction 1490 // (AA::RangeTy) to allow different content values for different 1491 // ranges. ranges. Hence, support vectors storing different values. 1492 Type *ElementType = VT->getElementType(); 1493 int64_t ElementSize = DL.getTypeStoreSize(ElementType).getFixedValue(); 1494 auto *ConstContent = cast<Constant>(*Content); 1495 Type *Int32Ty = Type::getInt32Ty(ElementType->getContext()); 1496 SmallVector<int64_t> ElementOffsets(Offsets.begin(), Offsets.end()); 1497 1498 for (int i = 0, e = VT->getElementCount().getFixedValue(); i != e; ++i) { 1499 Value *ElementContent = ConstantExpr::getExtractElement( 1500 ConstContent, ConstantInt::get(Int32Ty, i)); 1501 1502 // Add the element access. 1503 Changed = Changed | addAccess(A, {ElementOffsets, ElementSize}, I, 1504 ElementContent, Kind, ElementType); 1505 1506 // Advance the offsets for the next element. 1507 for (auto &ElementOffset : ElementOffsets) 1508 ElementOffset += ElementSize; 1509 } 1510 } 1511 return true; 1512 }; 1513 1514 /// See AbstractAttribute::updateImpl(...). 1515 ChangeStatus updateImpl(Attributor &A) override; 1516 1517 /// If the indices to \p GEP can be traced to constants, incorporate all 1518 /// of these into \p UsrOI. 1519 /// 1520 /// \return true iff \p UsrOI is updated. 1521 bool collectConstantsForGEP(Attributor &A, const DataLayout &DL, 1522 OffsetInfo &UsrOI, const OffsetInfo &PtrOI, 1523 const GEPOperator *GEP); 1524 1525 /// See AbstractAttribute::trackStatistics() 1526 void trackStatistics() const override { 1527 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition()); 1528 } 1529 }; 1530 1531 bool AAPointerInfoFloating::collectConstantsForGEP(Attributor &A, 1532 const DataLayout &DL, 1533 OffsetInfo &UsrOI, 1534 const OffsetInfo &PtrOI, 1535 const GEPOperator *GEP) { 1536 unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType()); 1537 MapVector<Value *, APInt> VariableOffsets; 1538 APInt ConstantOffset(BitWidth, 0); 1539 1540 assert(!UsrOI.isUnknown() && !PtrOI.isUnknown() && 1541 "Don't look for constant values if the offset has already been " 1542 "determined to be unknown."); 1543 1544 if (!GEP->collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset)) { 1545 UsrOI.setUnknown(); 1546 return true; 1547 } 1548 1549 LLVM_DEBUG(dbgs() << "[AAPointerInfo] GEP offset is " 1550 << (VariableOffsets.empty() ? "" : "not") << " constant " 1551 << *GEP << "\n"); 1552 1553 auto Union = PtrOI; 1554 Union.addToAll(ConstantOffset.getSExtValue()); 1555 1556 // Each VI in VariableOffsets has a set of potential constant values. Every 1557 // combination of elements, picked one each from these sets, is separately 1558 // added to the original set of offsets, thus resulting in more offsets. 1559 for (const auto &VI : VariableOffsets) { 1560 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>( 1561 *this, IRPosition::value(*VI.first), DepClassTy::OPTIONAL); 1562 if (!PotentialConstantsAA || !PotentialConstantsAA->isValidState()) { 1563 UsrOI.setUnknown(); 1564 return true; 1565 } 1566 1567 // UndefValue is treated as a zero, which leaves Union as is. 1568 if (PotentialConstantsAA->undefIsContained()) 1569 continue; 1570 1571 // We need at least one constant in every set to compute an actual offset. 1572 // Otherwise, we end up pessimizing AAPointerInfo by respecting offsets that 1573 // don't actually exist. In other words, the absence of constant values 1574 // implies that the operation can be assumed dead for now. 1575 auto &AssumedSet = PotentialConstantsAA->getAssumedSet(); 1576 if (AssumedSet.empty()) 1577 return false; 1578 1579 OffsetInfo Product; 1580 for (const auto &ConstOffset : AssumedSet) { 1581 auto CopyPerOffset = Union; 1582 CopyPerOffset.addToAll(ConstOffset.getSExtValue() * 1583 VI.second.getZExtValue()); 1584 Product.merge(CopyPerOffset); 1585 } 1586 Union = Product; 1587 } 1588 1589 UsrOI = std::move(Union); 1590 return true; 1591 } 1592 1593 ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) { 1594 using namespace AA::PointerInfo; 1595 ChangeStatus Changed = ChangeStatus::UNCHANGED; 1596 const DataLayout &DL = A.getDataLayout(); 1597 Value &AssociatedValue = getAssociatedValue(); 1598 1599 DenseMap<Value *, OffsetInfo> OffsetInfoMap; 1600 OffsetInfoMap[&AssociatedValue].insert(0); 1601 1602 auto HandlePassthroughUser = [&](Value *Usr, Value *CurPtr, bool &Follow) { 1603 // One does not simply walk into a map and assign a reference to a possibly 1604 // new location. That can cause an invalidation before the assignment 1605 // happens, like so: 1606 // 1607 // OffsetInfoMap[Usr] = OffsetInfoMap[CurPtr]; /* bad idea! */ 1608 // 1609 // The RHS is a reference that may be invalidated by an insertion caused by 1610 // the LHS. So we ensure that the side-effect of the LHS happens first. 1611 1612 assert(OffsetInfoMap.contains(CurPtr) && 1613 "CurPtr does not exist in the map!"); 1614 1615 auto &UsrOI = OffsetInfoMap[Usr]; 1616 auto &PtrOI = OffsetInfoMap[CurPtr]; 1617 assert(!PtrOI.isUnassigned() && 1618 "Cannot pass through if the input Ptr was not visited!"); 1619 UsrOI.merge(PtrOI); 1620 Follow = true; 1621 return true; 1622 }; 1623 1624 auto UsePred = [&](const Use &U, bool &Follow) -> bool { 1625 Value *CurPtr = U.get(); 1626 User *Usr = U.getUser(); 1627 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Analyze " << *CurPtr << " in " << *Usr 1628 << "\n"); 1629 assert(OffsetInfoMap.count(CurPtr) && 1630 "The current pointer offset should have been seeded!"); 1631 1632 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Usr)) { 1633 if (CE->isCast()) 1634 return HandlePassthroughUser(Usr, CurPtr, Follow); 1635 if (!isa<GEPOperator>(CE)) { 1636 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled constant user " << *CE 1637 << "\n"); 1638 return false; 1639 } 1640 } 1641 if (auto *GEP = dyn_cast<GEPOperator>(Usr)) { 1642 // Note the order here, the Usr access might change the map, CurPtr is 1643 // already in it though. 1644 auto &UsrOI = OffsetInfoMap[Usr]; 1645 auto &PtrOI = OffsetInfoMap[CurPtr]; 1646 1647 if (UsrOI.isUnknown()) 1648 return true; 1649 1650 if (PtrOI.isUnknown()) { 1651 Follow = true; 1652 UsrOI.setUnknown(); 1653 return true; 1654 } 1655 1656 Follow = collectConstantsForGEP(A, DL, UsrOI, PtrOI, GEP); 1657 return true; 1658 } 1659 if (isa<PtrToIntInst>(Usr)) 1660 return false; 1661 if (isa<CastInst>(Usr) || isa<SelectInst>(Usr) || isa<ReturnInst>(Usr)) 1662 return HandlePassthroughUser(Usr, CurPtr, Follow); 1663 1664 // For PHIs we need to take care of the recurrence explicitly as the value 1665 // might change while we iterate through a loop. For now, we give up if 1666 // the PHI is not invariant. 1667 if (auto *PHI = dyn_cast<PHINode>(Usr)) { 1668 // Note the order here, the Usr access might change the map, CurPtr is 1669 // already in it though. 1670 bool IsFirstPHIUser = !OffsetInfoMap.count(PHI); 1671 auto &UsrOI = OffsetInfoMap[PHI]; 1672 auto &PtrOI = OffsetInfoMap[CurPtr]; 1673 1674 // Check if the PHI operand has already an unknown offset as we can't 1675 // improve on that anymore. 1676 if (PtrOI.isUnknown()) { 1677 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand offset unknown " 1678 << *CurPtr << " in " << *PHI << "\n"); 1679 Follow = !UsrOI.isUnknown(); 1680 UsrOI.setUnknown(); 1681 return true; 1682 } 1683 1684 // Check if the PHI is invariant (so far). 1685 if (UsrOI == PtrOI) { 1686 assert(!PtrOI.isUnassigned() && 1687 "Cannot assign if the current Ptr was not visited!"); 1688 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant (so far)"); 1689 return true; 1690 } 1691 1692 // Check if the PHI operand can be traced back to AssociatedValue. 1693 APInt Offset( 1694 DL.getIndexSizeInBits(CurPtr->getType()->getPointerAddressSpace()), 1695 0); 1696 Value *CurPtrBase = CurPtr->stripAndAccumulateConstantOffsets( 1697 DL, Offset, /* AllowNonInbounds */ true); 1698 auto It = OffsetInfoMap.find(CurPtrBase); 1699 if (It == OffsetInfoMap.end()) { 1700 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand is too complex " 1701 << *CurPtr << " in " << *PHI 1702 << " (base: " << *CurPtrBase << ")\n"); 1703 UsrOI.setUnknown(); 1704 Follow = true; 1705 return true; 1706 } 1707 1708 // Check if the PHI operand is not dependent on the PHI itself. Every 1709 // recurrence is a cyclic net of PHIs in the data flow, and has an 1710 // equivalent Cycle in the control flow. One of those PHIs must be in the 1711 // header of that control flow Cycle. This is independent of the choice of 1712 // Cycles reported by CycleInfo. It is sufficient to check the PHIs in 1713 // every Cycle header; if such a node is marked unknown, this will 1714 // eventually propagate through the whole net of PHIs in the recurrence. 1715 const auto *CI = 1716 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>( 1717 *PHI->getFunction()); 1718 if (mayBeInCycle(CI, cast<Instruction>(Usr), /* HeaderOnly */ true)) { 1719 auto BaseOI = It->getSecond(); 1720 BaseOI.addToAll(Offset.getZExtValue()); 1721 if (IsFirstPHIUser || BaseOI == UsrOI) { 1722 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant " << *CurPtr 1723 << " in " << *Usr << "\n"); 1724 return HandlePassthroughUser(Usr, CurPtr, Follow); 1725 } 1726 1727 LLVM_DEBUG( 1728 dbgs() << "[AAPointerInfo] PHI operand pointer offset mismatch " 1729 << *CurPtr << " in " << *PHI << "\n"); 1730 UsrOI.setUnknown(); 1731 Follow = true; 1732 return true; 1733 } 1734 1735 UsrOI.merge(PtrOI); 1736 Follow = true; 1737 return true; 1738 } 1739 1740 if (auto *LoadI = dyn_cast<LoadInst>(Usr)) { 1741 // If the access is to a pointer that may or may not be the associated 1742 // value, e.g. due to a PHI, we cannot assume it will be read. 1743 AccessKind AK = AccessKind::AK_R; 1744 if (getUnderlyingObject(CurPtr) == &AssociatedValue) 1745 AK = AccessKind(AK | AccessKind::AK_MUST); 1746 else 1747 AK = AccessKind(AK | AccessKind::AK_MAY); 1748 if (!handleAccess(A, *LoadI, /* Content */ nullptr, AK, 1749 OffsetInfoMap[CurPtr].Offsets, Changed, 1750 *LoadI->getType())) 1751 return false; 1752 1753 auto IsAssumption = [](Instruction &I) { 1754 if (auto *II = dyn_cast<IntrinsicInst>(&I)) 1755 return II->isAssumeLikeIntrinsic(); 1756 return false; 1757 }; 1758 1759 auto IsImpactedInRange = [&](Instruction *FromI, Instruction *ToI) { 1760 // Check if the assumption and the load are executed together without 1761 // memory modification. 1762 do { 1763 if (FromI->mayWriteToMemory() && !IsAssumption(*FromI)) 1764 return true; 1765 FromI = FromI->getNextNonDebugInstruction(); 1766 } while (FromI && FromI != ToI); 1767 return false; 1768 }; 1769 1770 BasicBlock *BB = LoadI->getParent(); 1771 auto IsValidAssume = [&](IntrinsicInst &IntrI) { 1772 if (IntrI.getIntrinsicID() != Intrinsic::assume) 1773 return false; 1774 BasicBlock *IntrBB = IntrI.getParent(); 1775 if (IntrI.getParent() == BB) { 1776 if (IsImpactedInRange(LoadI->getNextNonDebugInstruction(), &IntrI)) 1777 return false; 1778 } else { 1779 auto PredIt = pred_begin(IntrBB); 1780 if (PredIt == pred_end(IntrBB)) 1781 return false; 1782 if ((*PredIt) != BB) 1783 return false; 1784 if (++PredIt != pred_end(IntrBB)) 1785 return false; 1786 for (auto *SuccBB : successors(BB)) { 1787 if (SuccBB == IntrBB) 1788 continue; 1789 if (isa<UnreachableInst>(SuccBB->getTerminator())) 1790 continue; 1791 return false; 1792 } 1793 if (IsImpactedInRange(LoadI->getNextNonDebugInstruction(), 1794 BB->getTerminator())) 1795 return false; 1796 if (IsImpactedInRange(&IntrBB->front(), &IntrI)) 1797 return false; 1798 } 1799 return true; 1800 }; 1801 1802 std::pair<Value *, IntrinsicInst *> Assumption; 1803 for (const Use &LoadU : LoadI->uses()) { 1804 if (auto *CmpI = dyn_cast<CmpInst>(LoadU.getUser())) { 1805 if (!CmpI->isEquality() || !CmpI->isTrueWhenEqual()) 1806 continue; 1807 for (const Use &CmpU : CmpI->uses()) { 1808 if (auto *IntrI = dyn_cast<IntrinsicInst>(CmpU.getUser())) { 1809 if (!IsValidAssume(*IntrI)) 1810 continue; 1811 int Idx = CmpI->getOperandUse(0) == LoadU; 1812 Assumption = {CmpI->getOperand(Idx), IntrI}; 1813 break; 1814 } 1815 } 1816 } 1817 if (Assumption.first) 1818 break; 1819 } 1820 1821 // Check if we found an assumption associated with this load. 1822 if (!Assumption.first || !Assumption.second) 1823 return true; 1824 1825 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Assumption found " 1826 << *Assumption.second << ": " << *LoadI 1827 << " == " << *Assumption.first << "\n"); 1828 bool UsedAssumedInformation = false; 1829 std::optional<Value *> Content = nullptr; 1830 if (Assumption.first) 1831 Content = 1832 A.getAssumedSimplified(*Assumption.first, *this, 1833 UsedAssumedInformation, AA::Interprocedural); 1834 return handleAccess( 1835 A, *Assumption.second, Content, AccessKind::AK_ASSUMPTION, 1836 OffsetInfoMap[CurPtr].Offsets, Changed, *LoadI->getType()); 1837 } 1838 1839 auto HandleStoreLike = [&](Instruction &I, Value *ValueOp, Type &ValueTy, 1840 ArrayRef<Value *> OtherOps, AccessKind AK) { 1841 for (auto *OtherOp : OtherOps) { 1842 if (OtherOp == CurPtr) { 1843 LLVM_DEBUG( 1844 dbgs() 1845 << "[AAPointerInfo] Escaping use in store like instruction " << I 1846 << "\n"); 1847 return false; 1848 } 1849 } 1850 1851 // If the access is to a pointer that may or may not be the associated 1852 // value, e.g. due to a PHI, we cannot assume it will be written. 1853 if (getUnderlyingObject(CurPtr) == &AssociatedValue) 1854 AK = AccessKind(AK | AccessKind::AK_MUST); 1855 else 1856 AK = AccessKind(AK | AccessKind::AK_MAY); 1857 bool UsedAssumedInformation = false; 1858 std::optional<Value *> Content = nullptr; 1859 if (ValueOp) 1860 Content = A.getAssumedSimplified( 1861 *ValueOp, *this, UsedAssumedInformation, AA::Interprocedural); 1862 return handleAccess(A, I, Content, AK, OffsetInfoMap[CurPtr].Offsets, 1863 Changed, ValueTy); 1864 }; 1865 1866 if (auto *StoreI = dyn_cast<StoreInst>(Usr)) 1867 return HandleStoreLike(*StoreI, StoreI->getValueOperand(), 1868 *StoreI->getValueOperand()->getType(), 1869 {StoreI->getValueOperand()}, AccessKind::AK_W); 1870 if (auto *RMWI = dyn_cast<AtomicRMWInst>(Usr)) 1871 return HandleStoreLike(*RMWI, nullptr, *RMWI->getValOperand()->getType(), 1872 {RMWI->getValOperand()}, AccessKind::AK_RW); 1873 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(Usr)) 1874 return HandleStoreLike( 1875 *CXI, nullptr, *CXI->getNewValOperand()->getType(), 1876 {CXI->getCompareOperand(), CXI->getNewValOperand()}, 1877 AccessKind::AK_RW); 1878 1879 if (auto *CB = dyn_cast<CallBase>(Usr)) { 1880 if (CB->isLifetimeStartOrEnd()) 1881 return true; 1882 const auto *TLI = 1883 A.getInfoCache().getTargetLibraryInfoForFunction(*CB->getFunction()); 1884 if (getFreedOperand(CB, TLI) == U) 1885 return true; 1886 if (CB->isArgOperand(&U)) { 1887 unsigned ArgNo = CB->getArgOperandNo(&U); 1888 const auto *CSArgPI = A.getAAFor<AAPointerInfo>( 1889 *this, IRPosition::callsite_argument(*CB, ArgNo), 1890 DepClassTy::REQUIRED); 1891 if (!CSArgPI) 1892 return false; 1893 Changed = 1894 translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB) | 1895 Changed; 1896 return isValidState(); 1897 } 1898 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB 1899 << "\n"); 1900 // TODO: Allow some call uses 1901 return false; 1902 } 1903 1904 LLVM_DEBUG(dbgs() << "[AAPointerInfo] User not handled " << *Usr << "\n"); 1905 return false; 1906 }; 1907 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) { 1908 assert(OffsetInfoMap.count(OldU) && "Old use should be known already!"); 1909 if (OffsetInfoMap.count(NewU)) { 1910 LLVM_DEBUG({ 1911 if (!(OffsetInfoMap[NewU] == OffsetInfoMap[OldU])) { 1912 dbgs() << "[AAPointerInfo] Equivalent use callback failed: " 1913 << OffsetInfoMap[NewU] << " vs " << OffsetInfoMap[OldU] 1914 << "\n"; 1915 } 1916 }); 1917 return OffsetInfoMap[NewU] == OffsetInfoMap[OldU]; 1918 } 1919 OffsetInfoMap[NewU] = OffsetInfoMap[OldU]; 1920 return true; 1921 }; 1922 if (!A.checkForAllUses(UsePred, *this, AssociatedValue, 1923 /* CheckBBLivenessOnly */ true, DepClassTy::OPTIONAL, 1924 /* IgnoreDroppableUses */ true, EquivalentUseCB)) { 1925 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Check for all uses failed, abort!\n"); 1926 return indicatePessimisticFixpoint(); 1927 } 1928 1929 LLVM_DEBUG({ 1930 dbgs() << "Accesses by bin after update:\n"; 1931 dumpState(dbgs()); 1932 }); 1933 1934 return Changed; 1935 } 1936 1937 struct AAPointerInfoReturned final : AAPointerInfoImpl { 1938 AAPointerInfoReturned(const IRPosition &IRP, Attributor &A) 1939 : AAPointerInfoImpl(IRP, A) {} 1940 1941 /// See AbstractAttribute::updateImpl(...). 1942 ChangeStatus updateImpl(Attributor &A) override { 1943 return indicatePessimisticFixpoint(); 1944 } 1945 1946 /// See AbstractAttribute::trackStatistics() 1947 void trackStatistics() const override { 1948 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition()); 1949 } 1950 }; 1951 1952 struct AAPointerInfoArgument final : AAPointerInfoFloating { 1953 AAPointerInfoArgument(const IRPosition &IRP, Attributor &A) 1954 : AAPointerInfoFloating(IRP, A) {} 1955 1956 /// See AbstractAttribute::trackStatistics() 1957 void trackStatistics() const override { 1958 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition()); 1959 } 1960 }; 1961 1962 struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating { 1963 AAPointerInfoCallSiteArgument(const IRPosition &IRP, Attributor &A) 1964 : AAPointerInfoFloating(IRP, A) {} 1965 1966 /// See AbstractAttribute::updateImpl(...). 1967 ChangeStatus updateImpl(Attributor &A) override { 1968 using namespace AA::PointerInfo; 1969 // We handle memory intrinsics explicitly, at least the first (= 1970 // destination) and second (=source) arguments as we know how they are 1971 // accessed. 1972 if (auto *MI = dyn_cast_or_null<MemIntrinsic>(getCtxI())) { 1973 ConstantInt *Length = dyn_cast<ConstantInt>(MI->getLength()); 1974 int64_t LengthVal = AA::RangeTy::Unknown; 1975 if (Length) 1976 LengthVal = Length->getSExtValue(); 1977 unsigned ArgNo = getIRPosition().getCallSiteArgNo(); 1978 ChangeStatus Changed = ChangeStatus::UNCHANGED; 1979 if (ArgNo > 1) { 1980 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled memory intrinsic " 1981 << *MI << "\n"); 1982 return indicatePessimisticFixpoint(); 1983 } else { 1984 auto Kind = 1985 ArgNo == 0 ? AccessKind::AK_MUST_WRITE : AccessKind::AK_MUST_READ; 1986 Changed = 1987 Changed | addAccess(A, {0, LengthVal}, *MI, nullptr, Kind, nullptr); 1988 } 1989 LLVM_DEBUG({ 1990 dbgs() << "Accesses by bin after update:\n"; 1991 dumpState(dbgs()); 1992 }); 1993 1994 return Changed; 1995 } 1996 1997 // TODO: Once we have call site specific value information we can provide 1998 // call site specific liveness information and then it makes 1999 // sense to specialize attributes for call sites arguments instead of 2000 // redirecting requests to the callee argument. 2001 Argument *Arg = getAssociatedArgument(); 2002 if (Arg) { 2003 const IRPosition &ArgPos = IRPosition::argument(*Arg); 2004 auto *ArgAA = 2005 A.getAAFor<AAPointerInfo>(*this, ArgPos, DepClassTy::REQUIRED); 2006 if (ArgAA && ArgAA->getState().isValidState()) 2007 return translateAndAddStateFromCallee(A, *ArgAA, 2008 *cast<CallBase>(getCtxI())); 2009 if (!Arg->getParent()->isDeclaration()) 2010 return indicatePessimisticFixpoint(); 2011 } 2012 2013 bool IsKnownNoCapture; 2014 if (!AA::hasAssumedIRAttr<Attribute::NoCapture>( 2015 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoCapture)) 2016 return indicatePessimisticFixpoint(); 2017 2018 bool IsKnown = false; 2019 if (AA::isAssumedReadNone(A, getIRPosition(), *this, IsKnown)) 2020 return ChangeStatus::UNCHANGED; 2021 bool ReadOnly = AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown); 2022 auto Kind = 2023 ReadOnly ? AccessKind::AK_MAY_READ : AccessKind::AK_MAY_READ_WRITE; 2024 return addAccess(A, AA::RangeTy::getUnknown(), *getCtxI(), nullptr, Kind, 2025 nullptr); 2026 } 2027 2028 /// See AbstractAttribute::trackStatistics() 2029 void trackStatistics() const override { 2030 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition()); 2031 } 2032 }; 2033 2034 struct AAPointerInfoCallSiteReturned final : AAPointerInfoFloating { 2035 AAPointerInfoCallSiteReturned(const IRPosition &IRP, Attributor &A) 2036 : AAPointerInfoFloating(IRP, A) {} 2037 2038 /// See AbstractAttribute::trackStatistics() 2039 void trackStatistics() const override { 2040 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition()); 2041 } 2042 }; 2043 } // namespace 2044 2045 /// -----------------------NoUnwind Function Attribute-------------------------- 2046 2047 namespace { 2048 struct AANoUnwindImpl : AANoUnwind { 2049 AANoUnwindImpl(const IRPosition &IRP, Attributor &A) : AANoUnwind(IRP, A) {} 2050 2051 /// See AbstractAttribute::initialize(...). 2052 void initialize(Attributor &A) override { 2053 bool IsKnown; 2054 assert(!AA::hasAssumedIRAttr<Attribute::NoUnwind>( 2055 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown)); 2056 (void)IsKnown; 2057 } 2058 2059 const std::string getAsStr(Attributor *A) const override { 2060 return getAssumed() ? "nounwind" : "may-unwind"; 2061 } 2062 2063 /// See AbstractAttribute::updateImpl(...). 2064 ChangeStatus updateImpl(Attributor &A) override { 2065 auto Opcodes = { 2066 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr, 2067 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet, 2068 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume}; 2069 2070 auto CheckForNoUnwind = [&](Instruction &I) { 2071 if (!I.mayThrow(/* IncludePhaseOneUnwind */ true)) 2072 return true; 2073 2074 if (const auto *CB = dyn_cast<CallBase>(&I)) { 2075 bool IsKnownNoUnwind; 2076 return AA::hasAssumedIRAttr<Attribute::NoUnwind>( 2077 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED, 2078 IsKnownNoUnwind); 2079 } 2080 return false; 2081 }; 2082 2083 bool UsedAssumedInformation = false; 2084 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes, 2085 UsedAssumedInformation)) 2086 return indicatePessimisticFixpoint(); 2087 2088 return ChangeStatus::UNCHANGED; 2089 } 2090 }; 2091 2092 struct AANoUnwindFunction final : public AANoUnwindImpl { 2093 AANoUnwindFunction(const IRPosition &IRP, Attributor &A) 2094 : AANoUnwindImpl(IRP, A) {} 2095 2096 /// See AbstractAttribute::trackStatistics() 2097 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) } 2098 }; 2099 2100 /// NoUnwind attribute deduction for a call sites. 2101 struct AANoUnwindCallSite final 2102 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl> { 2103 AANoUnwindCallSite(const IRPosition &IRP, Attributor &A) 2104 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl>(IRP, A) {} 2105 2106 /// See AbstractAttribute::trackStatistics() 2107 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); } 2108 }; 2109 } // namespace 2110 2111 /// ------------------------ NoSync Function Attribute ------------------------- 2112 2113 bool AANoSync::isAlignedBarrier(const CallBase &CB, bool ExecutedAligned) { 2114 switch (CB.getIntrinsicID()) { 2115 case Intrinsic::nvvm_barrier0: 2116 case Intrinsic::nvvm_barrier0_and: 2117 case Intrinsic::nvvm_barrier0_or: 2118 case Intrinsic::nvvm_barrier0_popc: 2119 return true; 2120 case Intrinsic::amdgcn_s_barrier: 2121 if (ExecutedAligned) 2122 return true; 2123 break; 2124 default: 2125 break; 2126 } 2127 return hasAssumption(CB, KnownAssumptionString("ompx_aligned_barrier")); 2128 } 2129 2130 bool AANoSync::isNonRelaxedAtomic(const Instruction *I) { 2131 if (!I->isAtomic()) 2132 return false; 2133 2134 if (auto *FI = dyn_cast<FenceInst>(I)) 2135 // All legal orderings for fence are stronger than monotonic. 2136 return FI->getSyncScopeID() != SyncScope::SingleThread; 2137 if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) { 2138 // Unordered is not a legal ordering for cmpxchg. 2139 return (AI->getSuccessOrdering() != AtomicOrdering::Monotonic || 2140 AI->getFailureOrdering() != AtomicOrdering::Monotonic); 2141 } 2142 2143 AtomicOrdering Ordering; 2144 switch (I->getOpcode()) { 2145 case Instruction::AtomicRMW: 2146 Ordering = cast<AtomicRMWInst>(I)->getOrdering(); 2147 break; 2148 case Instruction::Store: 2149 Ordering = cast<StoreInst>(I)->getOrdering(); 2150 break; 2151 case Instruction::Load: 2152 Ordering = cast<LoadInst>(I)->getOrdering(); 2153 break; 2154 default: 2155 llvm_unreachable( 2156 "New atomic operations need to be known in the attributor."); 2157 } 2158 2159 return (Ordering != AtomicOrdering::Unordered && 2160 Ordering != AtomicOrdering::Monotonic); 2161 } 2162 2163 /// Return true if this intrinsic is nosync. This is only used for intrinsics 2164 /// which would be nosync except that they have a volatile flag. All other 2165 /// intrinsics are simply annotated with the nosync attribute in Intrinsics.td. 2166 bool AANoSync::isNoSyncIntrinsic(const Instruction *I) { 2167 if (auto *MI = dyn_cast<MemIntrinsic>(I)) 2168 return !MI->isVolatile(); 2169 return false; 2170 } 2171 2172 namespace { 2173 struct AANoSyncImpl : AANoSync { 2174 AANoSyncImpl(const IRPosition &IRP, Attributor &A) : AANoSync(IRP, A) {} 2175 2176 /// See AbstractAttribute::initialize(...). 2177 void initialize(Attributor &A) override { 2178 bool IsKnown; 2179 assert(!AA::hasAssumedIRAttr<Attribute::NoSync>(A, nullptr, getIRPosition(), 2180 DepClassTy::NONE, IsKnown)); 2181 (void)IsKnown; 2182 } 2183 2184 const std::string getAsStr(Attributor *A) const override { 2185 return getAssumed() ? "nosync" : "may-sync"; 2186 } 2187 2188 /// See AbstractAttribute::updateImpl(...). 2189 ChangeStatus updateImpl(Attributor &A) override; 2190 }; 2191 2192 ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) { 2193 2194 auto CheckRWInstForNoSync = [&](Instruction &I) { 2195 return AA::isNoSyncInst(A, I, *this); 2196 }; 2197 2198 auto CheckForNoSync = [&](Instruction &I) { 2199 // At this point we handled all read/write effects and they are all 2200 // nosync, so they can be skipped. 2201 if (I.mayReadOrWriteMemory()) 2202 return true; 2203 2204 bool IsKnown; 2205 CallBase &CB = cast<CallBase>(I); 2206 if (AA::hasAssumedIRAttr<Attribute::NoSync>( 2207 A, this, IRPosition::callsite_function(CB), DepClassTy::OPTIONAL, 2208 IsKnown)) 2209 return true; 2210 2211 // non-convergent and readnone imply nosync. 2212 return !CB.isConvergent(); 2213 }; 2214 2215 bool UsedAssumedInformation = false; 2216 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this, 2217 UsedAssumedInformation) || 2218 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this, 2219 UsedAssumedInformation)) 2220 return indicatePessimisticFixpoint(); 2221 2222 return ChangeStatus::UNCHANGED; 2223 } 2224 2225 struct AANoSyncFunction final : public AANoSyncImpl { 2226 AANoSyncFunction(const IRPosition &IRP, Attributor &A) 2227 : AANoSyncImpl(IRP, A) {} 2228 2229 /// See AbstractAttribute::trackStatistics() 2230 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) } 2231 }; 2232 2233 /// NoSync attribute deduction for a call sites. 2234 struct AANoSyncCallSite final : AACalleeToCallSite<AANoSync, AANoSyncImpl> { 2235 AANoSyncCallSite(const IRPosition &IRP, Attributor &A) 2236 : AACalleeToCallSite<AANoSync, AANoSyncImpl>(IRP, A) {} 2237 2238 /// See AbstractAttribute::trackStatistics() 2239 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); } 2240 }; 2241 } // namespace 2242 2243 /// ------------------------ No-Free Attributes ---------------------------- 2244 2245 namespace { 2246 struct AANoFreeImpl : public AANoFree { 2247 AANoFreeImpl(const IRPosition &IRP, Attributor &A) : AANoFree(IRP, A) {} 2248 2249 /// See AbstractAttribute::initialize(...). 2250 void initialize(Attributor &A) override { 2251 bool IsKnown; 2252 assert(!AA::hasAssumedIRAttr<Attribute::NoFree>(A, nullptr, getIRPosition(), 2253 DepClassTy::NONE, IsKnown)); 2254 (void)IsKnown; 2255 } 2256 2257 /// See AbstractAttribute::updateImpl(...). 2258 ChangeStatus updateImpl(Attributor &A) override { 2259 auto CheckForNoFree = [&](Instruction &I) { 2260 bool IsKnown; 2261 return AA::hasAssumedIRAttr<Attribute::NoFree>( 2262 A, this, IRPosition::callsite_function(cast<CallBase>(I)), 2263 DepClassTy::REQUIRED, IsKnown); 2264 }; 2265 2266 bool UsedAssumedInformation = false; 2267 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this, 2268 UsedAssumedInformation)) 2269 return indicatePessimisticFixpoint(); 2270 return ChangeStatus::UNCHANGED; 2271 } 2272 2273 /// See AbstractAttribute::getAsStr(). 2274 const std::string getAsStr(Attributor *A) const override { 2275 return getAssumed() ? "nofree" : "may-free"; 2276 } 2277 }; 2278 2279 struct AANoFreeFunction final : public AANoFreeImpl { 2280 AANoFreeFunction(const IRPosition &IRP, Attributor &A) 2281 : AANoFreeImpl(IRP, A) {} 2282 2283 /// See AbstractAttribute::trackStatistics() 2284 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) } 2285 }; 2286 2287 /// NoFree attribute deduction for a call sites. 2288 struct AANoFreeCallSite final : AACalleeToCallSite<AANoFree, AANoFreeImpl> { 2289 AANoFreeCallSite(const IRPosition &IRP, Attributor &A) 2290 : AACalleeToCallSite<AANoFree, AANoFreeImpl>(IRP, A) {} 2291 2292 /// See AbstractAttribute::trackStatistics() 2293 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); } 2294 }; 2295 2296 /// NoFree attribute for floating values. 2297 struct AANoFreeFloating : AANoFreeImpl { 2298 AANoFreeFloating(const IRPosition &IRP, Attributor &A) 2299 : AANoFreeImpl(IRP, A) {} 2300 2301 /// See AbstractAttribute::trackStatistics() 2302 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)} 2303 2304 /// See Abstract Attribute::updateImpl(...). 2305 ChangeStatus updateImpl(Attributor &A) override { 2306 const IRPosition &IRP = getIRPosition(); 2307 2308 bool IsKnown; 2309 if (AA::hasAssumedIRAttr<Attribute::NoFree>(A, this, 2310 IRPosition::function_scope(IRP), 2311 DepClassTy::OPTIONAL, IsKnown)) 2312 return ChangeStatus::UNCHANGED; 2313 2314 Value &AssociatedValue = getIRPosition().getAssociatedValue(); 2315 auto Pred = [&](const Use &U, bool &Follow) -> bool { 2316 Instruction *UserI = cast<Instruction>(U.getUser()); 2317 if (auto *CB = dyn_cast<CallBase>(UserI)) { 2318 if (CB->isBundleOperand(&U)) 2319 return false; 2320 if (!CB->isArgOperand(&U)) 2321 return true; 2322 unsigned ArgNo = CB->getArgOperandNo(&U); 2323 2324 bool IsKnown; 2325 return AA::hasAssumedIRAttr<Attribute::NoFree>( 2326 A, this, IRPosition::callsite_argument(*CB, ArgNo), 2327 DepClassTy::REQUIRED, IsKnown); 2328 } 2329 2330 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) || 2331 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) { 2332 Follow = true; 2333 return true; 2334 } 2335 if (isa<StoreInst>(UserI) || isa<LoadInst>(UserI) || 2336 isa<ReturnInst>(UserI)) 2337 return true; 2338 2339 // Unknown user. 2340 return false; 2341 }; 2342 if (!A.checkForAllUses(Pred, *this, AssociatedValue)) 2343 return indicatePessimisticFixpoint(); 2344 2345 return ChangeStatus::UNCHANGED; 2346 } 2347 }; 2348 2349 /// NoFree attribute for a call site argument. 2350 struct AANoFreeArgument final : AANoFreeFloating { 2351 AANoFreeArgument(const IRPosition &IRP, Attributor &A) 2352 : AANoFreeFloating(IRP, A) {} 2353 2354 /// See AbstractAttribute::trackStatistics() 2355 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) } 2356 }; 2357 2358 /// NoFree attribute for call site arguments. 2359 struct AANoFreeCallSiteArgument final : AANoFreeFloating { 2360 AANoFreeCallSiteArgument(const IRPosition &IRP, Attributor &A) 2361 : AANoFreeFloating(IRP, A) {} 2362 2363 /// See AbstractAttribute::updateImpl(...). 2364 ChangeStatus updateImpl(Attributor &A) override { 2365 // TODO: Once we have call site specific value information we can provide 2366 // call site specific liveness information and then it makes 2367 // sense to specialize attributes for call sites arguments instead of 2368 // redirecting requests to the callee argument. 2369 Argument *Arg = getAssociatedArgument(); 2370 if (!Arg) 2371 return indicatePessimisticFixpoint(); 2372 const IRPosition &ArgPos = IRPosition::argument(*Arg); 2373 bool IsKnown; 2374 if (AA::hasAssumedIRAttr<Attribute::NoFree>(A, this, ArgPos, 2375 DepClassTy::REQUIRED, IsKnown)) 2376 return ChangeStatus::UNCHANGED; 2377 return indicatePessimisticFixpoint(); 2378 } 2379 2380 /// See AbstractAttribute::trackStatistics() 2381 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nofree)}; 2382 }; 2383 2384 /// NoFree attribute for function return value. 2385 struct AANoFreeReturned final : AANoFreeFloating { 2386 AANoFreeReturned(const IRPosition &IRP, Attributor &A) 2387 : AANoFreeFloating(IRP, A) { 2388 llvm_unreachable("NoFree is not applicable to function returns!"); 2389 } 2390 2391 /// See AbstractAttribute::initialize(...). 2392 void initialize(Attributor &A) override { 2393 llvm_unreachable("NoFree is not applicable to function returns!"); 2394 } 2395 2396 /// See AbstractAttribute::updateImpl(...). 2397 ChangeStatus updateImpl(Attributor &A) override { 2398 llvm_unreachable("NoFree is not applicable to function returns!"); 2399 } 2400 2401 /// See AbstractAttribute::trackStatistics() 2402 void trackStatistics() const override {} 2403 }; 2404 2405 /// NoFree attribute deduction for a call site return value. 2406 struct AANoFreeCallSiteReturned final : AANoFreeFloating { 2407 AANoFreeCallSiteReturned(const IRPosition &IRP, Attributor &A) 2408 : AANoFreeFloating(IRP, A) {} 2409 2410 ChangeStatus manifest(Attributor &A) override { 2411 return ChangeStatus::UNCHANGED; 2412 } 2413 /// See AbstractAttribute::trackStatistics() 2414 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) } 2415 }; 2416 } // namespace 2417 2418 /// ------------------------ NonNull Argument Attribute ------------------------ 2419 2420 bool AANonNull::isImpliedByIR(Attributor &A, const IRPosition &IRP, 2421 Attribute::AttrKind ImpliedAttributeKind, 2422 bool IgnoreSubsumingPositions) { 2423 SmallVector<Attribute::AttrKind, 2> AttrKinds; 2424 AttrKinds.push_back(Attribute::NonNull); 2425 if (!NullPointerIsDefined(IRP.getAnchorScope(), 2426 IRP.getAssociatedType()->getPointerAddressSpace())) 2427 AttrKinds.push_back(Attribute::Dereferenceable); 2428 if (A.hasAttr(IRP, AttrKinds, IgnoreSubsumingPositions, Attribute::NonNull)) 2429 return true; 2430 2431 DominatorTree *DT = nullptr; 2432 AssumptionCache *AC = nullptr; 2433 InformationCache &InfoCache = A.getInfoCache(); 2434 if (const Function *Fn = IRP.getAnchorScope()) { 2435 if (!Fn->isDeclaration()) { 2436 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*Fn); 2437 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*Fn); 2438 } 2439 } 2440 2441 SmallVector<AA::ValueAndContext> Worklist; 2442 if (IRP.getPositionKind() != IRP_RETURNED) { 2443 Worklist.push_back({IRP.getAssociatedValue(), IRP.getCtxI()}); 2444 } else { 2445 bool UsedAssumedInformation = false; 2446 if (!A.checkForAllInstructions( 2447 [&](Instruction &I) { 2448 Worklist.push_back({*cast<ReturnInst>(I).getReturnValue(), &I}); 2449 return true; 2450 }, 2451 IRP.getAssociatedFunction(), nullptr, {Instruction::Ret}, 2452 UsedAssumedInformation, false, /*CheckPotentiallyDead=*/true)) 2453 return false; 2454 } 2455 2456 if (llvm::any_of(Worklist, [&](AA::ValueAndContext VAC) { 2457 return !isKnownNonZero( 2458 VAC.getValue(), 2459 SimplifyQuery(A.getDataLayout(), DT, AC, VAC.getCtxI())); 2460 })) 2461 return false; 2462 2463 A.manifestAttrs(IRP, {Attribute::get(IRP.getAnchorValue().getContext(), 2464 Attribute::NonNull)}); 2465 return true; 2466 } 2467 2468 namespace { 2469 static int64_t getKnownNonNullAndDerefBytesForUse( 2470 Attributor &A, const AbstractAttribute &QueryingAA, Value &AssociatedValue, 2471 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) { 2472 TrackUse = false; 2473 2474 const Value *UseV = U->get(); 2475 if (!UseV->getType()->isPointerTy()) 2476 return 0; 2477 2478 // We need to follow common pointer manipulation uses to the accesses they 2479 // feed into. We can try to be smart to avoid looking through things we do not 2480 // like for now, e.g., non-inbounds GEPs. 2481 if (isa<CastInst>(I)) { 2482 TrackUse = true; 2483 return 0; 2484 } 2485 2486 if (isa<GetElementPtrInst>(I)) { 2487 TrackUse = true; 2488 return 0; 2489 } 2490 2491 Type *PtrTy = UseV->getType(); 2492 const Function *F = I->getFunction(); 2493 bool NullPointerIsDefined = 2494 F ? llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace()) : true; 2495 const DataLayout &DL = A.getInfoCache().getDL(); 2496 if (const auto *CB = dyn_cast<CallBase>(I)) { 2497 if (CB->isBundleOperand(U)) { 2498 if (RetainedKnowledge RK = getKnowledgeFromUse( 2499 U, {Attribute::NonNull, Attribute::Dereferenceable})) { 2500 IsNonNull |= 2501 (RK.AttrKind == Attribute::NonNull || !NullPointerIsDefined); 2502 return RK.ArgValue; 2503 } 2504 return 0; 2505 } 2506 2507 if (CB->isCallee(U)) { 2508 IsNonNull |= !NullPointerIsDefined; 2509 return 0; 2510 } 2511 2512 unsigned ArgNo = CB->getArgOperandNo(U); 2513 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo); 2514 // As long as we only use known information there is no need to track 2515 // dependences here. 2516 bool IsKnownNonNull; 2517 AA::hasAssumedIRAttr<Attribute::NonNull>(A, &QueryingAA, IRP, 2518 DepClassTy::NONE, IsKnownNonNull); 2519 IsNonNull |= IsKnownNonNull; 2520 auto *DerefAA = 2521 A.getAAFor<AADereferenceable>(QueryingAA, IRP, DepClassTy::NONE); 2522 return DerefAA ? DerefAA->getKnownDereferenceableBytes() : 0; 2523 } 2524 2525 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I); 2526 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || 2527 Loc->Size.isScalable() || I->isVolatile()) 2528 return 0; 2529 2530 int64_t Offset; 2531 const Value *Base = 2532 getMinimalBaseOfPointer(A, QueryingAA, Loc->Ptr, Offset, DL); 2533 if (Base && Base == &AssociatedValue) { 2534 int64_t DerefBytes = Loc->Size.getValue() + Offset; 2535 IsNonNull |= !NullPointerIsDefined; 2536 return std::max(int64_t(0), DerefBytes); 2537 } 2538 2539 /// Corner case when an offset is 0. 2540 Base = GetPointerBaseWithConstantOffset(Loc->Ptr, Offset, DL, 2541 /*AllowNonInbounds*/ true); 2542 if (Base && Base == &AssociatedValue && Offset == 0) { 2543 int64_t DerefBytes = Loc->Size.getValue(); 2544 IsNonNull |= !NullPointerIsDefined; 2545 return std::max(int64_t(0), DerefBytes); 2546 } 2547 2548 return 0; 2549 } 2550 2551 struct AANonNullImpl : AANonNull { 2552 AANonNullImpl(const IRPosition &IRP, Attributor &A) : AANonNull(IRP, A) {} 2553 2554 /// See AbstractAttribute::initialize(...). 2555 void initialize(Attributor &A) override { 2556 Value &V = *getAssociatedValue().stripPointerCasts(); 2557 if (isa<ConstantPointerNull>(V)) { 2558 indicatePessimisticFixpoint(); 2559 return; 2560 } 2561 2562 if (Instruction *CtxI = getCtxI()) 2563 followUsesInMBEC(*this, A, getState(), *CtxI); 2564 } 2565 2566 /// See followUsesInMBEC 2567 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I, 2568 AANonNull::StateType &State) { 2569 bool IsNonNull = false; 2570 bool TrackUse = false; 2571 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I, 2572 IsNonNull, TrackUse); 2573 State.setKnown(IsNonNull); 2574 return TrackUse; 2575 } 2576 2577 /// See AbstractAttribute::getAsStr(). 2578 const std::string getAsStr(Attributor *A) const override { 2579 return getAssumed() ? "nonnull" : "may-null"; 2580 } 2581 }; 2582 2583 /// NonNull attribute for a floating value. 2584 struct AANonNullFloating : public AANonNullImpl { 2585 AANonNullFloating(const IRPosition &IRP, Attributor &A) 2586 : AANonNullImpl(IRP, A) {} 2587 2588 /// See AbstractAttribute::updateImpl(...). 2589 ChangeStatus updateImpl(Attributor &A) override { 2590 auto CheckIRP = [&](const IRPosition &IRP) { 2591 bool IsKnownNonNull; 2592 return AA::hasAssumedIRAttr<Attribute::NonNull>( 2593 A, *this, IRP, DepClassTy::OPTIONAL, IsKnownNonNull); 2594 }; 2595 2596 bool Stripped; 2597 bool UsedAssumedInformation = false; 2598 Value *AssociatedValue = &getAssociatedValue(); 2599 SmallVector<AA::ValueAndContext> Values; 2600 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values, 2601 AA::AnyScope, UsedAssumedInformation)) 2602 Stripped = false; 2603 else 2604 Stripped = 2605 Values.size() != 1 || Values.front().getValue() != AssociatedValue; 2606 2607 if (!Stripped) { 2608 bool IsKnown; 2609 if (auto *PHI = dyn_cast<PHINode>(AssociatedValue)) 2610 if (llvm::all_of(PHI->incoming_values(), [&](Value *Op) { 2611 return AA::hasAssumedIRAttr<Attribute::NonNull>( 2612 A, this, IRPosition::value(*Op), DepClassTy::OPTIONAL, 2613 IsKnown); 2614 })) 2615 return ChangeStatus::UNCHANGED; 2616 if (auto *Select = dyn_cast<SelectInst>(AssociatedValue)) 2617 if (AA::hasAssumedIRAttr<Attribute::NonNull>( 2618 A, this, IRPosition::value(*Select->getFalseValue()), 2619 DepClassTy::OPTIONAL, IsKnown) && 2620 AA::hasAssumedIRAttr<Attribute::NonNull>( 2621 A, this, IRPosition::value(*Select->getTrueValue()), 2622 DepClassTy::OPTIONAL, IsKnown)) 2623 return ChangeStatus::UNCHANGED; 2624 2625 // If we haven't stripped anything we might still be able to use a 2626 // different AA, but only if the IRP changes. Effectively when we 2627 // interpret this not as a call site value but as a floating/argument 2628 // value. 2629 const IRPosition AVIRP = IRPosition::value(*AssociatedValue); 2630 if (AVIRP == getIRPosition() || !CheckIRP(AVIRP)) 2631 return indicatePessimisticFixpoint(); 2632 return ChangeStatus::UNCHANGED; 2633 } 2634 2635 for (const auto &VAC : Values) 2636 if (!CheckIRP(IRPosition::value(*VAC.getValue()))) 2637 return indicatePessimisticFixpoint(); 2638 2639 return ChangeStatus::UNCHANGED; 2640 } 2641 2642 /// See AbstractAttribute::trackStatistics() 2643 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) } 2644 }; 2645 2646 /// NonNull attribute for function return value. 2647 struct AANonNullReturned final 2648 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType, 2649 false, AANonNull::IRAttributeKind, false> { 2650 AANonNullReturned(const IRPosition &IRP, Attributor &A) 2651 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType, 2652 false, Attribute::NonNull, false>(IRP, A) { 2653 } 2654 2655 /// See AbstractAttribute::getAsStr(). 2656 const std::string getAsStr(Attributor *A) const override { 2657 return getAssumed() ? "nonnull" : "may-null"; 2658 } 2659 2660 /// See AbstractAttribute::trackStatistics() 2661 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) } 2662 }; 2663 2664 /// NonNull attribute for function argument. 2665 struct AANonNullArgument final 2666 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl> { 2667 AANonNullArgument(const IRPosition &IRP, Attributor &A) 2668 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl>(IRP, A) {} 2669 2670 /// See AbstractAttribute::trackStatistics() 2671 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) } 2672 }; 2673 2674 struct AANonNullCallSiteArgument final : AANonNullFloating { 2675 AANonNullCallSiteArgument(const IRPosition &IRP, Attributor &A) 2676 : AANonNullFloating(IRP, A) {} 2677 2678 /// See AbstractAttribute::trackStatistics() 2679 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) } 2680 }; 2681 2682 /// NonNull attribute for a call site return position. 2683 struct AANonNullCallSiteReturned final 2684 : AACalleeToCallSite<AANonNull, AANonNullImpl> { 2685 AANonNullCallSiteReturned(const IRPosition &IRP, Attributor &A) 2686 : AACalleeToCallSite<AANonNull, AANonNullImpl>(IRP, A) {} 2687 2688 /// See AbstractAttribute::trackStatistics() 2689 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) } 2690 }; 2691 } // namespace 2692 2693 /// ------------------------ Must-Progress Attributes -------------------------- 2694 namespace { 2695 struct AAMustProgressImpl : public AAMustProgress { 2696 AAMustProgressImpl(const IRPosition &IRP, Attributor &A) 2697 : AAMustProgress(IRP, A) {} 2698 2699 /// See AbstractAttribute::initialize(...). 2700 void initialize(Attributor &A) override { 2701 bool IsKnown; 2702 assert(!AA::hasAssumedIRAttr<Attribute::MustProgress>( 2703 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown)); 2704 (void)IsKnown; 2705 } 2706 2707 /// See AbstractAttribute::getAsStr() 2708 const std::string getAsStr(Attributor *A) const override { 2709 return getAssumed() ? "mustprogress" : "may-not-progress"; 2710 } 2711 }; 2712 2713 struct AAMustProgressFunction final : AAMustProgressImpl { 2714 AAMustProgressFunction(const IRPosition &IRP, Attributor &A) 2715 : AAMustProgressImpl(IRP, A) {} 2716 2717 /// See AbstractAttribute::updateImpl(...). 2718 ChangeStatus updateImpl(Attributor &A) override { 2719 bool IsKnown; 2720 if (AA::hasAssumedIRAttr<Attribute::WillReturn>( 2721 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnown)) { 2722 if (IsKnown) 2723 return indicateOptimisticFixpoint(); 2724 return ChangeStatus::UNCHANGED; 2725 } 2726 2727 auto CheckForMustProgress = [&](AbstractCallSite ACS) { 2728 IRPosition IPos = IRPosition::callsite_function(*ACS.getInstruction()); 2729 bool IsKnownMustProgress; 2730 return AA::hasAssumedIRAttr<Attribute::MustProgress>( 2731 A, this, IPos, DepClassTy::REQUIRED, IsKnownMustProgress, 2732 /* IgnoreSubsumingPositions */ true); 2733 }; 2734 2735 bool AllCallSitesKnown = true; 2736 if (!A.checkForAllCallSites(CheckForMustProgress, *this, 2737 /* RequireAllCallSites */ true, 2738 AllCallSitesKnown)) 2739 return indicatePessimisticFixpoint(); 2740 2741 return ChangeStatus::UNCHANGED; 2742 } 2743 2744 /// See AbstractAttribute::trackStatistics() 2745 void trackStatistics() const override { 2746 STATS_DECLTRACK_FN_ATTR(mustprogress) 2747 } 2748 }; 2749 2750 /// MustProgress attribute deduction for a call sites. 2751 struct AAMustProgressCallSite final : AAMustProgressImpl { 2752 AAMustProgressCallSite(const IRPosition &IRP, Attributor &A) 2753 : AAMustProgressImpl(IRP, A) {} 2754 2755 /// See AbstractAttribute::updateImpl(...). 2756 ChangeStatus updateImpl(Attributor &A) override { 2757 // TODO: Once we have call site specific value information we can provide 2758 // call site specific liveness information and then it makes 2759 // sense to specialize attributes for call sites arguments instead of 2760 // redirecting requests to the callee argument. 2761 const IRPosition &FnPos = IRPosition::function(*getAnchorScope()); 2762 bool IsKnownMustProgress; 2763 if (!AA::hasAssumedIRAttr<Attribute::MustProgress>( 2764 A, this, FnPos, DepClassTy::REQUIRED, IsKnownMustProgress)) 2765 return indicatePessimisticFixpoint(); 2766 return ChangeStatus::UNCHANGED; 2767 } 2768 2769 /// See AbstractAttribute::trackStatistics() 2770 void trackStatistics() const override { 2771 STATS_DECLTRACK_CS_ATTR(mustprogress); 2772 } 2773 }; 2774 } // namespace 2775 2776 /// ------------------------ No-Recurse Attributes ---------------------------- 2777 2778 namespace { 2779 struct AANoRecurseImpl : public AANoRecurse { 2780 AANoRecurseImpl(const IRPosition &IRP, Attributor &A) : AANoRecurse(IRP, A) {} 2781 2782 /// See AbstractAttribute::initialize(...). 2783 void initialize(Attributor &A) override { 2784 bool IsKnown; 2785 assert(!AA::hasAssumedIRAttr<Attribute::NoRecurse>( 2786 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown)); 2787 (void)IsKnown; 2788 } 2789 2790 /// See AbstractAttribute::getAsStr() 2791 const std::string getAsStr(Attributor *A) const override { 2792 return getAssumed() ? "norecurse" : "may-recurse"; 2793 } 2794 }; 2795 2796 struct AANoRecurseFunction final : AANoRecurseImpl { 2797 AANoRecurseFunction(const IRPosition &IRP, Attributor &A) 2798 : AANoRecurseImpl(IRP, A) {} 2799 2800 /// See AbstractAttribute::updateImpl(...). 2801 ChangeStatus updateImpl(Attributor &A) override { 2802 2803 // If all live call sites are known to be no-recurse, we are as well. 2804 auto CallSitePred = [&](AbstractCallSite ACS) { 2805 bool IsKnownNoRecurse; 2806 if (!AA::hasAssumedIRAttr<Attribute::NoRecurse>( 2807 A, this, 2808 IRPosition::function(*ACS.getInstruction()->getFunction()), 2809 DepClassTy::NONE, IsKnownNoRecurse)) 2810 return false; 2811 return IsKnownNoRecurse; 2812 }; 2813 bool UsedAssumedInformation = false; 2814 if (A.checkForAllCallSites(CallSitePred, *this, true, 2815 UsedAssumedInformation)) { 2816 // If we know all call sites and all are known no-recurse, we are done. 2817 // If all known call sites, which might not be all that exist, are known 2818 // to be no-recurse, we are not done but we can continue to assume 2819 // no-recurse. If one of the call sites we have not visited will become 2820 // live, another update is triggered. 2821 if (!UsedAssumedInformation) 2822 indicateOptimisticFixpoint(); 2823 return ChangeStatus::UNCHANGED; 2824 } 2825 2826 const AAInterFnReachability *EdgeReachability = 2827 A.getAAFor<AAInterFnReachability>(*this, getIRPosition(), 2828 DepClassTy::REQUIRED); 2829 if (EdgeReachability && EdgeReachability->canReach(A, *getAnchorScope())) 2830 return indicatePessimisticFixpoint(); 2831 return ChangeStatus::UNCHANGED; 2832 } 2833 2834 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) } 2835 }; 2836 2837 /// NoRecurse attribute deduction for a call sites. 2838 struct AANoRecurseCallSite final 2839 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl> { 2840 AANoRecurseCallSite(const IRPosition &IRP, Attributor &A) 2841 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl>(IRP, A) {} 2842 2843 /// See AbstractAttribute::trackStatistics() 2844 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); } 2845 }; 2846 } // namespace 2847 2848 /// ------------------------ No-Convergent Attribute -------------------------- 2849 2850 namespace { 2851 struct AANonConvergentImpl : public AANonConvergent { 2852 AANonConvergentImpl(const IRPosition &IRP, Attributor &A) 2853 : AANonConvergent(IRP, A) {} 2854 2855 /// See AbstractAttribute::getAsStr() 2856 const std::string getAsStr(Attributor *A) const override { 2857 return getAssumed() ? "non-convergent" : "may-be-convergent"; 2858 } 2859 }; 2860 2861 struct AANonConvergentFunction final : AANonConvergentImpl { 2862 AANonConvergentFunction(const IRPosition &IRP, Attributor &A) 2863 : AANonConvergentImpl(IRP, A) {} 2864 2865 /// See AbstractAttribute::updateImpl(...). 2866 ChangeStatus updateImpl(Attributor &A) override { 2867 // If all function calls are known to not be convergent, we are not 2868 // convergent. 2869 auto CalleeIsNotConvergent = [&](Instruction &Inst) { 2870 CallBase &CB = cast<CallBase>(Inst); 2871 auto *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand()); 2872 if (!Callee || Callee->isIntrinsic()) { 2873 return false; 2874 } 2875 if (Callee->isDeclaration()) { 2876 return !Callee->hasFnAttribute(Attribute::Convergent); 2877 } 2878 const auto *ConvergentAA = A.getAAFor<AANonConvergent>( 2879 *this, IRPosition::function(*Callee), DepClassTy::REQUIRED); 2880 return ConvergentAA && ConvergentAA->isAssumedNotConvergent(); 2881 }; 2882 2883 bool UsedAssumedInformation = false; 2884 if (!A.checkForAllCallLikeInstructions(CalleeIsNotConvergent, *this, 2885 UsedAssumedInformation)) { 2886 return indicatePessimisticFixpoint(); 2887 } 2888 return ChangeStatus::UNCHANGED; 2889 } 2890 2891 ChangeStatus manifest(Attributor &A) override { 2892 if (isKnownNotConvergent() && 2893 A.hasAttr(getIRPosition(), Attribute::Convergent)) { 2894 A.removeAttrs(getIRPosition(), {Attribute::Convergent}); 2895 return ChangeStatus::CHANGED; 2896 } 2897 return ChangeStatus::UNCHANGED; 2898 } 2899 2900 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(convergent) } 2901 }; 2902 } // namespace 2903 2904 /// -------------------- Undefined-Behavior Attributes ------------------------ 2905 2906 namespace { 2907 struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { 2908 AAUndefinedBehaviorImpl(const IRPosition &IRP, Attributor &A) 2909 : AAUndefinedBehavior(IRP, A) {} 2910 2911 /// See AbstractAttribute::updateImpl(...). 2912 // through a pointer (i.e. also branches etc.) 2913 ChangeStatus updateImpl(Attributor &A) override { 2914 const size_t UBPrevSize = KnownUBInsts.size(); 2915 const size_t NoUBPrevSize = AssumedNoUBInsts.size(); 2916 2917 auto InspectMemAccessInstForUB = [&](Instruction &I) { 2918 // Lang ref now states volatile store is not UB, let's skip them. 2919 if (I.isVolatile() && I.mayWriteToMemory()) 2920 return true; 2921 2922 // Skip instructions that are already saved. 2923 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I)) 2924 return true; 2925 2926 // If we reach here, we know we have an instruction 2927 // that accesses memory through a pointer operand, 2928 // for which getPointerOperand() should give it to us. 2929 Value *PtrOp = 2930 const_cast<Value *>(getPointerOperand(&I, /* AllowVolatile */ true)); 2931 assert(PtrOp && 2932 "Expected pointer operand of memory accessing instruction"); 2933 2934 // Either we stopped and the appropriate action was taken, 2935 // or we got back a simplified value to continue. 2936 std::optional<Value *> SimplifiedPtrOp = 2937 stopOnUndefOrAssumed(A, PtrOp, &I); 2938 if (!SimplifiedPtrOp || !*SimplifiedPtrOp) 2939 return true; 2940 const Value *PtrOpVal = *SimplifiedPtrOp; 2941 2942 // A memory access through a pointer is considered UB 2943 // only if the pointer has constant null value. 2944 // TODO: Expand it to not only check constant values. 2945 if (!isa<ConstantPointerNull>(PtrOpVal)) { 2946 AssumedNoUBInsts.insert(&I); 2947 return true; 2948 } 2949 const Type *PtrTy = PtrOpVal->getType(); 2950 2951 // Because we only consider instructions inside functions, 2952 // assume that a parent function exists. 2953 const Function *F = I.getFunction(); 2954 2955 // A memory access using constant null pointer is only considered UB 2956 // if null pointer is _not_ defined for the target platform. 2957 if (llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace())) 2958 AssumedNoUBInsts.insert(&I); 2959 else 2960 KnownUBInsts.insert(&I); 2961 return true; 2962 }; 2963 2964 auto InspectBrInstForUB = [&](Instruction &I) { 2965 // A conditional branch instruction is considered UB if it has `undef` 2966 // condition. 2967 2968 // Skip instructions that are already saved. 2969 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I)) 2970 return true; 2971 2972 // We know we have a branch instruction. 2973 auto *BrInst = cast<BranchInst>(&I); 2974 2975 // Unconditional branches are never considered UB. 2976 if (BrInst->isUnconditional()) 2977 return true; 2978 2979 // Either we stopped and the appropriate action was taken, 2980 // or we got back a simplified value to continue. 2981 std::optional<Value *> SimplifiedCond = 2982 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst); 2983 if (!SimplifiedCond || !*SimplifiedCond) 2984 return true; 2985 AssumedNoUBInsts.insert(&I); 2986 return true; 2987 }; 2988 2989 auto InspectCallSiteForUB = [&](Instruction &I) { 2990 // Check whether a callsite always cause UB or not 2991 2992 // Skip instructions that are already saved. 2993 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I)) 2994 return true; 2995 2996 // Check nonnull and noundef argument attribute violation for each 2997 // callsite. 2998 CallBase &CB = cast<CallBase>(I); 2999 auto *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand()); 3000 if (!Callee) 3001 return true; 3002 for (unsigned idx = 0; idx < CB.arg_size(); idx++) { 3003 // If current argument is known to be simplified to null pointer and the 3004 // corresponding argument position is known to have nonnull attribute, 3005 // the argument is poison. Furthermore, if the argument is poison and 3006 // the position is known to have noundef attriubte, this callsite is 3007 // considered UB. 3008 if (idx >= Callee->arg_size()) 3009 break; 3010 Value *ArgVal = CB.getArgOperand(idx); 3011 if (!ArgVal) 3012 continue; 3013 // Here, we handle three cases. 3014 // (1) Not having a value means it is dead. (we can replace the value 3015 // with undef) 3016 // (2) Simplified to undef. The argument violate noundef attriubte. 3017 // (3) Simplified to null pointer where known to be nonnull. 3018 // The argument is a poison value and violate noundef attribute. 3019 IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx); 3020 bool IsKnownNoUndef; 3021 AA::hasAssumedIRAttr<Attribute::NoUndef>( 3022 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNoUndef); 3023 if (!IsKnownNoUndef) 3024 continue; 3025 bool UsedAssumedInformation = false; 3026 std::optional<Value *> SimplifiedVal = 3027 A.getAssumedSimplified(IRPosition::value(*ArgVal), *this, 3028 UsedAssumedInformation, AA::Interprocedural); 3029 if (UsedAssumedInformation) 3030 continue; 3031 if (SimplifiedVal && !*SimplifiedVal) 3032 return true; 3033 if (!SimplifiedVal || isa<UndefValue>(**SimplifiedVal)) { 3034 KnownUBInsts.insert(&I); 3035 continue; 3036 } 3037 if (!ArgVal->getType()->isPointerTy() || 3038 !isa<ConstantPointerNull>(**SimplifiedVal)) 3039 continue; 3040 bool IsKnownNonNull; 3041 AA::hasAssumedIRAttr<Attribute::NonNull>( 3042 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNonNull); 3043 if (IsKnownNonNull) 3044 KnownUBInsts.insert(&I); 3045 } 3046 return true; 3047 }; 3048 3049 auto InspectReturnInstForUB = [&](Instruction &I) { 3050 auto &RI = cast<ReturnInst>(I); 3051 // Either we stopped and the appropriate action was taken, 3052 // or we got back a simplified return value to continue. 3053 std::optional<Value *> SimplifiedRetValue = 3054 stopOnUndefOrAssumed(A, RI.getReturnValue(), &I); 3055 if (!SimplifiedRetValue || !*SimplifiedRetValue) 3056 return true; 3057 3058 // Check if a return instruction always cause UB or not 3059 // Note: It is guaranteed that the returned position of the anchor 3060 // scope has noundef attribute when this is called. 3061 // We also ensure the return position is not "assumed dead" 3062 // because the returned value was then potentially simplified to 3063 // `undef` in AAReturnedValues without removing the `noundef` 3064 // attribute yet. 3065 3066 // When the returned position has noundef attriubte, UB occurs in the 3067 // following cases. 3068 // (1) Returned value is known to be undef. 3069 // (2) The value is known to be a null pointer and the returned 3070 // position has nonnull attribute (because the returned value is 3071 // poison). 3072 if (isa<ConstantPointerNull>(*SimplifiedRetValue)) { 3073 bool IsKnownNonNull; 3074 AA::hasAssumedIRAttr<Attribute::NonNull>( 3075 A, this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE, 3076 IsKnownNonNull); 3077 if (IsKnownNonNull) 3078 KnownUBInsts.insert(&I); 3079 } 3080 3081 return true; 3082 }; 3083 3084 bool UsedAssumedInformation = false; 3085 A.checkForAllInstructions(InspectMemAccessInstForUB, *this, 3086 {Instruction::Load, Instruction::Store, 3087 Instruction::AtomicCmpXchg, 3088 Instruction::AtomicRMW}, 3089 UsedAssumedInformation, 3090 /* CheckBBLivenessOnly */ true); 3091 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::Br}, 3092 UsedAssumedInformation, 3093 /* CheckBBLivenessOnly */ true); 3094 A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this, 3095 UsedAssumedInformation); 3096 3097 // If the returned position of the anchor scope has noundef attriubte, check 3098 // all returned instructions. 3099 if (!getAnchorScope()->getReturnType()->isVoidTy()) { 3100 const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope()); 3101 if (!A.isAssumedDead(ReturnIRP, this, nullptr, UsedAssumedInformation)) { 3102 bool IsKnownNoUndef; 3103 AA::hasAssumedIRAttr<Attribute::NoUndef>( 3104 A, this, ReturnIRP, DepClassTy::NONE, IsKnownNoUndef); 3105 if (IsKnownNoUndef) 3106 A.checkForAllInstructions(InspectReturnInstForUB, *this, 3107 {Instruction::Ret}, UsedAssumedInformation, 3108 /* CheckBBLivenessOnly */ true); 3109 } 3110 } 3111 3112 if (NoUBPrevSize != AssumedNoUBInsts.size() || 3113 UBPrevSize != KnownUBInsts.size()) 3114 return ChangeStatus::CHANGED; 3115 return ChangeStatus::UNCHANGED; 3116 } 3117 3118 bool isKnownToCauseUB(Instruction *I) const override { 3119 return KnownUBInsts.count(I); 3120 } 3121 3122 bool isAssumedToCauseUB(Instruction *I) const override { 3123 // In simple words, if an instruction is not in the assumed to _not_ 3124 // cause UB, then it is assumed UB (that includes those 3125 // in the KnownUBInsts set). The rest is boilerplate 3126 // is to ensure that it is one of the instructions we test 3127 // for UB. 3128 3129 switch (I->getOpcode()) { 3130 case Instruction::Load: 3131 case Instruction::Store: 3132 case Instruction::AtomicCmpXchg: 3133 case Instruction::AtomicRMW: 3134 return !AssumedNoUBInsts.count(I); 3135 case Instruction::Br: { 3136 auto *BrInst = cast<BranchInst>(I); 3137 if (BrInst->isUnconditional()) 3138 return false; 3139 return !AssumedNoUBInsts.count(I); 3140 } break; 3141 default: 3142 return false; 3143 } 3144 return false; 3145 } 3146 3147 ChangeStatus manifest(Attributor &A) override { 3148 if (KnownUBInsts.empty()) 3149 return ChangeStatus::UNCHANGED; 3150 for (Instruction *I : KnownUBInsts) 3151 A.changeToUnreachableAfterManifest(I); 3152 return ChangeStatus::CHANGED; 3153 } 3154 3155 /// See AbstractAttribute::getAsStr() 3156 const std::string getAsStr(Attributor *A) const override { 3157 return getAssumed() ? "undefined-behavior" : "no-ub"; 3158 } 3159 3160 /// Note: The correctness of this analysis depends on the fact that the 3161 /// following 2 sets will stop changing after some point. 3162 /// "Change" here means that their size changes. 3163 /// The size of each set is monotonically increasing 3164 /// (we only add items to them) and it is upper bounded by the number of 3165 /// instructions in the processed function (we can never save more 3166 /// elements in either set than this number). Hence, at some point, 3167 /// they will stop increasing. 3168 /// Consequently, at some point, both sets will have stopped 3169 /// changing, effectively making the analysis reach a fixpoint. 3170 3171 /// Note: These 2 sets are disjoint and an instruction can be considered 3172 /// one of 3 things: 3173 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in 3174 /// the KnownUBInsts set. 3175 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior 3176 /// has a reason to assume it). 3177 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior 3178 /// could not find a reason to assume or prove that it can cause UB, 3179 /// hence it assumes it doesn't. We have a set for these instructions 3180 /// so that we don't reprocess them in every update. 3181 /// Note however that instructions in this set may cause UB. 3182 3183 protected: 3184 /// A set of all live instructions _known_ to cause UB. 3185 SmallPtrSet<Instruction *, 8> KnownUBInsts; 3186 3187 private: 3188 /// A set of all the (live) instructions that are assumed to _not_ cause UB. 3189 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts; 3190 3191 // Should be called on updates in which if we're processing an instruction 3192 // \p I that depends on a value \p V, one of the following has to happen: 3193 // - If the value is assumed, then stop. 3194 // - If the value is known but undef, then consider it UB. 3195 // - Otherwise, do specific processing with the simplified value. 3196 // We return std::nullopt in the first 2 cases to signify that an appropriate 3197 // action was taken and the caller should stop. 3198 // Otherwise, we return the simplified value that the caller should 3199 // use for specific processing. 3200 std::optional<Value *> stopOnUndefOrAssumed(Attributor &A, Value *V, 3201 Instruction *I) { 3202 bool UsedAssumedInformation = false; 3203 std::optional<Value *> SimplifiedV = 3204 A.getAssumedSimplified(IRPosition::value(*V), *this, 3205 UsedAssumedInformation, AA::Interprocedural); 3206 if (!UsedAssumedInformation) { 3207 // Don't depend on assumed values. 3208 if (!SimplifiedV) { 3209 // If it is known (which we tested above) but it doesn't have a value, 3210 // then we can assume `undef` and hence the instruction is UB. 3211 KnownUBInsts.insert(I); 3212 return std::nullopt; 3213 } 3214 if (!*SimplifiedV) 3215 return nullptr; 3216 V = *SimplifiedV; 3217 } 3218 if (isa<UndefValue>(V)) { 3219 KnownUBInsts.insert(I); 3220 return std::nullopt; 3221 } 3222 return V; 3223 } 3224 }; 3225 3226 struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl { 3227 AAUndefinedBehaviorFunction(const IRPosition &IRP, Attributor &A) 3228 : AAUndefinedBehaviorImpl(IRP, A) {} 3229 3230 /// See AbstractAttribute::trackStatistics() 3231 void trackStatistics() const override { 3232 STATS_DECL(UndefinedBehaviorInstruction, Instruction, 3233 "Number of instructions known to have UB"); 3234 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) += 3235 KnownUBInsts.size(); 3236 } 3237 }; 3238 } // namespace 3239 3240 /// ------------------------ Will-Return Attributes ---------------------------- 3241 3242 namespace { 3243 // Helper function that checks whether a function has any cycle which we don't 3244 // know if it is bounded or not. 3245 // Loops with maximum trip count are considered bounded, any other cycle not. 3246 static bool mayContainUnboundedCycle(Function &F, Attributor &A) { 3247 ScalarEvolution *SE = 3248 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(F); 3249 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(F); 3250 // If either SCEV or LoopInfo is not available for the function then we assume 3251 // any cycle to be unbounded cycle. 3252 // We use scc_iterator which uses Tarjan algorithm to find all the maximal 3253 // SCCs.To detect if there's a cycle, we only need to find the maximal ones. 3254 if (!SE || !LI) { 3255 for (scc_iterator<Function *> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI) 3256 if (SCCI.hasCycle()) 3257 return true; 3258 return false; 3259 } 3260 3261 // If there's irreducible control, the function may contain non-loop cycles. 3262 if (mayContainIrreducibleControl(F, LI)) 3263 return true; 3264 3265 // Any loop that does not have a max trip count is considered unbounded cycle. 3266 for (auto *L : LI->getLoopsInPreorder()) { 3267 if (!SE->getSmallConstantMaxTripCount(L)) 3268 return true; 3269 } 3270 return false; 3271 } 3272 3273 struct AAWillReturnImpl : public AAWillReturn { 3274 AAWillReturnImpl(const IRPosition &IRP, Attributor &A) 3275 : AAWillReturn(IRP, A) {} 3276 3277 /// See AbstractAttribute::initialize(...). 3278 void initialize(Attributor &A) override { 3279 bool IsKnown; 3280 assert(!AA::hasAssumedIRAttr<Attribute::WillReturn>( 3281 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown)); 3282 (void)IsKnown; 3283 } 3284 3285 /// Check for `mustprogress` and `readonly` as they imply `willreturn`. 3286 bool isImpliedByMustprogressAndReadonly(Attributor &A, bool KnownOnly) { 3287 if (!A.hasAttr(getIRPosition(), {Attribute::MustProgress})) 3288 return false; 3289 3290 bool IsKnown; 3291 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown)) 3292 return IsKnown || !KnownOnly; 3293 return false; 3294 } 3295 3296 /// See AbstractAttribute::updateImpl(...). 3297 ChangeStatus updateImpl(Attributor &A) override { 3298 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false)) 3299 return ChangeStatus::UNCHANGED; 3300 3301 auto CheckForWillReturn = [&](Instruction &I) { 3302 IRPosition IPos = IRPosition::callsite_function(cast<CallBase>(I)); 3303 bool IsKnown; 3304 if (AA::hasAssumedIRAttr<Attribute::WillReturn>( 3305 A, this, IPos, DepClassTy::REQUIRED, IsKnown)) { 3306 if (IsKnown) 3307 return true; 3308 } else { 3309 return false; 3310 } 3311 bool IsKnownNoRecurse; 3312 return AA::hasAssumedIRAttr<Attribute::NoRecurse>( 3313 A, this, IPos, DepClassTy::REQUIRED, IsKnownNoRecurse); 3314 }; 3315 3316 bool UsedAssumedInformation = false; 3317 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this, 3318 UsedAssumedInformation)) 3319 return indicatePessimisticFixpoint(); 3320 3321 return ChangeStatus::UNCHANGED; 3322 } 3323 3324 /// See AbstractAttribute::getAsStr() 3325 const std::string getAsStr(Attributor *A) const override { 3326 return getAssumed() ? "willreturn" : "may-noreturn"; 3327 } 3328 }; 3329 3330 struct AAWillReturnFunction final : AAWillReturnImpl { 3331 AAWillReturnFunction(const IRPosition &IRP, Attributor &A) 3332 : AAWillReturnImpl(IRP, A) {} 3333 3334 /// See AbstractAttribute::initialize(...). 3335 void initialize(Attributor &A) override { 3336 AAWillReturnImpl::initialize(A); 3337 3338 Function *F = getAnchorScope(); 3339 assert(F && "Did expect an anchor function"); 3340 if (F->isDeclaration() || mayContainUnboundedCycle(*F, A)) 3341 indicatePessimisticFixpoint(); 3342 } 3343 3344 /// See AbstractAttribute::trackStatistics() 3345 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) } 3346 }; 3347 3348 /// WillReturn attribute deduction for a call sites. 3349 struct AAWillReturnCallSite final 3350 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl> { 3351 AAWillReturnCallSite(const IRPosition &IRP, Attributor &A) 3352 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl>(IRP, A) {} 3353 3354 /// See AbstractAttribute::updateImpl(...). 3355 ChangeStatus updateImpl(Attributor &A) override { 3356 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false)) 3357 return ChangeStatus::UNCHANGED; 3358 3359 return AACalleeToCallSite::updateImpl(A); 3360 } 3361 3362 /// See AbstractAttribute::trackStatistics() 3363 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); } 3364 }; 3365 } // namespace 3366 3367 /// -------------------AAIntraFnReachability Attribute-------------------------- 3368 3369 /// All information associated with a reachability query. This boilerplate code 3370 /// is used by both AAIntraFnReachability and AAInterFnReachability, with 3371 /// different \p ToTy values. 3372 template <typename ToTy> struct ReachabilityQueryInfo { 3373 enum class Reachable { 3374 No, 3375 Yes, 3376 }; 3377 3378 /// Start here, 3379 const Instruction *From = nullptr; 3380 /// reach this place, 3381 const ToTy *To = nullptr; 3382 /// without going through any of these instructions, 3383 const AA::InstExclusionSetTy *ExclusionSet = nullptr; 3384 /// and remember if it worked: 3385 Reachable Result = Reachable::No; 3386 3387 /// Precomputed hash for this RQI. 3388 unsigned Hash = 0; 3389 3390 unsigned computeHashValue() const { 3391 assert(Hash == 0 && "Computed hash twice!"); 3392 using InstSetDMI = DenseMapInfo<const AA::InstExclusionSetTy *>; 3393 using PairDMI = DenseMapInfo<std::pair<const Instruction *, const ToTy *>>; 3394 return const_cast<ReachabilityQueryInfo<ToTy> *>(this)->Hash = 3395 detail::combineHashValue(PairDMI ::getHashValue({From, To}), 3396 InstSetDMI::getHashValue(ExclusionSet)); 3397 } 3398 3399 ReachabilityQueryInfo(const Instruction *From, const ToTy *To) 3400 : From(From), To(To) {} 3401 3402 /// Constructor replacement to ensure unique and stable sets are used for the 3403 /// cache. 3404 ReachabilityQueryInfo(Attributor &A, const Instruction &From, const ToTy &To, 3405 const AA::InstExclusionSetTy *ES, bool MakeUnique) 3406 : From(&From), To(&To), ExclusionSet(ES) { 3407 3408 if (!ES || ES->empty()) { 3409 ExclusionSet = nullptr; 3410 } else if (MakeUnique) { 3411 ExclusionSet = A.getInfoCache().getOrCreateUniqueBlockExecutionSet(ES); 3412 } 3413 } 3414 3415 ReachabilityQueryInfo(const ReachabilityQueryInfo &RQI) 3416 : From(RQI.From), To(RQI.To), ExclusionSet(RQI.ExclusionSet) {} 3417 }; 3418 3419 namespace llvm { 3420 template <typename ToTy> struct DenseMapInfo<ReachabilityQueryInfo<ToTy> *> { 3421 using InstSetDMI = DenseMapInfo<const AA::InstExclusionSetTy *>; 3422 using PairDMI = DenseMapInfo<std::pair<const Instruction *, const ToTy *>>; 3423 3424 static ReachabilityQueryInfo<ToTy> EmptyKey; 3425 static ReachabilityQueryInfo<ToTy> TombstoneKey; 3426 3427 static inline ReachabilityQueryInfo<ToTy> *getEmptyKey() { return &EmptyKey; } 3428 static inline ReachabilityQueryInfo<ToTy> *getTombstoneKey() { 3429 return &TombstoneKey; 3430 } 3431 static unsigned getHashValue(const ReachabilityQueryInfo<ToTy> *RQI) { 3432 return RQI->Hash ? RQI->Hash : RQI->computeHashValue(); 3433 } 3434 static bool isEqual(const ReachabilityQueryInfo<ToTy> *LHS, 3435 const ReachabilityQueryInfo<ToTy> *RHS) { 3436 if (!PairDMI::isEqual({LHS->From, LHS->To}, {RHS->From, RHS->To})) 3437 return false; 3438 return InstSetDMI::isEqual(LHS->ExclusionSet, RHS->ExclusionSet); 3439 } 3440 }; 3441 3442 #define DefineKeys(ToTy) \ 3443 template <> \ 3444 ReachabilityQueryInfo<ToTy> \ 3445 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::EmptyKey = \ 3446 ReachabilityQueryInfo<ToTy>( \ 3447 DenseMapInfo<const Instruction *>::getEmptyKey(), \ 3448 DenseMapInfo<const ToTy *>::getEmptyKey()); \ 3449 template <> \ 3450 ReachabilityQueryInfo<ToTy> \ 3451 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::TombstoneKey = \ 3452 ReachabilityQueryInfo<ToTy>( \ 3453 DenseMapInfo<const Instruction *>::getTombstoneKey(), \ 3454 DenseMapInfo<const ToTy *>::getTombstoneKey()); 3455 3456 DefineKeys(Instruction) DefineKeys(Function) 3457 #undef DefineKeys 3458 3459 } // namespace llvm 3460 3461 namespace { 3462 3463 template <typename BaseTy, typename ToTy> 3464 struct CachedReachabilityAA : public BaseTy { 3465 using RQITy = ReachabilityQueryInfo<ToTy>; 3466 3467 CachedReachabilityAA(const IRPosition &IRP, Attributor &A) : BaseTy(IRP, A) {} 3468 3469 /// See AbstractAttribute::isQueryAA. 3470 bool isQueryAA() const override { return true; } 3471 3472 /// See AbstractAttribute::updateImpl(...). 3473 ChangeStatus updateImpl(Attributor &A) override { 3474 ChangeStatus Changed = ChangeStatus::UNCHANGED; 3475 for (unsigned u = 0, e = QueryVector.size(); u < e; ++u) { 3476 RQITy *RQI = QueryVector[u]; 3477 if (RQI->Result == RQITy::Reachable::No && 3478 isReachableImpl(A, *RQI, /*IsTemporaryRQI=*/false)) 3479 Changed = ChangeStatus::CHANGED; 3480 } 3481 return Changed; 3482 } 3483 3484 virtual bool isReachableImpl(Attributor &A, RQITy &RQI, 3485 bool IsTemporaryRQI) = 0; 3486 3487 bool rememberResult(Attributor &A, typename RQITy::Reachable Result, 3488 RQITy &RQI, bool UsedExclusionSet, bool IsTemporaryRQI) { 3489 RQI.Result = Result; 3490 3491 // Remove the temporary RQI from the cache. 3492 if (IsTemporaryRQI) 3493 QueryCache.erase(&RQI); 3494 3495 // Insert a plain RQI (w/o exclusion set) if that makes sense. Two options: 3496 // 1) If it is reachable, it doesn't matter if we have an exclusion set for 3497 // this query. 2) We did not use the exclusion set, potentially because 3498 // there is none. 3499 if (Result == RQITy::Reachable::Yes || !UsedExclusionSet) { 3500 RQITy PlainRQI(RQI.From, RQI.To); 3501 if (!QueryCache.count(&PlainRQI)) { 3502 RQITy *RQIPtr = new (A.Allocator) RQITy(RQI.From, RQI.To); 3503 RQIPtr->Result = Result; 3504 QueryVector.push_back(RQIPtr); 3505 QueryCache.insert(RQIPtr); 3506 } 3507 } 3508 3509 // Check if we need to insert a new permanent RQI with the exclusion set. 3510 if (IsTemporaryRQI && Result != RQITy::Reachable::Yes && UsedExclusionSet) { 3511 assert((!RQI.ExclusionSet || !RQI.ExclusionSet->empty()) && 3512 "Did not expect empty set!"); 3513 RQITy *RQIPtr = new (A.Allocator) 3514 RQITy(A, *RQI.From, *RQI.To, RQI.ExclusionSet, true); 3515 assert(RQIPtr->Result == RQITy::Reachable::No && "Already reachable?"); 3516 RQIPtr->Result = Result; 3517 assert(!QueryCache.count(RQIPtr)); 3518 QueryVector.push_back(RQIPtr); 3519 QueryCache.insert(RQIPtr); 3520 } 3521 3522 if (Result == RQITy::Reachable::No && IsTemporaryRQI) 3523 A.registerForUpdate(*this); 3524 return Result == RQITy::Reachable::Yes; 3525 } 3526 3527 const std::string getAsStr(Attributor *A) const override { 3528 // TODO: Return the number of reachable queries. 3529 return "#queries(" + std::to_string(QueryVector.size()) + ")"; 3530 } 3531 3532 bool checkQueryCache(Attributor &A, RQITy &StackRQI, 3533 typename RQITy::Reachable &Result) { 3534 if (!this->getState().isValidState()) { 3535 Result = RQITy::Reachable::Yes; 3536 return true; 3537 } 3538 3539 // If we have an exclusion set we might be able to find our answer by 3540 // ignoring it first. 3541 if (StackRQI.ExclusionSet) { 3542 RQITy PlainRQI(StackRQI.From, StackRQI.To); 3543 auto It = QueryCache.find(&PlainRQI); 3544 if (It != QueryCache.end() && (*It)->Result == RQITy::Reachable::No) { 3545 Result = RQITy::Reachable::No; 3546 return true; 3547 } 3548 } 3549 3550 auto It = QueryCache.find(&StackRQI); 3551 if (It != QueryCache.end()) { 3552 Result = (*It)->Result; 3553 return true; 3554 } 3555 3556 // Insert a temporary for recursive queries. We will replace it with a 3557 // permanent entry later. 3558 QueryCache.insert(&StackRQI); 3559 return false; 3560 } 3561 3562 private: 3563 SmallVector<RQITy *> QueryVector; 3564 DenseSet<RQITy *> QueryCache; 3565 }; 3566 3567 struct AAIntraFnReachabilityFunction final 3568 : public CachedReachabilityAA<AAIntraFnReachability, Instruction> { 3569 using Base = CachedReachabilityAA<AAIntraFnReachability, Instruction>; 3570 AAIntraFnReachabilityFunction(const IRPosition &IRP, Attributor &A) 3571 : Base(IRP, A) { 3572 DT = A.getInfoCache().getAnalysisResultForFunction<DominatorTreeAnalysis>( 3573 *IRP.getAssociatedFunction()); 3574 } 3575 3576 bool isAssumedReachable( 3577 Attributor &A, const Instruction &From, const Instruction &To, 3578 const AA::InstExclusionSetTy *ExclusionSet) const override { 3579 auto *NonConstThis = const_cast<AAIntraFnReachabilityFunction *>(this); 3580 if (&From == &To) 3581 return true; 3582 3583 RQITy StackRQI(A, From, To, ExclusionSet, false); 3584 typename RQITy::Reachable Result; 3585 if (!NonConstThis->checkQueryCache(A, StackRQI, Result)) 3586 return NonConstThis->isReachableImpl(A, StackRQI, 3587 /*IsTemporaryRQI=*/true); 3588 return Result == RQITy::Reachable::Yes; 3589 } 3590 3591 ChangeStatus updateImpl(Attributor &A) override { 3592 // We only depend on liveness. DeadEdges is all we care about, check if any 3593 // of them changed. 3594 auto *LivenessAA = 3595 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL); 3596 if (LivenessAA && 3597 llvm::all_of(DeadEdges, 3598 [&](const auto &DeadEdge) { 3599 return LivenessAA->isEdgeDead(DeadEdge.first, 3600 DeadEdge.second); 3601 }) && 3602 llvm::all_of(DeadBlocks, [&](const BasicBlock *BB) { 3603 return LivenessAA->isAssumedDead(BB); 3604 })) { 3605 return ChangeStatus::UNCHANGED; 3606 } 3607 DeadEdges.clear(); 3608 DeadBlocks.clear(); 3609 return Base::updateImpl(A); 3610 } 3611 3612 bool isReachableImpl(Attributor &A, RQITy &RQI, 3613 bool IsTemporaryRQI) override { 3614 const Instruction *Origin = RQI.From; 3615 bool UsedExclusionSet = false; 3616 3617 auto WillReachInBlock = [&](const Instruction &From, const Instruction &To, 3618 const AA::InstExclusionSetTy *ExclusionSet) { 3619 const Instruction *IP = &From; 3620 while (IP && IP != &To) { 3621 if (ExclusionSet && IP != Origin && ExclusionSet->count(IP)) { 3622 UsedExclusionSet = true; 3623 break; 3624 } 3625 IP = IP->getNextNode(); 3626 } 3627 return IP == &To; 3628 }; 3629 3630 const BasicBlock *FromBB = RQI.From->getParent(); 3631 const BasicBlock *ToBB = RQI.To->getParent(); 3632 assert(FromBB->getParent() == ToBB->getParent() && 3633 "Not an intra-procedural query!"); 3634 3635 // Check intra-block reachability, however, other reaching paths are still 3636 // possible. 3637 if (FromBB == ToBB && 3638 WillReachInBlock(*RQI.From, *RQI.To, RQI.ExclusionSet)) 3639 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet, 3640 IsTemporaryRQI); 3641 3642 // Check if reaching the ToBB block is sufficient or if even that would not 3643 // ensure reaching the target. In the latter case we are done. 3644 if (!WillReachInBlock(ToBB->front(), *RQI.To, RQI.ExclusionSet)) 3645 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet, 3646 IsTemporaryRQI); 3647 3648 const Function *Fn = FromBB->getParent(); 3649 SmallPtrSet<const BasicBlock *, 16> ExclusionBlocks; 3650 if (RQI.ExclusionSet) 3651 for (auto *I : *RQI.ExclusionSet) 3652 if (I->getFunction() == Fn) 3653 ExclusionBlocks.insert(I->getParent()); 3654 3655 // Check if we make it out of the FromBB block at all. 3656 if (ExclusionBlocks.count(FromBB) && 3657 !WillReachInBlock(*RQI.From, *FromBB->getTerminator(), 3658 RQI.ExclusionSet)) 3659 return rememberResult(A, RQITy::Reachable::No, RQI, true, IsTemporaryRQI); 3660 3661 auto *LivenessAA = 3662 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL); 3663 if (LivenessAA && LivenessAA->isAssumedDead(ToBB)) { 3664 DeadBlocks.insert(ToBB); 3665 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet, 3666 IsTemporaryRQI); 3667 } 3668 3669 SmallPtrSet<const BasicBlock *, 16> Visited; 3670 SmallVector<const BasicBlock *, 16> Worklist; 3671 Worklist.push_back(FromBB); 3672 3673 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> LocalDeadEdges; 3674 while (!Worklist.empty()) { 3675 const BasicBlock *BB = Worklist.pop_back_val(); 3676 if (!Visited.insert(BB).second) 3677 continue; 3678 for (const BasicBlock *SuccBB : successors(BB)) { 3679 if (LivenessAA && LivenessAA->isEdgeDead(BB, SuccBB)) { 3680 LocalDeadEdges.insert({BB, SuccBB}); 3681 continue; 3682 } 3683 // We checked before if we just need to reach the ToBB block. 3684 if (SuccBB == ToBB) 3685 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet, 3686 IsTemporaryRQI); 3687 if (DT && ExclusionBlocks.empty() && DT->dominates(BB, ToBB)) 3688 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet, 3689 IsTemporaryRQI); 3690 3691 if (ExclusionBlocks.count(SuccBB)) { 3692 UsedExclusionSet = true; 3693 continue; 3694 } 3695 Worklist.push_back(SuccBB); 3696 } 3697 } 3698 3699 DeadEdges.insert(LocalDeadEdges.begin(), LocalDeadEdges.end()); 3700 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet, 3701 IsTemporaryRQI); 3702 } 3703 3704 /// See AbstractAttribute::trackStatistics() 3705 void trackStatistics() const override {} 3706 3707 private: 3708 // Set of assumed dead blocks we used in the last query. If any changes we 3709 // update the state. 3710 DenseSet<const BasicBlock *> DeadBlocks; 3711 3712 // Set of assumed dead edges we used in the last query. If any changes we 3713 // update the state. 3714 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> DeadEdges; 3715 3716 /// The dominator tree of the function to short-circuit reasoning. 3717 const DominatorTree *DT = nullptr; 3718 }; 3719 } // namespace 3720 3721 /// ------------------------ NoAlias Argument Attribute ------------------------ 3722 3723 bool AANoAlias::isImpliedByIR(Attributor &A, const IRPosition &IRP, 3724 Attribute::AttrKind ImpliedAttributeKind, 3725 bool IgnoreSubsumingPositions) { 3726 assert(ImpliedAttributeKind == Attribute::NoAlias && 3727 "Unexpected attribute kind"); 3728 Value *Val = &IRP.getAssociatedValue(); 3729 if (IRP.getPositionKind() != IRP_CALL_SITE_ARGUMENT) { 3730 if (isa<AllocaInst>(Val)) 3731 return true; 3732 } else { 3733 IgnoreSubsumingPositions = true; 3734 } 3735 3736 if (isa<UndefValue>(Val)) 3737 return true; 3738 3739 if (isa<ConstantPointerNull>(Val) && 3740 !NullPointerIsDefined(IRP.getAnchorScope(), 3741 Val->getType()->getPointerAddressSpace())) 3742 return true; 3743 3744 if (A.hasAttr(IRP, {Attribute::ByVal, Attribute::NoAlias}, 3745 IgnoreSubsumingPositions, Attribute::NoAlias)) 3746 return true; 3747 3748 return false; 3749 } 3750 3751 namespace { 3752 struct AANoAliasImpl : AANoAlias { 3753 AANoAliasImpl(const IRPosition &IRP, Attributor &A) : AANoAlias(IRP, A) { 3754 assert(getAssociatedType()->isPointerTy() && 3755 "Noalias is a pointer attribute"); 3756 } 3757 3758 const std::string getAsStr(Attributor *A) const override { 3759 return getAssumed() ? "noalias" : "may-alias"; 3760 } 3761 }; 3762 3763 /// NoAlias attribute for a floating value. 3764 struct AANoAliasFloating final : AANoAliasImpl { 3765 AANoAliasFloating(const IRPosition &IRP, Attributor &A) 3766 : AANoAliasImpl(IRP, A) {} 3767 3768 /// See AbstractAttribute::updateImpl(...). 3769 ChangeStatus updateImpl(Attributor &A) override { 3770 // TODO: Implement this. 3771 return indicatePessimisticFixpoint(); 3772 } 3773 3774 /// See AbstractAttribute::trackStatistics() 3775 void trackStatistics() const override { 3776 STATS_DECLTRACK_FLOATING_ATTR(noalias) 3777 } 3778 }; 3779 3780 /// NoAlias attribute for an argument. 3781 struct AANoAliasArgument final 3782 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> { 3783 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>; 3784 AANoAliasArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {} 3785 3786 /// See AbstractAttribute::update(...). 3787 ChangeStatus updateImpl(Attributor &A) override { 3788 // We have to make sure no-alias on the argument does not break 3789 // synchronization when this is a callback argument, see also [1] below. 3790 // If synchronization cannot be affected, we delegate to the base updateImpl 3791 // function, otherwise we give up for now. 3792 3793 // If the function is no-sync, no-alias cannot break synchronization. 3794 bool IsKnownNoSycn; 3795 if (AA::hasAssumedIRAttr<Attribute::NoSync>( 3796 A, this, IRPosition::function_scope(getIRPosition()), 3797 DepClassTy::OPTIONAL, IsKnownNoSycn)) 3798 return Base::updateImpl(A); 3799 3800 // If the argument is read-only, no-alias cannot break synchronization. 3801 bool IsKnown; 3802 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown)) 3803 return Base::updateImpl(A); 3804 3805 // If the argument is never passed through callbacks, no-alias cannot break 3806 // synchronization. 3807 bool UsedAssumedInformation = false; 3808 if (A.checkForAllCallSites( 3809 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this, 3810 true, UsedAssumedInformation)) 3811 return Base::updateImpl(A); 3812 3813 // TODO: add no-alias but make sure it doesn't break synchronization by 3814 // introducing fake uses. See: 3815 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel, 3816 // International Workshop on OpenMP 2018, 3817 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf 3818 3819 return indicatePessimisticFixpoint(); 3820 } 3821 3822 /// See AbstractAttribute::trackStatistics() 3823 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) } 3824 }; 3825 3826 struct AANoAliasCallSiteArgument final : AANoAliasImpl { 3827 AANoAliasCallSiteArgument(const IRPosition &IRP, Attributor &A) 3828 : AANoAliasImpl(IRP, A) {} 3829 3830 /// Determine if the underlying value may alias with the call site argument 3831 /// \p OtherArgNo of \p ICS (= the underlying call site). 3832 bool mayAliasWithArgument(Attributor &A, AAResults *&AAR, 3833 const AAMemoryBehavior &MemBehaviorAA, 3834 const CallBase &CB, unsigned OtherArgNo) { 3835 // We do not need to worry about aliasing with the underlying IRP. 3836 if (this->getCalleeArgNo() == (int)OtherArgNo) 3837 return false; 3838 3839 // If it is not a pointer or pointer vector we do not alias. 3840 const Value *ArgOp = CB.getArgOperand(OtherArgNo); 3841 if (!ArgOp->getType()->isPtrOrPtrVectorTy()) 3842 return false; 3843 3844 auto *CBArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>( 3845 *this, IRPosition::callsite_argument(CB, OtherArgNo), DepClassTy::NONE); 3846 3847 // If the argument is readnone, there is no read-write aliasing. 3848 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadNone()) { 3849 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL); 3850 return false; 3851 } 3852 3853 // If the argument is readonly and the underlying value is readonly, there 3854 // is no read-write aliasing. 3855 bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly(); 3856 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadOnly() && 3857 IsReadOnly) { 3858 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL); 3859 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL); 3860 return false; 3861 } 3862 3863 // We have to utilize actual alias analysis queries so we need the object. 3864 if (!AAR) 3865 AAR = A.getInfoCache().getAnalysisResultForFunction<AAManager>( 3866 *getAnchorScope()); 3867 3868 // Try to rule it out at the call site. 3869 bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp); 3870 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between " 3871 "callsite arguments: " 3872 << getAssociatedValue() << " " << *ArgOp << " => " 3873 << (IsAliasing ? "" : "no-") << "alias \n"); 3874 3875 return IsAliasing; 3876 } 3877 3878 bool isKnownNoAliasDueToNoAliasPreservation( 3879 Attributor &A, AAResults *&AAR, const AAMemoryBehavior &MemBehaviorAA) { 3880 // We can deduce "noalias" if the following conditions hold. 3881 // (i) Associated value is assumed to be noalias in the definition. 3882 // (ii) Associated value is assumed to be no-capture in all the uses 3883 // possibly executed before this callsite. 3884 // (iii) There is no other pointer argument which could alias with the 3885 // value. 3886 3887 auto IsDereferenceableOrNull = [&](Value *O, const DataLayout &DL) { 3888 const auto *DerefAA = A.getAAFor<AADereferenceable>( 3889 *this, IRPosition::value(*O), DepClassTy::OPTIONAL); 3890 return DerefAA ? DerefAA->getAssumedDereferenceableBytes() : 0; 3891 }; 3892 3893 const IRPosition &VIRP = IRPosition::value(getAssociatedValue()); 3894 const Function *ScopeFn = VIRP.getAnchorScope(); 3895 // Check whether the value is captured in the scope using AANoCapture. 3896 // Look at CFG and check only uses possibly executed before this 3897 // callsite. 3898 auto UsePred = [&](const Use &U, bool &Follow) -> bool { 3899 Instruction *UserI = cast<Instruction>(U.getUser()); 3900 3901 // If UserI is the curr instruction and there is a single potential use of 3902 // the value in UserI we allow the use. 3903 // TODO: We should inspect the operands and allow those that cannot alias 3904 // with the value. 3905 if (UserI == getCtxI() && UserI->getNumOperands() == 1) 3906 return true; 3907 3908 if (ScopeFn) { 3909 if (auto *CB = dyn_cast<CallBase>(UserI)) { 3910 if (CB->isArgOperand(&U)) { 3911 3912 unsigned ArgNo = CB->getArgOperandNo(&U); 3913 3914 bool IsKnownNoCapture; 3915 if (AA::hasAssumedIRAttr<Attribute::NoCapture>( 3916 A, this, IRPosition::callsite_argument(*CB, ArgNo), 3917 DepClassTy::OPTIONAL, IsKnownNoCapture)) 3918 return true; 3919 } 3920 } 3921 3922 if (!AA::isPotentiallyReachable( 3923 A, *UserI, *getCtxI(), *this, /* ExclusionSet */ nullptr, 3924 [ScopeFn](const Function &Fn) { return &Fn != ScopeFn; })) 3925 return true; 3926 } 3927 3928 // TODO: We should track the capturing uses in AANoCapture but the problem 3929 // is CGSCC runs. For those we would need to "allow" AANoCapture for 3930 // a value in the module slice. 3931 switch (DetermineUseCaptureKind(U, IsDereferenceableOrNull)) { 3932 case UseCaptureKind::NO_CAPTURE: 3933 return true; 3934 case UseCaptureKind::MAY_CAPTURE: 3935 LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *UserI 3936 << "\n"); 3937 return false; 3938 case UseCaptureKind::PASSTHROUGH: 3939 Follow = true; 3940 return true; 3941 } 3942 llvm_unreachable("unknown UseCaptureKind"); 3943 }; 3944 3945 bool IsKnownNoCapture; 3946 const AANoCapture *NoCaptureAA = nullptr; 3947 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>( 3948 A, this, VIRP, DepClassTy::NONE, IsKnownNoCapture, false, &NoCaptureAA); 3949 if (!IsAssumedNoCapture && 3950 (!NoCaptureAA || !NoCaptureAA->isAssumedNoCaptureMaybeReturned())) { 3951 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) { 3952 LLVM_DEBUG( 3953 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue() 3954 << " cannot be noalias as it is potentially captured\n"); 3955 return false; 3956 } 3957 } 3958 if (NoCaptureAA) 3959 A.recordDependence(*NoCaptureAA, *this, DepClassTy::OPTIONAL); 3960 3961 // Check there is no other pointer argument which could alias with the 3962 // value passed at this call site. 3963 // TODO: AbstractCallSite 3964 const auto &CB = cast<CallBase>(getAnchorValue()); 3965 for (unsigned OtherArgNo = 0; OtherArgNo < CB.arg_size(); OtherArgNo++) 3966 if (mayAliasWithArgument(A, AAR, MemBehaviorAA, CB, OtherArgNo)) 3967 return false; 3968 3969 return true; 3970 } 3971 3972 /// See AbstractAttribute::updateImpl(...). 3973 ChangeStatus updateImpl(Attributor &A) override { 3974 // If the argument is readnone we are done as there are no accesses via the 3975 // argument. 3976 auto *MemBehaviorAA = 3977 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE); 3978 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) { 3979 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL); 3980 return ChangeStatus::UNCHANGED; 3981 } 3982 3983 bool IsKnownNoAlias; 3984 const IRPosition &VIRP = IRPosition::value(getAssociatedValue()); 3985 if (!AA::hasAssumedIRAttr<Attribute::NoAlias>( 3986 A, this, VIRP, DepClassTy::REQUIRED, IsKnownNoAlias)) { 3987 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue() 3988 << " is not no-alias at the definition\n"); 3989 return indicatePessimisticFixpoint(); 3990 } 3991 3992 AAResults *AAR = nullptr; 3993 if (MemBehaviorAA && 3994 isKnownNoAliasDueToNoAliasPreservation(A, AAR, *MemBehaviorAA)) { 3995 LLVM_DEBUG( 3996 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n"); 3997 return ChangeStatus::UNCHANGED; 3998 } 3999 4000 return indicatePessimisticFixpoint(); 4001 } 4002 4003 /// See AbstractAttribute::trackStatistics() 4004 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) } 4005 }; 4006 4007 /// NoAlias attribute for function return value. 4008 struct AANoAliasReturned final : AANoAliasImpl { 4009 AANoAliasReturned(const IRPosition &IRP, Attributor &A) 4010 : AANoAliasImpl(IRP, A) {} 4011 4012 /// See AbstractAttribute::updateImpl(...). 4013 ChangeStatus updateImpl(Attributor &A) override { 4014 4015 auto CheckReturnValue = [&](Value &RV) -> bool { 4016 if (Constant *C = dyn_cast<Constant>(&RV)) 4017 if (C->isNullValue() || isa<UndefValue>(C)) 4018 return true; 4019 4020 /// For now, we can only deduce noalias if we have call sites. 4021 /// FIXME: add more support. 4022 if (!isa<CallBase>(&RV)) 4023 return false; 4024 4025 const IRPosition &RVPos = IRPosition::value(RV); 4026 bool IsKnownNoAlias; 4027 if (!AA::hasAssumedIRAttr<Attribute::NoAlias>( 4028 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoAlias)) 4029 return false; 4030 4031 bool IsKnownNoCapture; 4032 const AANoCapture *NoCaptureAA = nullptr; 4033 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>( 4034 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoCapture, false, 4035 &NoCaptureAA); 4036 return IsAssumedNoCapture || 4037 (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned()); 4038 }; 4039 4040 if (!A.checkForAllReturnedValues(CheckReturnValue, *this)) 4041 return indicatePessimisticFixpoint(); 4042 4043 return ChangeStatus::UNCHANGED; 4044 } 4045 4046 /// See AbstractAttribute::trackStatistics() 4047 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) } 4048 }; 4049 4050 /// NoAlias attribute deduction for a call site return value. 4051 struct AANoAliasCallSiteReturned final 4052 : AACalleeToCallSite<AANoAlias, AANoAliasImpl> { 4053 AANoAliasCallSiteReturned(const IRPosition &IRP, Attributor &A) 4054 : AACalleeToCallSite<AANoAlias, AANoAliasImpl>(IRP, A) {} 4055 4056 /// See AbstractAttribute::trackStatistics() 4057 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); } 4058 }; 4059 } // namespace 4060 4061 /// -------------------AAIsDead Function Attribute----------------------- 4062 4063 namespace { 4064 struct AAIsDeadValueImpl : public AAIsDead { 4065 AAIsDeadValueImpl(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {} 4066 4067 /// See AAIsDead::isAssumedDead(). 4068 bool isAssumedDead() const override { return isAssumed(IS_DEAD); } 4069 4070 /// See AAIsDead::isKnownDead(). 4071 bool isKnownDead() const override { return isKnown(IS_DEAD); } 4072 4073 /// See AAIsDead::isAssumedDead(BasicBlock *). 4074 bool isAssumedDead(const BasicBlock *BB) const override { return false; } 4075 4076 /// See AAIsDead::isKnownDead(BasicBlock *). 4077 bool isKnownDead(const BasicBlock *BB) const override { return false; } 4078 4079 /// See AAIsDead::isAssumedDead(Instruction *I). 4080 bool isAssumedDead(const Instruction *I) const override { 4081 return I == getCtxI() && isAssumedDead(); 4082 } 4083 4084 /// See AAIsDead::isKnownDead(Instruction *I). 4085 bool isKnownDead(const Instruction *I) const override { 4086 return isAssumedDead(I) && isKnownDead(); 4087 } 4088 4089 /// See AbstractAttribute::getAsStr(). 4090 const std::string getAsStr(Attributor *A) const override { 4091 return isAssumedDead() ? "assumed-dead" : "assumed-live"; 4092 } 4093 4094 /// Check if all uses are assumed dead. 4095 bool areAllUsesAssumedDead(Attributor &A, Value &V) { 4096 // Callers might not check the type, void has no uses. 4097 if (V.getType()->isVoidTy() || V.use_empty()) 4098 return true; 4099 4100 // If we replace a value with a constant there are no uses left afterwards. 4101 if (!isa<Constant>(V)) { 4102 if (auto *I = dyn_cast<Instruction>(&V)) 4103 if (!A.isRunOn(*I->getFunction())) 4104 return false; 4105 bool UsedAssumedInformation = false; 4106 std::optional<Constant *> C = 4107 A.getAssumedConstant(V, *this, UsedAssumedInformation); 4108 if (!C || *C) 4109 return true; 4110 } 4111 4112 auto UsePred = [&](const Use &U, bool &Follow) { return false; }; 4113 // Explicitly set the dependence class to required because we want a long 4114 // chain of N dependent instructions to be considered live as soon as one is 4115 // without going through N update cycles. This is not required for 4116 // correctness. 4117 return A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ false, 4118 DepClassTy::REQUIRED, 4119 /* IgnoreDroppableUses */ false); 4120 } 4121 4122 /// Determine if \p I is assumed to be side-effect free. 4123 bool isAssumedSideEffectFree(Attributor &A, Instruction *I) { 4124 if (!I || wouldInstructionBeTriviallyDead(I)) 4125 return true; 4126 4127 auto *CB = dyn_cast<CallBase>(I); 4128 if (!CB || isa<IntrinsicInst>(CB)) 4129 return false; 4130 4131 const IRPosition &CallIRP = IRPosition::callsite_function(*CB); 4132 4133 bool IsKnownNoUnwind; 4134 if (!AA::hasAssumedIRAttr<Attribute::NoUnwind>( 4135 A, this, CallIRP, DepClassTy::OPTIONAL, IsKnownNoUnwind)) 4136 return false; 4137 4138 bool IsKnown; 4139 return AA::isAssumedReadOnly(A, CallIRP, *this, IsKnown); 4140 } 4141 }; 4142 4143 struct AAIsDeadFloating : public AAIsDeadValueImpl { 4144 AAIsDeadFloating(const IRPosition &IRP, Attributor &A) 4145 : AAIsDeadValueImpl(IRP, A) {} 4146 4147 /// See AbstractAttribute::initialize(...). 4148 void initialize(Attributor &A) override { 4149 AAIsDeadValueImpl::initialize(A); 4150 4151 if (isa<UndefValue>(getAssociatedValue())) { 4152 indicatePessimisticFixpoint(); 4153 return; 4154 } 4155 4156 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()); 4157 if (!isAssumedSideEffectFree(A, I)) { 4158 if (!isa_and_nonnull<StoreInst>(I) && !isa_and_nonnull<FenceInst>(I)) 4159 indicatePessimisticFixpoint(); 4160 else 4161 removeAssumedBits(HAS_NO_EFFECT); 4162 } 4163 } 4164 4165 bool isDeadFence(Attributor &A, FenceInst &FI) { 4166 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>( 4167 IRPosition::function(*FI.getFunction()), *this, DepClassTy::NONE); 4168 if (!ExecDomainAA || !ExecDomainAA->isNoOpFence(FI)) 4169 return false; 4170 A.recordDependence(*ExecDomainAA, *this, DepClassTy::OPTIONAL); 4171 return true; 4172 } 4173 4174 bool isDeadStore(Attributor &A, StoreInst &SI, 4175 SmallSetVector<Instruction *, 8> *AssumeOnlyInst = nullptr) { 4176 // Lang ref now states volatile store is not UB/dead, let's skip them. 4177 if (SI.isVolatile()) 4178 return false; 4179 4180 // If we are collecting assumes to be deleted we are in the manifest stage. 4181 // It's problematic to collect the potential copies again now so we use the 4182 // cached ones. 4183 bool UsedAssumedInformation = false; 4184 if (!AssumeOnlyInst) { 4185 PotentialCopies.clear(); 4186 if (!AA::getPotentialCopiesOfStoredValue(A, SI, PotentialCopies, *this, 4187 UsedAssumedInformation)) { 4188 LLVM_DEBUG( 4189 dbgs() 4190 << "[AAIsDead] Could not determine potential copies of store!\n"); 4191 return false; 4192 } 4193 } 4194 LLVM_DEBUG(dbgs() << "[AAIsDead] Store has " << PotentialCopies.size() 4195 << " potential copies.\n"); 4196 4197 InformationCache &InfoCache = A.getInfoCache(); 4198 return llvm::all_of(PotentialCopies, [&](Value *V) { 4199 if (A.isAssumedDead(IRPosition::value(*V), this, nullptr, 4200 UsedAssumedInformation)) 4201 return true; 4202 if (auto *LI = dyn_cast<LoadInst>(V)) { 4203 if (llvm::all_of(LI->uses(), [&](const Use &U) { 4204 auto &UserI = cast<Instruction>(*U.getUser()); 4205 if (InfoCache.isOnlyUsedByAssume(UserI)) { 4206 if (AssumeOnlyInst) 4207 AssumeOnlyInst->insert(&UserI); 4208 return true; 4209 } 4210 return A.isAssumedDead(U, this, nullptr, UsedAssumedInformation); 4211 })) { 4212 return true; 4213 } 4214 } 4215 LLVM_DEBUG(dbgs() << "[AAIsDead] Potential copy " << *V 4216 << " is assumed live!\n"); 4217 return false; 4218 }); 4219 } 4220 4221 /// See AbstractAttribute::getAsStr(). 4222 const std::string getAsStr(Attributor *A) const override { 4223 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()); 4224 if (isa_and_nonnull<StoreInst>(I)) 4225 if (isValidState()) 4226 return "assumed-dead-store"; 4227 if (isa_and_nonnull<FenceInst>(I)) 4228 if (isValidState()) 4229 return "assumed-dead-fence"; 4230 return AAIsDeadValueImpl::getAsStr(A); 4231 } 4232 4233 /// See AbstractAttribute::updateImpl(...). 4234 ChangeStatus updateImpl(Attributor &A) override { 4235 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()); 4236 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) { 4237 if (!isDeadStore(A, *SI)) 4238 return indicatePessimisticFixpoint(); 4239 } else if (auto *FI = dyn_cast_or_null<FenceInst>(I)) { 4240 if (!isDeadFence(A, *FI)) 4241 return indicatePessimisticFixpoint(); 4242 } else { 4243 if (!isAssumedSideEffectFree(A, I)) 4244 return indicatePessimisticFixpoint(); 4245 if (!areAllUsesAssumedDead(A, getAssociatedValue())) 4246 return indicatePessimisticFixpoint(); 4247 } 4248 return ChangeStatus::UNCHANGED; 4249 } 4250 4251 bool isRemovableStore() const override { 4252 return isAssumed(IS_REMOVABLE) && isa<StoreInst>(&getAssociatedValue()); 4253 } 4254 4255 /// See AbstractAttribute::manifest(...). 4256 ChangeStatus manifest(Attributor &A) override { 4257 Value &V = getAssociatedValue(); 4258 if (auto *I = dyn_cast<Instruction>(&V)) { 4259 // If we get here we basically know the users are all dead. We check if 4260 // isAssumedSideEffectFree returns true here again because it might not be 4261 // the case and only the users are dead but the instruction (=call) is 4262 // still needed. 4263 if (auto *SI = dyn_cast<StoreInst>(I)) { 4264 SmallSetVector<Instruction *, 8> AssumeOnlyInst; 4265 bool IsDead = isDeadStore(A, *SI, &AssumeOnlyInst); 4266 (void)IsDead; 4267 assert(IsDead && "Store was assumed to be dead!"); 4268 A.deleteAfterManifest(*I); 4269 for (size_t i = 0; i < AssumeOnlyInst.size(); ++i) { 4270 Instruction *AOI = AssumeOnlyInst[i]; 4271 for (auto *Usr : AOI->users()) 4272 AssumeOnlyInst.insert(cast<Instruction>(Usr)); 4273 A.deleteAfterManifest(*AOI); 4274 } 4275 return ChangeStatus::CHANGED; 4276 } 4277 if (auto *FI = dyn_cast<FenceInst>(I)) { 4278 assert(isDeadFence(A, *FI)); 4279 A.deleteAfterManifest(*FI); 4280 return ChangeStatus::CHANGED; 4281 } 4282 if (isAssumedSideEffectFree(A, I) && !isa<InvokeInst>(I)) { 4283 A.deleteAfterManifest(*I); 4284 return ChangeStatus::CHANGED; 4285 } 4286 } 4287 return ChangeStatus::UNCHANGED; 4288 } 4289 4290 /// See AbstractAttribute::trackStatistics() 4291 void trackStatistics() const override { 4292 STATS_DECLTRACK_FLOATING_ATTR(IsDead) 4293 } 4294 4295 private: 4296 // The potential copies of a dead store, used for deletion during manifest. 4297 SmallSetVector<Value *, 4> PotentialCopies; 4298 }; 4299 4300 struct AAIsDeadArgument : public AAIsDeadFloating { 4301 AAIsDeadArgument(const IRPosition &IRP, Attributor &A) 4302 : AAIsDeadFloating(IRP, A) {} 4303 4304 /// See AbstractAttribute::manifest(...). 4305 ChangeStatus manifest(Attributor &A) override { 4306 Argument &Arg = *getAssociatedArgument(); 4307 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {})) 4308 if (A.registerFunctionSignatureRewrite( 4309 Arg, /* ReplacementTypes */ {}, 4310 Attributor::ArgumentReplacementInfo::CalleeRepairCBTy{}, 4311 Attributor::ArgumentReplacementInfo::ACSRepairCBTy{})) { 4312 return ChangeStatus::CHANGED; 4313 } 4314 return ChangeStatus::UNCHANGED; 4315 } 4316 4317 /// See AbstractAttribute::trackStatistics() 4318 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) } 4319 }; 4320 4321 struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl { 4322 AAIsDeadCallSiteArgument(const IRPosition &IRP, Attributor &A) 4323 : AAIsDeadValueImpl(IRP, A) {} 4324 4325 /// See AbstractAttribute::initialize(...). 4326 void initialize(Attributor &A) override { 4327 AAIsDeadValueImpl::initialize(A); 4328 if (isa<UndefValue>(getAssociatedValue())) 4329 indicatePessimisticFixpoint(); 4330 } 4331 4332 /// See AbstractAttribute::updateImpl(...). 4333 ChangeStatus updateImpl(Attributor &A) override { 4334 // TODO: Once we have call site specific value information we can provide 4335 // call site specific liveness information and then it makes 4336 // sense to specialize attributes for call sites arguments instead of 4337 // redirecting requests to the callee argument. 4338 Argument *Arg = getAssociatedArgument(); 4339 if (!Arg) 4340 return indicatePessimisticFixpoint(); 4341 const IRPosition &ArgPos = IRPosition::argument(*Arg); 4342 auto *ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos, DepClassTy::REQUIRED); 4343 if (!ArgAA) 4344 return indicatePessimisticFixpoint(); 4345 return clampStateAndIndicateChange(getState(), ArgAA->getState()); 4346 } 4347 4348 /// See AbstractAttribute::manifest(...). 4349 ChangeStatus manifest(Attributor &A) override { 4350 CallBase &CB = cast<CallBase>(getAnchorValue()); 4351 Use &U = CB.getArgOperandUse(getCallSiteArgNo()); 4352 assert(!isa<UndefValue>(U.get()) && 4353 "Expected undef values to be filtered out!"); 4354 UndefValue &UV = *UndefValue::get(U->getType()); 4355 if (A.changeUseAfterManifest(U, UV)) 4356 return ChangeStatus::CHANGED; 4357 return ChangeStatus::UNCHANGED; 4358 } 4359 4360 /// See AbstractAttribute::trackStatistics() 4361 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) } 4362 }; 4363 4364 struct AAIsDeadCallSiteReturned : public AAIsDeadFloating { 4365 AAIsDeadCallSiteReturned(const IRPosition &IRP, Attributor &A) 4366 : AAIsDeadFloating(IRP, A) {} 4367 4368 /// See AAIsDead::isAssumedDead(). 4369 bool isAssumedDead() const override { 4370 return AAIsDeadFloating::isAssumedDead() && IsAssumedSideEffectFree; 4371 } 4372 4373 /// See AbstractAttribute::initialize(...). 4374 void initialize(Attributor &A) override { 4375 AAIsDeadFloating::initialize(A); 4376 if (isa<UndefValue>(getAssociatedValue())) { 4377 indicatePessimisticFixpoint(); 4378 return; 4379 } 4380 4381 // We track this separately as a secondary state. 4382 IsAssumedSideEffectFree = isAssumedSideEffectFree(A, getCtxI()); 4383 } 4384 4385 /// See AbstractAttribute::updateImpl(...). 4386 ChangeStatus updateImpl(Attributor &A) override { 4387 ChangeStatus Changed = ChangeStatus::UNCHANGED; 4388 if (IsAssumedSideEffectFree && !isAssumedSideEffectFree(A, getCtxI())) { 4389 IsAssumedSideEffectFree = false; 4390 Changed = ChangeStatus::CHANGED; 4391 } 4392 if (!areAllUsesAssumedDead(A, getAssociatedValue())) 4393 return indicatePessimisticFixpoint(); 4394 return Changed; 4395 } 4396 4397 /// See AbstractAttribute::trackStatistics() 4398 void trackStatistics() const override { 4399 if (IsAssumedSideEffectFree) 4400 STATS_DECLTRACK_CSRET_ATTR(IsDead) 4401 else 4402 STATS_DECLTRACK_CSRET_ATTR(UnusedResult) 4403 } 4404 4405 /// See AbstractAttribute::getAsStr(). 4406 const std::string getAsStr(Attributor *A) const override { 4407 return isAssumedDead() 4408 ? "assumed-dead" 4409 : (getAssumed() ? "assumed-dead-users" : "assumed-live"); 4410 } 4411 4412 private: 4413 bool IsAssumedSideEffectFree = true; 4414 }; 4415 4416 struct AAIsDeadReturned : public AAIsDeadValueImpl { 4417 AAIsDeadReturned(const IRPosition &IRP, Attributor &A) 4418 : AAIsDeadValueImpl(IRP, A) {} 4419 4420 /// See AbstractAttribute::updateImpl(...). 4421 ChangeStatus updateImpl(Attributor &A) override { 4422 4423 bool UsedAssumedInformation = false; 4424 A.checkForAllInstructions([](Instruction &) { return true; }, *this, 4425 {Instruction::Ret}, UsedAssumedInformation); 4426 4427 auto PredForCallSite = [&](AbstractCallSite ACS) { 4428 if (ACS.isCallbackCall() || !ACS.getInstruction()) 4429 return false; 4430 return areAllUsesAssumedDead(A, *ACS.getInstruction()); 4431 }; 4432 4433 if (!A.checkForAllCallSites(PredForCallSite, *this, true, 4434 UsedAssumedInformation)) 4435 return indicatePessimisticFixpoint(); 4436 4437 return ChangeStatus::UNCHANGED; 4438 } 4439 4440 /// See AbstractAttribute::manifest(...). 4441 ChangeStatus manifest(Attributor &A) override { 4442 // TODO: Rewrite the signature to return void? 4443 bool AnyChange = false; 4444 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType()); 4445 auto RetInstPred = [&](Instruction &I) { 4446 ReturnInst &RI = cast<ReturnInst>(I); 4447 if (!isa<UndefValue>(RI.getReturnValue())) 4448 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV); 4449 return true; 4450 }; 4451 bool UsedAssumedInformation = false; 4452 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret}, 4453 UsedAssumedInformation); 4454 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 4455 } 4456 4457 /// See AbstractAttribute::trackStatistics() 4458 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) } 4459 }; 4460 4461 struct AAIsDeadFunction : public AAIsDead { 4462 AAIsDeadFunction(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {} 4463 4464 /// See AbstractAttribute::initialize(...). 4465 void initialize(Attributor &A) override { 4466 Function *F = getAnchorScope(); 4467 assert(F && "Did expect an anchor function"); 4468 if (!isAssumedDeadInternalFunction(A)) { 4469 ToBeExploredFrom.insert(&F->getEntryBlock().front()); 4470 assumeLive(A, F->getEntryBlock()); 4471 } 4472 } 4473 4474 bool isAssumedDeadInternalFunction(Attributor &A) { 4475 if (!getAnchorScope()->hasLocalLinkage()) 4476 return false; 4477 bool UsedAssumedInformation = false; 4478 return A.checkForAllCallSites([](AbstractCallSite) { return false; }, *this, 4479 true, UsedAssumedInformation); 4480 } 4481 4482 /// See AbstractAttribute::getAsStr(). 4483 const std::string getAsStr(Attributor *A) const override { 4484 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" + 4485 std::to_string(getAnchorScope()->size()) + "][#TBEP " + 4486 std::to_string(ToBeExploredFrom.size()) + "][#KDE " + 4487 std::to_string(KnownDeadEnds.size()) + "]"; 4488 } 4489 4490 /// See AbstractAttribute::manifest(...). 4491 ChangeStatus manifest(Attributor &A) override { 4492 assert(getState().isValidState() && 4493 "Attempted to manifest an invalid state!"); 4494 4495 ChangeStatus HasChanged = ChangeStatus::UNCHANGED; 4496 Function &F = *getAnchorScope(); 4497 4498 if (AssumedLiveBlocks.empty()) { 4499 A.deleteAfterManifest(F); 4500 return ChangeStatus::CHANGED; 4501 } 4502 4503 // Flag to determine if we can change an invoke to a call assuming the 4504 // callee is nounwind. This is not possible if the personality of the 4505 // function allows to catch asynchronous exceptions. 4506 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F); 4507 4508 KnownDeadEnds.set_union(ToBeExploredFrom); 4509 for (const Instruction *DeadEndI : KnownDeadEnds) { 4510 auto *CB = dyn_cast<CallBase>(DeadEndI); 4511 if (!CB) 4512 continue; 4513 bool IsKnownNoReturn; 4514 bool MayReturn = !AA::hasAssumedIRAttr<Attribute::NoReturn>( 4515 A, this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL, 4516 IsKnownNoReturn); 4517 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB))) 4518 continue; 4519 4520 if (auto *II = dyn_cast<InvokeInst>(DeadEndI)) 4521 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II)); 4522 else 4523 A.changeToUnreachableAfterManifest( 4524 const_cast<Instruction *>(DeadEndI->getNextNode())); 4525 HasChanged = ChangeStatus::CHANGED; 4526 } 4527 4528 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted."); 4529 for (BasicBlock &BB : F) 4530 if (!AssumedLiveBlocks.count(&BB)) { 4531 A.deleteAfterManifest(BB); 4532 ++BUILD_STAT_NAME(AAIsDead, BasicBlock); 4533 HasChanged = ChangeStatus::CHANGED; 4534 } 4535 4536 return HasChanged; 4537 } 4538 4539 /// See AbstractAttribute::updateImpl(...). 4540 ChangeStatus updateImpl(Attributor &A) override; 4541 4542 bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const override { 4543 assert(From->getParent() == getAnchorScope() && 4544 To->getParent() == getAnchorScope() && 4545 "Used AAIsDead of the wrong function"); 4546 return isValidState() && !AssumedLiveEdges.count(std::make_pair(From, To)); 4547 } 4548 4549 /// See AbstractAttribute::trackStatistics() 4550 void trackStatistics() const override {} 4551 4552 /// Returns true if the function is assumed dead. 4553 bool isAssumedDead() const override { return false; } 4554 4555 /// See AAIsDead::isKnownDead(). 4556 bool isKnownDead() const override { return false; } 4557 4558 /// See AAIsDead::isAssumedDead(BasicBlock *). 4559 bool isAssumedDead(const BasicBlock *BB) const override { 4560 assert(BB->getParent() == getAnchorScope() && 4561 "BB must be in the same anchor scope function."); 4562 4563 if (!getAssumed()) 4564 return false; 4565 return !AssumedLiveBlocks.count(BB); 4566 } 4567 4568 /// See AAIsDead::isKnownDead(BasicBlock *). 4569 bool isKnownDead(const BasicBlock *BB) const override { 4570 return getKnown() && isAssumedDead(BB); 4571 } 4572 4573 /// See AAIsDead::isAssumed(Instruction *I). 4574 bool isAssumedDead(const Instruction *I) const override { 4575 assert(I->getParent()->getParent() == getAnchorScope() && 4576 "Instruction must be in the same anchor scope function."); 4577 4578 if (!getAssumed()) 4579 return false; 4580 4581 // If it is not in AssumedLiveBlocks then it for sure dead. 4582 // Otherwise, it can still be after noreturn call in a live block. 4583 if (!AssumedLiveBlocks.count(I->getParent())) 4584 return true; 4585 4586 // If it is not after a liveness barrier it is live. 4587 const Instruction *PrevI = I->getPrevNode(); 4588 while (PrevI) { 4589 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI)) 4590 return true; 4591 PrevI = PrevI->getPrevNode(); 4592 } 4593 return false; 4594 } 4595 4596 /// See AAIsDead::isKnownDead(Instruction *I). 4597 bool isKnownDead(const Instruction *I) const override { 4598 return getKnown() && isAssumedDead(I); 4599 } 4600 4601 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A 4602 /// that internal function called from \p BB should now be looked at. 4603 bool assumeLive(Attributor &A, const BasicBlock &BB) { 4604 if (!AssumedLiveBlocks.insert(&BB).second) 4605 return false; 4606 4607 // We assume that all of BB is (probably) live now and if there are calls to 4608 // internal functions we will assume that those are now live as well. This 4609 // is a performance optimization for blocks with calls to a lot of internal 4610 // functions. It can however cause dead functions to be treated as live. 4611 for (const Instruction &I : BB) 4612 if (const auto *CB = dyn_cast<CallBase>(&I)) 4613 if (auto *F = dyn_cast_if_present<Function>(CB->getCalledOperand())) 4614 if (F->hasLocalLinkage()) 4615 A.markLiveInternalFunction(*F); 4616 return true; 4617 } 4618 4619 /// Collection of instructions that need to be explored again, e.g., we 4620 /// did assume they do not transfer control to (one of their) successors. 4621 SmallSetVector<const Instruction *, 8> ToBeExploredFrom; 4622 4623 /// Collection of instructions that are known to not transfer control. 4624 SmallSetVector<const Instruction *, 8> KnownDeadEnds; 4625 4626 /// Collection of all assumed live edges 4627 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> AssumedLiveEdges; 4628 4629 /// Collection of all assumed live BasicBlocks. 4630 DenseSet<const BasicBlock *> AssumedLiveBlocks; 4631 }; 4632 4633 static bool 4634 identifyAliveSuccessors(Attributor &A, const CallBase &CB, 4635 AbstractAttribute &AA, 4636 SmallVectorImpl<const Instruction *> &AliveSuccessors) { 4637 const IRPosition &IPos = IRPosition::callsite_function(CB); 4638 4639 bool IsKnownNoReturn; 4640 if (AA::hasAssumedIRAttr<Attribute::NoReturn>( 4641 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoReturn)) 4642 return !IsKnownNoReturn; 4643 if (CB.isTerminator()) 4644 AliveSuccessors.push_back(&CB.getSuccessor(0)->front()); 4645 else 4646 AliveSuccessors.push_back(CB.getNextNode()); 4647 return false; 4648 } 4649 4650 static bool 4651 identifyAliveSuccessors(Attributor &A, const InvokeInst &II, 4652 AbstractAttribute &AA, 4653 SmallVectorImpl<const Instruction *> &AliveSuccessors) { 4654 bool UsedAssumedInformation = 4655 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors); 4656 4657 // First, determine if we can change an invoke to a call assuming the 4658 // callee is nounwind. This is not possible if the personality of the 4659 // function allows to catch asynchronous exceptions. 4660 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) { 4661 AliveSuccessors.push_back(&II.getUnwindDest()->front()); 4662 } else { 4663 const IRPosition &IPos = IRPosition::callsite_function(II); 4664 4665 bool IsKnownNoUnwind; 4666 if (AA::hasAssumedIRAttr<Attribute::NoUnwind>( 4667 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) { 4668 UsedAssumedInformation |= !IsKnownNoUnwind; 4669 } else { 4670 AliveSuccessors.push_back(&II.getUnwindDest()->front()); 4671 } 4672 } 4673 return UsedAssumedInformation; 4674 } 4675 4676 static bool 4677 identifyAliveSuccessors(Attributor &A, const BranchInst &BI, 4678 AbstractAttribute &AA, 4679 SmallVectorImpl<const Instruction *> &AliveSuccessors) { 4680 bool UsedAssumedInformation = false; 4681 if (BI.getNumSuccessors() == 1) { 4682 AliveSuccessors.push_back(&BI.getSuccessor(0)->front()); 4683 } else { 4684 std::optional<Constant *> C = 4685 A.getAssumedConstant(*BI.getCondition(), AA, UsedAssumedInformation); 4686 if (!C || isa_and_nonnull<UndefValue>(*C)) { 4687 // No value yet, assume both edges are dead. 4688 } else if (isa_and_nonnull<ConstantInt>(*C)) { 4689 const BasicBlock *SuccBB = 4690 BI.getSuccessor(1 - cast<ConstantInt>(*C)->getValue().getZExtValue()); 4691 AliveSuccessors.push_back(&SuccBB->front()); 4692 } else { 4693 AliveSuccessors.push_back(&BI.getSuccessor(0)->front()); 4694 AliveSuccessors.push_back(&BI.getSuccessor(1)->front()); 4695 UsedAssumedInformation = false; 4696 } 4697 } 4698 return UsedAssumedInformation; 4699 } 4700 4701 static bool 4702 identifyAliveSuccessors(Attributor &A, const SwitchInst &SI, 4703 AbstractAttribute &AA, 4704 SmallVectorImpl<const Instruction *> &AliveSuccessors) { 4705 bool UsedAssumedInformation = false; 4706 SmallVector<AA::ValueAndContext> Values; 4707 if (!A.getAssumedSimplifiedValues(IRPosition::value(*SI.getCondition()), &AA, 4708 Values, AA::AnyScope, 4709 UsedAssumedInformation)) { 4710 // Something went wrong, assume all successors are live. 4711 for (const BasicBlock *SuccBB : successors(SI.getParent())) 4712 AliveSuccessors.push_back(&SuccBB->front()); 4713 return false; 4714 } 4715 4716 if (Values.empty() || 4717 (Values.size() == 1 && 4718 isa_and_nonnull<UndefValue>(Values.front().getValue()))) { 4719 // No valid value yet, assume all edges are dead. 4720 return UsedAssumedInformation; 4721 } 4722 4723 Type &Ty = *SI.getCondition()->getType(); 4724 SmallPtrSet<ConstantInt *, 8> Constants; 4725 auto CheckForConstantInt = [&](Value *V) { 4726 if (auto *CI = dyn_cast_if_present<ConstantInt>(AA::getWithType(*V, Ty))) { 4727 Constants.insert(CI); 4728 return true; 4729 } 4730 return false; 4731 }; 4732 4733 if (!all_of(Values, [&](AA::ValueAndContext &VAC) { 4734 return CheckForConstantInt(VAC.getValue()); 4735 })) { 4736 for (const BasicBlock *SuccBB : successors(SI.getParent())) 4737 AliveSuccessors.push_back(&SuccBB->front()); 4738 return UsedAssumedInformation; 4739 } 4740 4741 unsigned MatchedCases = 0; 4742 for (const auto &CaseIt : SI.cases()) { 4743 if (Constants.count(CaseIt.getCaseValue())) { 4744 ++MatchedCases; 4745 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front()); 4746 } 4747 } 4748 4749 // If all potential values have been matched, we will not visit the default 4750 // case. 4751 if (MatchedCases < Constants.size()) 4752 AliveSuccessors.push_back(&SI.getDefaultDest()->front()); 4753 return UsedAssumedInformation; 4754 } 4755 4756 ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) { 4757 ChangeStatus Change = ChangeStatus::UNCHANGED; 4758 4759 if (AssumedLiveBlocks.empty()) { 4760 if (isAssumedDeadInternalFunction(A)) 4761 return ChangeStatus::UNCHANGED; 4762 4763 Function *F = getAnchorScope(); 4764 ToBeExploredFrom.insert(&F->getEntryBlock().front()); 4765 assumeLive(A, F->getEntryBlock()); 4766 Change = ChangeStatus::CHANGED; 4767 } 4768 4769 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/" 4770 << getAnchorScope()->size() << "] BBs and " 4771 << ToBeExploredFrom.size() << " exploration points and " 4772 << KnownDeadEnds.size() << " known dead ends\n"); 4773 4774 // Copy and clear the list of instructions we need to explore from. It is 4775 // refilled with instructions the next update has to look at. 4776 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(), 4777 ToBeExploredFrom.end()); 4778 decltype(ToBeExploredFrom) NewToBeExploredFrom; 4779 4780 SmallVector<const Instruction *, 8> AliveSuccessors; 4781 while (!Worklist.empty()) { 4782 const Instruction *I = Worklist.pop_back_val(); 4783 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n"); 4784 4785 // Fast forward for uninteresting instructions. We could look for UB here 4786 // though. 4787 while (!I->isTerminator() && !isa<CallBase>(I)) 4788 I = I->getNextNode(); 4789 4790 AliveSuccessors.clear(); 4791 4792 bool UsedAssumedInformation = false; 4793 switch (I->getOpcode()) { 4794 // TODO: look for (assumed) UB to backwards propagate "deadness". 4795 default: 4796 assert(I->isTerminator() && 4797 "Expected non-terminators to be handled already!"); 4798 for (const BasicBlock *SuccBB : successors(I->getParent())) 4799 AliveSuccessors.push_back(&SuccBB->front()); 4800 break; 4801 case Instruction::Call: 4802 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I), 4803 *this, AliveSuccessors); 4804 break; 4805 case Instruction::Invoke: 4806 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I), 4807 *this, AliveSuccessors); 4808 break; 4809 case Instruction::Br: 4810 UsedAssumedInformation = identifyAliveSuccessors(A, cast<BranchInst>(*I), 4811 *this, AliveSuccessors); 4812 break; 4813 case Instruction::Switch: 4814 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I), 4815 *this, AliveSuccessors); 4816 break; 4817 } 4818 4819 if (UsedAssumedInformation) { 4820 NewToBeExploredFrom.insert(I); 4821 } else if (AliveSuccessors.empty() || 4822 (I->isTerminator() && 4823 AliveSuccessors.size() < I->getNumSuccessors())) { 4824 if (KnownDeadEnds.insert(I)) 4825 Change = ChangeStatus::CHANGED; 4826 } 4827 4828 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: " 4829 << AliveSuccessors.size() << " UsedAssumedInformation: " 4830 << UsedAssumedInformation << "\n"); 4831 4832 for (const Instruction *AliveSuccessor : AliveSuccessors) { 4833 if (!I->isTerminator()) { 4834 assert(AliveSuccessors.size() == 1 && 4835 "Non-terminator expected to have a single successor!"); 4836 Worklist.push_back(AliveSuccessor); 4837 } else { 4838 // record the assumed live edge 4839 auto Edge = std::make_pair(I->getParent(), AliveSuccessor->getParent()); 4840 if (AssumedLiveEdges.insert(Edge).second) 4841 Change = ChangeStatus::CHANGED; 4842 if (assumeLive(A, *AliveSuccessor->getParent())) 4843 Worklist.push_back(AliveSuccessor); 4844 } 4845 } 4846 } 4847 4848 // Check if the content of ToBeExploredFrom changed, ignore the order. 4849 if (NewToBeExploredFrom.size() != ToBeExploredFrom.size() || 4850 llvm::any_of(NewToBeExploredFrom, [&](const Instruction *I) { 4851 return !ToBeExploredFrom.count(I); 4852 })) { 4853 Change = ChangeStatus::CHANGED; 4854 ToBeExploredFrom = std::move(NewToBeExploredFrom); 4855 } 4856 4857 // If we know everything is live there is no need to query for liveness. 4858 // Instead, indicating a pessimistic fixpoint will cause the state to be 4859 // "invalid" and all queries to be answered conservatively without lookups. 4860 // To be in this state we have to (1) finished the exploration and (3) not 4861 // discovered any non-trivial dead end and (2) not ruled unreachable code 4862 // dead. 4863 if (ToBeExploredFrom.empty() && 4864 getAnchorScope()->size() == AssumedLiveBlocks.size() && 4865 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) { 4866 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0; 4867 })) 4868 return indicatePessimisticFixpoint(); 4869 return Change; 4870 } 4871 4872 /// Liveness information for a call sites. 4873 struct AAIsDeadCallSite final : AAIsDeadFunction { 4874 AAIsDeadCallSite(const IRPosition &IRP, Attributor &A) 4875 : AAIsDeadFunction(IRP, A) {} 4876 4877 /// See AbstractAttribute::initialize(...). 4878 void initialize(Attributor &A) override { 4879 // TODO: Once we have call site specific value information we can provide 4880 // call site specific liveness information and then it makes 4881 // sense to specialize attributes for call sites instead of 4882 // redirecting requests to the callee. 4883 llvm_unreachable("Abstract attributes for liveness are not " 4884 "supported for call sites yet!"); 4885 } 4886 4887 /// See AbstractAttribute::updateImpl(...). 4888 ChangeStatus updateImpl(Attributor &A) override { 4889 return indicatePessimisticFixpoint(); 4890 } 4891 4892 /// See AbstractAttribute::trackStatistics() 4893 void trackStatistics() const override {} 4894 }; 4895 } // namespace 4896 4897 /// -------------------- Dereferenceable Argument Attribute -------------------- 4898 4899 namespace { 4900 struct AADereferenceableImpl : AADereferenceable { 4901 AADereferenceableImpl(const IRPosition &IRP, Attributor &A) 4902 : AADereferenceable(IRP, A) {} 4903 using StateType = DerefState; 4904 4905 /// See AbstractAttribute::initialize(...). 4906 void initialize(Attributor &A) override { 4907 Value &V = *getAssociatedValue().stripPointerCasts(); 4908 SmallVector<Attribute, 4> Attrs; 4909 A.getAttrs(getIRPosition(), 4910 {Attribute::Dereferenceable, Attribute::DereferenceableOrNull}, 4911 Attrs, /* IgnoreSubsumingPositions */ false); 4912 for (const Attribute &Attr : Attrs) 4913 takeKnownDerefBytesMaximum(Attr.getValueAsInt()); 4914 4915 // Ensure we initialize the non-null AA (if necessary). 4916 bool IsKnownNonNull; 4917 AA::hasAssumedIRAttr<Attribute::NonNull>( 4918 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNonNull); 4919 4920 bool CanBeNull, CanBeFreed; 4921 takeKnownDerefBytesMaximum(V.getPointerDereferenceableBytes( 4922 A.getDataLayout(), CanBeNull, CanBeFreed)); 4923 4924 if (Instruction *CtxI = getCtxI()) 4925 followUsesInMBEC(*this, A, getState(), *CtxI); 4926 } 4927 4928 /// See AbstractAttribute::getState() 4929 /// { 4930 StateType &getState() override { return *this; } 4931 const StateType &getState() const override { return *this; } 4932 /// } 4933 4934 /// Helper function for collecting accessed bytes in must-be-executed-context 4935 void addAccessedBytesForUse(Attributor &A, const Use *U, const Instruction *I, 4936 DerefState &State) { 4937 const Value *UseV = U->get(); 4938 if (!UseV->getType()->isPointerTy()) 4939 return; 4940 4941 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I); 4942 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile()) 4943 return; 4944 4945 int64_t Offset; 4946 const Value *Base = GetPointerBaseWithConstantOffset( 4947 Loc->Ptr, Offset, A.getDataLayout(), /*AllowNonInbounds*/ true); 4948 if (Base && Base == &getAssociatedValue()) 4949 State.addAccessedBytes(Offset, Loc->Size.getValue()); 4950 } 4951 4952 /// See followUsesInMBEC 4953 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I, 4954 AADereferenceable::StateType &State) { 4955 bool IsNonNull = false; 4956 bool TrackUse = false; 4957 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse( 4958 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse); 4959 LLVM_DEBUG(dbgs() << "[AADereferenceable] Deref bytes: " << DerefBytes 4960 << " for instruction " << *I << "\n"); 4961 4962 addAccessedBytesForUse(A, U, I, State); 4963 State.takeKnownDerefBytesMaximum(DerefBytes); 4964 return TrackUse; 4965 } 4966 4967 /// See AbstractAttribute::manifest(...). 4968 ChangeStatus manifest(Attributor &A) override { 4969 ChangeStatus Change = AADereferenceable::manifest(A); 4970 bool IsKnownNonNull; 4971 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>( 4972 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull); 4973 if (IsAssumedNonNull && 4974 A.hasAttr(getIRPosition(), Attribute::DereferenceableOrNull)) { 4975 A.removeAttrs(getIRPosition(), {Attribute::DereferenceableOrNull}); 4976 return ChangeStatus::CHANGED; 4977 } 4978 return Change; 4979 } 4980 4981 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, 4982 SmallVectorImpl<Attribute> &Attrs) const override { 4983 // TODO: Add *_globally support 4984 bool IsKnownNonNull; 4985 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>( 4986 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull); 4987 if (IsAssumedNonNull) 4988 Attrs.emplace_back(Attribute::getWithDereferenceableBytes( 4989 Ctx, getAssumedDereferenceableBytes())); 4990 else 4991 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes( 4992 Ctx, getAssumedDereferenceableBytes())); 4993 } 4994 4995 /// See AbstractAttribute::getAsStr(). 4996 const std::string getAsStr(Attributor *A) const override { 4997 if (!getAssumedDereferenceableBytes()) 4998 return "unknown-dereferenceable"; 4999 bool IsKnownNonNull; 5000 bool IsAssumedNonNull = false; 5001 if (A) 5002 IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>( 5003 *A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull); 5004 return std::string("dereferenceable") + 5005 (IsAssumedNonNull ? "" : "_or_null") + 5006 (isAssumedGlobal() ? "_globally" : "") + "<" + 5007 std::to_string(getKnownDereferenceableBytes()) + "-" + 5008 std::to_string(getAssumedDereferenceableBytes()) + ">" + 5009 (!A ? " [non-null is unknown]" : ""); 5010 } 5011 }; 5012 5013 /// Dereferenceable attribute for a floating value. 5014 struct AADereferenceableFloating : AADereferenceableImpl { 5015 AADereferenceableFloating(const IRPosition &IRP, Attributor &A) 5016 : AADereferenceableImpl(IRP, A) {} 5017 5018 /// See AbstractAttribute::updateImpl(...). 5019 ChangeStatus updateImpl(Attributor &A) override { 5020 bool Stripped; 5021 bool UsedAssumedInformation = false; 5022 SmallVector<AA::ValueAndContext> Values; 5023 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values, 5024 AA::AnyScope, UsedAssumedInformation)) { 5025 Values.push_back({getAssociatedValue(), getCtxI()}); 5026 Stripped = false; 5027 } else { 5028 Stripped = Values.size() != 1 || 5029 Values.front().getValue() != &getAssociatedValue(); 5030 } 5031 5032 const DataLayout &DL = A.getDataLayout(); 5033 DerefState T; 5034 5035 auto VisitValueCB = [&](const Value &V) -> bool { 5036 unsigned IdxWidth = 5037 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace()); 5038 APInt Offset(IdxWidth, 0); 5039 const Value *Base = stripAndAccumulateOffsets( 5040 A, *this, &V, DL, Offset, /* GetMinOffset */ false, 5041 /* AllowNonInbounds */ true); 5042 5043 const auto *AA = A.getAAFor<AADereferenceable>( 5044 *this, IRPosition::value(*Base), DepClassTy::REQUIRED); 5045 int64_t DerefBytes = 0; 5046 if (!AA || (!Stripped && this == AA)) { 5047 // Use IR information if we did not strip anything. 5048 // TODO: track globally. 5049 bool CanBeNull, CanBeFreed; 5050 DerefBytes = 5051 Base->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed); 5052 T.GlobalState.indicatePessimisticFixpoint(); 5053 } else { 5054 const DerefState &DS = AA->getState(); 5055 DerefBytes = DS.DerefBytesState.getAssumed(); 5056 T.GlobalState &= DS.GlobalState; 5057 } 5058 5059 // For now we do not try to "increase" dereferenceability due to negative 5060 // indices as we first have to come up with code to deal with loops and 5061 // for overflows of the dereferenceable bytes. 5062 int64_t OffsetSExt = Offset.getSExtValue(); 5063 if (OffsetSExt < 0) 5064 OffsetSExt = 0; 5065 5066 T.takeAssumedDerefBytesMinimum( 5067 std::max(int64_t(0), DerefBytes - OffsetSExt)); 5068 5069 if (this == AA) { 5070 if (!Stripped) { 5071 // If nothing was stripped IR information is all we got. 5072 T.takeKnownDerefBytesMaximum( 5073 std::max(int64_t(0), DerefBytes - OffsetSExt)); 5074 T.indicatePessimisticFixpoint(); 5075 } else if (OffsetSExt > 0) { 5076 // If something was stripped but there is circular reasoning we look 5077 // for the offset. If it is positive we basically decrease the 5078 // dereferenceable bytes in a circular loop now, which will simply 5079 // drive them down to the known value in a very slow way which we 5080 // can accelerate. 5081 T.indicatePessimisticFixpoint(); 5082 } 5083 } 5084 5085 return T.isValidState(); 5086 }; 5087 5088 for (const auto &VAC : Values) 5089 if (!VisitValueCB(*VAC.getValue())) 5090 return indicatePessimisticFixpoint(); 5091 5092 return clampStateAndIndicateChange(getState(), T); 5093 } 5094 5095 /// See AbstractAttribute::trackStatistics() 5096 void trackStatistics() const override { 5097 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable) 5098 } 5099 }; 5100 5101 /// Dereferenceable attribute for a return value. 5102 struct AADereferenceableReturned final 5103 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> { 5104 using Base = 5105 AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>; 5106 AADereferenceableReturned(const IRPosition &IRP, Attributor &A) 5107 : Base(IRP, A) {} 5108 5109 /// See AbstractAttribute::trackStatistics() 5110 void trackStatistics() const override { 5111 STATS_DECLTRACK_FNRET_ATTR(dereferenceable) 5112 } 5113 }; 5114 5115 /// Dereferenceable attribute for an argument 5116 struct AADereferenceableArgument final 5117 : AAArgumentFromCallSiteArguments<AADereferenceable, 5118 AADereferenceableImpl> { 5119 using Base = 5120 AAArgumentFromCallSiteArguments<AADereferenceable, AADereferenceableImpl>; 5121 AADereferenceableArgument(const IRPosition &IRP, Attributor &A) 5122 : Base(IRP, A) {} 5123 5124 /// See AbstractAttribute::trackStatistics() 5125 void trackStatistics() const override { 5126 STATS_DECLTRACK_ARG_ATTR(dereferenceable) 5127 } 5128 }; 5129 5130 /// Dereferenceable attribute for a call site argument. 5131 struct AADereferenceableCallSiteArgument final : AADereferenceableFloating { 5132 AADereferenceableCallSiteArgument(const IRPosition &IRP, Attributor &A) 5133 : AADereferenceableFloating(IRP, A) {} 5134 5135 /// See AbstractAttribute::trackStatistics() 5136 void trackStatistics() const override { 5137 STATS_DECLTRACK_CSARG_ATTR(dereferenceable) 5138 } 5139 }; 5140 5141 /// Dereferenceable attribute deduction for a call site return value. 5142 struct AADereferenceableCallSiteReturned final 5143 : AACalleeToCallSite<AADereferenceable, AADereferenceableImpl> { 5144 using Base = AACalleeToCallSite<AADereferenceable, AADereferenceableImpl>; 5145 AADereferenceableCallSiteReturned(const IRPosition &IRP, Attributor &A) 5146 : Base(IRP, A) {} 5147 5148 /// See AbstractAttribute::trackStatistics() 5149 void trackStatistics() const override { 5150 STATS_DECLTRACK_CS_ATTR(dereferenceable); 5151 } 5152 }; 5153 } // namespace 5154 5155 // ------------------------ Align Argument Attribute ------------------------ 5156 5157 namespace { 5158 static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA, 5159 Value &AssociatedValue, const Use *U, 5160 const Instruction *I, bool &TrackUse) { 5161 // We need to follow common pointer manipulation uses to the accesses they 5162 // feed into. 5163 if (isa<CastInst>(I)) { 5164 // Follow all but ptr2int casts. 5165 TrackUse = !isa<PtrToIntInst>(I); 5166 return 0; 5167 } 5168 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) { 5169 if (GEP->hasAllConstantIndices()) 5170 TrackUse = true; 5171 return 0; 5172 } 5173 5174 MaybeAlign MA; 5175 if (const auto *CB = dyn_cast<CallBase>(I)) { 5176 if (CB->isBundleOperand(U) || CB->isCallee(U)) 5177 return 0; 5178 5179 unsigned ArgNo = CB->getArgOperandNo(U); 5180 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo); 5181 // As long as we only use known information there is no need to track 5182 // dependences here. 5183 auto *AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP, DepClassTy::NONE); 5184 if (AlignAA) 5185 MA = MaybeAlign(AlignAA->getKnownAlign()); 5186 } 5187 5188 const DataLayout &DL = A.getDataLayout(); 5189 const Value *UseV = U->get(); 5190 if (auto *SI = dyn_cast<StoreInst>(I)) { 5191 if (SI->getPointerOperand() == UseV) 5192 MA = SI->getAlign(); 5193 } else if (auto *LI = dyn_cast<LoadInst>(I)) { 5194 if (LI->getPointerOperand() == UseV) 5195 MA = LI->getAlign(); 5196 } else if (auto *AI = dyn_cast<AtomicRMWInst>(I)) { 5197 if (AI->getPointerOperand() == UseV) 5198 MA = AI->getAlign(); 5199 } else if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) { 5200 if (AI->getPointerOperand() == UseV) 5201 MA = AI->getAlign(); 5202 } 5203 5204 if (!MA || *MA <= QueryingAA.getKnownAlign()) 5205 return 0; 5206 5207 unsigned Alignment = MA->value(); 5208 int64_t Offset; 5209 5210 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) { 5211 if (Base == &AssociatedValue) { 5212 // BasePointerAddr + Offset = Alignment * Q for some integer Q. 5213 // So we can say that the maximum power of two which is a divisor of 5214 // gcd(Offset, Alignment) is an alignment. 5215 5216 uint32_t gcd = std::gcd(uint32_t(abs((int32_t)Offset)), Alignment); 5217 Alignment = llvm::bit_floor(gcd); 5218 } 5219 } 5220 5221 return Alignment; 5222 } 5223 5224 struct AAAlignImpl : AAAlign { 5225 AAAlignImpl(const IRPosition &IRP, Attributor &A) : AAAlign(IRP, A) {} 5226 5227 /// See AbstractAttribute::initialize(...). 5228 void initialize(Attributor &A) override { 5229 SmallVector<Attribute, 4> Attrs; 5230 A.getAttrs(getIRPosition(), {Attribute::Alignment}, Attrs); 5231 for (const Attribute &Attr : Attrs) 5232 takeKnownMaximum(Attr.getValueAsInt()); 5233 5234 Value &V = *getAssociatedValue().stripPointerCasts(); 5235 takeKnownMaximum(V.getPointerAlignment(A.getDataLayout()).value()); 5236 5237 if (Instruction *CtxI = getCtxI()) 5238 followUsesInMBEC(*this, A, getState(), *CtxI); 5239 } 5240 5241 /// See AbstractAttribute::manifest(...). 5242 ChangeStatus manifest(Attributor &A) override { 5243 ChangeStatus LoadStoreChanged = ChangeStatus::UNCHANGED; 5244 5245 // Check for users that allow alignment annotations. 5246 Value &AssociatedValue = getAssociatedValue(); 5247 for (const Use &U : AssociatedValue.uses()) { 5248 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) { 5249 if (SI->getPointerOperand() == &AssociatedValue) 5250 if (SI->getAlign() < getAssumedAlign()) { 5251 STATS_DECLTRACK(AAAlign, Store, 5252 "Number of times alignment added to a store"); 5253 SI->setAlignment(getAssumedAlign()); 5254 LoadStoreChanged = ChangeStatus::CHANGED; 5255 } 5256 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) { 5257 if (LI->getPointerOperand() == &AssociatedValue) 5258 if (LI->getAlign() < getAssumedAlign()) { 5259 LI->setAlignment(getAssumedAlign()); 5260 STATS_DECLTRACK(AAAlign, Load, 5261 "Number of times alignment added to a load"); 5262 LoadStoreChanged = ChangeStatus::CHANGED; 5263 } 5264 } 5265 } 5266 5267 ChangeStatus Changed = AAAlign::manifest(A); 5268 5269 Align InheritAlign = 5270 getAssociatedValue().getPointerAlignment(A.getDataLayout()); 5271 if (InheritAlign >= getAssumedAlign()) 5272 return LoadStoreChanged; 5273 return Changed | LoadStoreChanged; 5274 } 5275 5276 // TODO: Provide a helper to determine the implied ABI alignment and check in 5277 // the existing manifest method and a new one for AAAlignImpl that value 5278 // to avoid making the alignment explicit if it did not improve. 5279 5280 /// See AbstractAttribute::getDeducedAttributes 5281 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, 5282 SmallVectorImpl<Attribute> &Attrs) const override { 5283 if (getAssumedAlign() > 1) 5284 Attrs.emplace_back( 5285 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign()))); 5286 } 5287 5288 /// See followUsesInMBEC 5289 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I, 5290 AAAlign::StateType &State) { 5291 bool TrackUse = false; 5292 5293 unsigned int KnownAlign = 5294 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse); 5295 State.takeKnownMaximum(KnownAlign); 5296 5297 return TrackUse; 5298 } 5299 5300 /// See AbstractAttribute::getAsStr(). 5301 const std::string getAsStr(Attributor *A) const override { 5302 return "align<" + std::to_string(getKnownAlign().value()) + "-" + 5303 std::to_string(getAssumedAlign().value()) + ">"; 5304 } 5305 }; 5306 5307 /// Align attribute for a floating value. 5308 struct AAAlignFloating : AAAlignImpl { 5309 AAAlignFloating(const IRPosition &IRP, Attributor &A) : AAAlignImpl(IRP, A) {} 5310 5311 /// See AbstractAttribute::updateImpl(...). 5312 ChangeStatus updateImpl(Attributor &A) override { 5313 const DataLayout &DL = A.getDataLayout(); 5314 5315 bool Stripped; 5316 bool UsedAssumedInformation = false; 5317 SmallVector<AA::ValueAndContext> Values; 5318 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values, 5319 AA::AnyScope, UsedAssumedInformation)) { 5320 Values.push_back({getAssociatedValue(), getCtxI()}); 5321 Stripped = false; 5322 } else { 5323 Stripped = Values.size() != 1 || 5324 Values.front().getValue() != &getAssociatedValue(); 5325 } 5326 5327 StateType T; 5328 auto VisitValueCB = [&](Value &V) -> bool { 5329 if (isa<UndefValue>(V) || isa<ConstantPointerNull>(V)) 5330 return true; 5331 const auto *AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V), 5332 DepClassTy::REQUIRED); 5333 if (!AA || (!Stripped && this == AA)) { 5334 int64_t Offset; 5335 unsigned Alignment = 1; 5336 if (const Value *Base = 5337 GetPointerBaseWithConstantOffset(&V, Offset, DL)) { 5338 // TODO: Use AAAlign for the base too. 5339 Align PA = Base->getPointerAlignment(DL); 5340 // BasePointerAddr + Offset = Alignment * Q for some integer Q. 5341 // So we can say that the maximum power of two which is a divisor of 5342 // gcd(Offset, Alignment) is an alignment. 5343 5344 uint32_t gcd = 5345 std::gcd(uint32_t(abs((int32_t)Offset)), uint32_t(PA.value())); 5346 Alignment = llvm::bit_floor(gcd); 5347 } else { 5348 Alignment = V.getPointerAlignment(DL).value(); 5349 } 5350 // Use only IR information if we did not strip anything. 5351 T.takeKnownMaximum(Alignment); 5352 T.indicatePessimisticFixpoint(); 5353 } else { 5354 // Use abstract attribute information. 5355 const AAAlign::StateType &DS = AA->getState(); 5356 T ^= DS; 5357 } 5358 return T.isValidState(); 5359 }; 5360 5361 for (const auto &VAC : Values) { 5362 if (!VisitValueCB(*VAC.getValue())) 5363 return indicatePessimisticFixpoint(); 5364 } 5365 5366 // TODO: If we know we visited all incoming values, thus no are assumed 5367 // dead, we can take the known information from the state T. 5368 return clampStateAndIndicateChange(getState(), T); 5369 } 5370 5371 /// See AbstractAttribute::trackStatistics() 5372 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) } 5373 }; 5374 5375 /// Align attribute for function return value. 5376 struct AAAlignReturned final 5377 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> { 5378 using Base = AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>; 5379 AAAlignReturned(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {} 5380 5381 /// See AbstractAttribute::trackStatistics() 5382 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) } 5383 }; 5384 5385 /// Align attribute for function argument. 5386 struct AAAlignArgument final 5387 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> { 5388 using Base = AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>; 5389 AAAlignArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {} 5390 5391 /// See AbstractAttribute::manifest(...). 5392 ChangeStatus manifest(Attributor &A) override { 5393 // If the associated argument is involved in a must-tail call we give up 5394 // because we would need to keep the argument alignments of caller and 5395 // callee in-sync. Just does not seem worth the trouble right now. 5396 if (A.getInfoCache().isInvolvedInMustTailCall(*getAssociatedArgument())) 5397 return ChangeStatus::UNCHANGED; 5398 return Base::manifest(A); 5399 } 5400 5401 /// See AbstractAttribute::trackStatistics() 5402 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) } 5403 }; 5404 5405 struct AAAlignCallSiteArgument final : AAAlignFloating { 5406 AAAlignCallSiteArgument(const IRPosition &IRP, Attributor &A) 5407 : AAAlignFloating(IRP, A) {} 5408 5409 /// See AbstractAttribute::manifest(...). 5410 ChangeStatus manifest(Attributor &A) override { 5411 // If the associated argument is involved in a must-tail call we give up 5412 // because we would need to keep the argument alignments of caller and 5413 // callee in-sync. Just does not seem worth the trouble right now. 5414 if (Argument *Arg = getAssociatedArgument()) 5415 if (A.getInfoCache().isInvolvedInMustTailCall(*Arg)) 5416 return ChangeStatus::UNCHANGED; 5417 ChangeStatus Changed = AAAlignImpl::manifest(A); 5418 Align InheritAlign = 5419 getAssociatedValue().getPointerAlignment(A.getDataLayout()); 5420 if (InheritAlign >= getAssumedAlign()) 5421 Changed = ChangeStatus::UNCHANGED; 5422 return Changed; 5423 } 5424 5425 /// See AbstractAttribute::updateImpl(Attributor &A). 5426 ChangeStatus updateImpl(Attributor &A) override { 5427 ChangeStatus Changed = AAAlignFloating::updateImpl(A); 5428 if (Argument *Arg = getAssociatedArgument()) { 5429 // We only take known information from the argument 5430 // so we do not need to track a dependence. 5431 const auto *ArgAlignAA = A.getAAFor<AAAlign>( 5432 *this, IRPosition::argument(*Arg), DepClassTy::NONE); 5433 if (ArgAlignAA) 5434 takeKnownMaximum(ArgAlignAA->getKnownAlign().value()); 5435 } 5436 return Changed; 5437 } 5438 5439 /// See AbstractAttribute::trackStatistics() 5440 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) } 5441 }; 5442 5443 /// Align attribute deduction for a call site return value. 5444 struct AAAlignCallSiteReturned final 5445 : AACalleeToCallSite<AAAlign, AAAlignImpl> { 5446 using Base = AACalleeToCallSite<AAAlign, AAAlignImpl>; 5447 AAAlignCallSiteReturned(const IRPosition &IRP, Attributor &A) 5448 : Base(IRP, A) {} 5449 5450 /// See AbstractAttribute::trackStatistics() 5451 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); } 5452 }; 5453 } // namespace 5454 5455 /// ------------------ Function No-Return Attribute ---------------------------- 5456 namespace { 5457 struct AANoReturnImpl : public AANoReturn { 5458 AANoReturnImpl(const IRPosition &IRP, Attributor &A) : AANoReturn(IRP, A) {} 5459 5460 /// See AbstractAttribute::initialize(...). 5461 void initialize(Attributor &A) override { 5462 bool IsKnown; 5463 assert(!AA::hasAssumedIRAttr<Attribute::NoReturn>( 5464 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown)); 5465 (void)IsKnown; 5466 } 5467 5468 /// See AbstractAttribute::getAsStr(). 5469 const std::string getAsStr(Attributor *A) const override { 5470 return getAssumed() ? "noreturn" : "may-return"; 5471 } 5472 5473 /// See AbstractAttribute::updateImpl(Attributor &A). 5474 ChangeStatus updateImpl(Attributor &A) override { 5475 auto CheckForNoReturn = [](Instruction &) { return false; }; 5476 bool UsedAssumedInformation = false; 5477 if (!A.checkForAllInstructions(CheckForNoReturn, *this, 5478 {(unsigned)Instruction::Ret}, 5479 UsedAssumedInformation)) 5480 return indicatePessimisticFixpoint(); 5481 return ChangeStatus::UNCHANGED; 5482 } 5483 }; 5484 5485 struct AANoReturnFunction final : AANoReturnImpl { 5486 AANoReturnFunction(const IRPosition &IRP, Attributor &A) 5487 : AANoReturnImpl(IRP, A) {} 5488 5489 /// See AbstractAttribute::trackStatistics() 5490 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) } 5491 }; 5492 5493 /// NoReturn attribute deduction for a call sites. 5494 struct AANoReturnCallSite final 5495 : AACalleeToCallSite<AANoReturn, AANoReturnImpl> { 5496 AANoReturnCallSite(const IRPosition &IRP, Attributor &A) 5497 : AACalleeToCallSite<AANoReturn, AANoReturnImpl>(IRP, A) {} 5498 5499 /// See AbstractAttribute::trackStatistics() 5500 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); } 5501 }; 5502 } // namespace 5503 5504 /// ----------------------- Instance Info --------------------------------- 5505 5506 namespace { 5507 /// A class to hold the state of for no-capture attributes. 5508 struct AAInstanceInfoImpl : public AAInstanceInfo { 5509 AAInstanceInfoImpl(const IRPosition &IRP, Attributor &A) 5510 : AAInstanceInfo(IRP, A) {} 5511 5512 /// See AbstractAttribute::initialize(...). 5513 void initialize(Attributor &A) override { 5514 Value &V = getAssociatedValue(); 5515 if (auto *C = dyn_cast<Constant>(&V)) { 5516 if (C->isThreadDependent()) 5517 indicatePessimisticFixpoint(); 5518 else 5519 indicateOptimisticFixpoint(); 5520 return; 5521 } 5522 if (auto *CB = dyn_cast<CallBase>(&V)) 5523 if (CB->arg_size() == 0 && !CB->mayHaveSideEffects() && 5524 !CB->mayReadFromMemory()) { 5525 indicateOptimisticFixpoint(); 5526 return; 5527 } 5528 if (auto *I = dyn_cast<Instruction>(&V)) { 5529 const auto *CI = 5530 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>( 5531 *I->getFunction()); 5532 if (mayBeInCycle(CI, I, /* HeaderOnly */ false)) { 5533 indicatePessimisticFixpoint(); 5534 return; 5535 } 5536 } 5537 } 5538 5539 /// See AbstractAttribute::updateImpl(...). 5540 ChangeStatus updateImpl(Attributor &A) override { 5541 ChangeStatus Changed = ChangeStatus::UNCHANGED; 5542 5543 Value &V = getAssociatedValue(); 5544 const Function *Scope = nullptr; 5545 if (auto *I = dyn_cast<Instruction>(&V)) 5546 Scope = I->getFunction(); 5547 if (auto *A = dyn_cast<Argument>(&V)) { 5548 Scope = A->getParent(); 5549 if (!Scope->hasLocalLinkage()) 5550 return Changed; 5551 } 5552 if (!Scope) 5553 return indicateOptimisticFixpoint(); 5554 5555 bool IsKnownNoRecurse; 5556 if (AA::hasAssumedIRAttr<Attribute::NoRecurse>( 5557 A, this, IRPosition::function(*Scope), DepClassTy::OPTIONAL, 5558 IsKnownNoRecurse)) 5559 return Changed; 5560 5561 auto UsePred = [&](const Use &U, bool &Follow) { 5562 const Instruction *UserI = dyn_cast<Instruction>(U.getUser()); 5563 if (!UserI || isa<GetElementPtrInst>(UserI) || isa<CastInst>(UserI) || 5564 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) { 5565 Follow = true; 5566 return true; 5567 } 5568 if (isa<LoadInst>(UserI) || isa<CmpInst>(UserI) || 5569 (isa<StoreInst>(UserI) && 5570 cast<StoreInst>(UserI)->getValueOperand() != U.get())) 5571 return true; 5572 if (auto *CB = dyn_cast<CallBase>(UserI)) { 5573 // This check is not guaranteeing uniqueness but for now that we cannot 5574 // end up with two versions of \p U thinking it was one. 5575 auto *Callee = dyn_cast_if_present<Function>(CB->getCalledOperand()); 5576 if (!Callee || !Callee->hasLocalLinkage()) 5577 return true; 5578 if (!CB->isArgOperand(&U)) 5579 return false; 5580 const auto *ArgInstanceInfoAA = A.getAAFor<AAInstanceInfo>( 5581 *this, IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U)), 5582 DepClassTy::OPTIONAL); 5583 if (!ArgInstanceInfoAA || 5584 !ArgInstanceInfoAA->isAssumedUniqueForAnalysis()) 5585 return false; 5586 // If this call base might reach the scope again we might forward the 5587 // argument back here. This is very conservative. 5588 if (AA::isPotentiallyReachable( 5589 A, *CB, *Scope, *this, /* ExclusionSet */ nullptr, 5590 [Scope](const Function &Fn) { return &Fn != Scope; })) 5591 return false; 5592 return true; 5593 } 5594 return false; 5595 }; 5596 5597 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) { 5598 if (auto *SI = dyn_cast<StoreInst>(OldU.getUser())) { 5599 auto *Ptr = SI->getPointerOperand()->stripPointerCasts(); 5600 if ((isa<AllocaInst>(Ptr) || isNoAliasCall(Ptr)) && 5601 AA::isDynamicallyUnique(A, *this, *Ptr)) 5602 return true; 5603 } 5604 return false; 5605 }; 5606 5607 if (!A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ true, 5608 DepClassTy::OPTIONAL, 5609 /* IgnoreDroppableUses */ true, EquivalentUseCB)) 5610 return indicatePessimisticFixpoint(); 5611 5612 return Changed; 5613 } 5614 5615 /// See AbstractState::getAsStr(). 5616 const std::string getAsStr(Attributor *A) const override { 5617 return isAssumedUniqueForAnalysis() ? "<unique [fAa]>" : "<unknown>"; 5618 } 5619 5620 /// See AbstractAttribute::trackStatistics() 5621 void trackStatistics() const override {} 5622 }; 5623 5624 /// InstanceInfo attribute for floating values. 5625 struct AAInstanceInfoFloating : AAInstanceInfoImpl { 5626 AAInstanceInfoFloating(const IRPosition &IRP, Attributor &A) 5627 : AAInstanceInfoImpl(IRP, A) {} 5628 }; 5629 5630 /// NoCapture attribute for function arguments. 5631 struct AAInstanceInfoArgument final : AAInstanceInfoFloating { 5632 AAInstanceInfoArgument(const IRPosition &IRP, Attributor &A) 5633 : AAInstanceInfoFloating(IRP, A) {} 5634 }; 5635 5636 /// InstanceInfo attribute for call site arguments. 5637 struct AAInstanceInfoCallSiteArgument final : AAInstanceInfoImpl { 5638 AAInstanceInfoCallSiteArgument(const IRPosition &IRP, Attributor &A) 5639 : AAInstanceInfoImpl(IRP, A) {} 5640 5641 /// See AbstractAttribute::updateImpl(...). 5642 ChangeStatus updateImpl(Attributor &A) override { 5643 // TODO: Once we have call site specific value information we can provide 5644 // call site specific liveness information and then it makes 5645 // sense to specialize attributes for call sites arguments instead of 5646 // redirecting requests to the callee argument. 5647 Argument *Arg = getAssociatedArgument(); 5648 if (!Arg) 5649 return indicatePessimisticFixpoint(); 5650 const IRPosition &ArgPos = IRPosition::argument(*Arg); 5651 auto *ArgAA = 5652 A.getAAFor<AAInstanceInfo>(*this, ArgPos, DepClassTy::REQUIRED); 5653 if (!ArgAA) 5654 return indicatePessimisticFixpoint(); 5655 return clampStateAndIndicateChange(getState(), ArgAA->getState()); 5656 } 5657 }; 5658 5659 /// InstanceInfo attribute for function return value. 5660 struct AAInstanceInfoReturned final : AAInstanceInfoImpl { 5661 AAInstanceInfoReturned(const IRPosition &IRP, Attributor &A) 5662 : AAInstanceInfoImpl(IRP, A) { 5663 llvm_unreachable("InstanceInfo is not applicable to function returns!"); 5664 } 5665 5666 /// See AbstractAttribute::initialize(...). 5667 void initialize(Attributor &A) override { 5668 llvm_unreachable("InstanceInfo is not applicable to function returns!"); 5669 } 5670 5671 /// See AbstractAttribute::updateImpl(...). 5672 ChangeStatus updateImpl(Attributor &A) override { 5673 llvm_unreachable("InstanceInfo is not applicable to function returns!"); 5674 } 5675 }; 5676 5677 /// InstanceInfo attribute deduction for a call site return value. 5678 struct AAInstanceInfoCallSiteReturned final : AAInstanceInfoFloating { 5679 AAInstanceInfoCallSiteReturned(const IRPosition &IRP, Attributor &A) 5680 : AAInstanceInfoFloating(IRP, A) {} 5681 }; 5682 } // namespace 5683 5684 /// ----------------------- Variable Capturing --------------------------------- 5685 bool AANoCapture::isImpliedByIR(Attributor &A, const IRPosition &IRP, 5686 Attribute::AttrKind ImpliedAttributeKind, 5687 bool IgnoreSubsumingPositions) { 5688 assert(ImpliedAttributeKind == Attribute::NoCapture && 5689 "Unexpected attribute kind"); 5690 Value &V = IRP.getAssociatedValue(); 5691 if (!IRP.isArgumentPosition()) 5692 return V.use_empty(); 5693 5694 // You cannot "capture" null in the default address space. 5695 // 5696 // FIXME: This should use NullPointerIsDefined to account for the function 5697 // attribute. 5698 if (isa<UndefValue>(V) || (isa<ConstantPointerNull>(V) && 5699 V.getType()->getPointerAddressSpace() == 0)) { 5700 return true; 5701 } 5702 5703 if (A.hasAttr(IRP, {Attribute::NoCapture}, 5704 /* IgnoreSubsumingPositions */ true, Attribute::NoCapture)) 5705 return true; 5706 5707 if (IRP.getPositionKind() == IRP_CALL_SITE_ARGUMENT) 5708 if (Argument *Arg = IRP.getAssociatedArgument()) 5709 if (A.hasAttr(IRPosition::argument(*Arg), 5710 {Attribute::NoCapture, Attribute::ByVal}, 5711 /* IgnoreSubsumingPositions */ true)) { 5712 A.manifestAttrs(IRP, 5713 Attribute::get(V.getContext(), Attribute::NoCapture)); 5714 return true; 5715 } 5716 5717 if (const Function *F = IRP.getAssociatedFunction()) { 5718 // Check what state the associated function can actually capture. 5719 AANoCapture::StateType State; 5720 determineFunctionCaptureCapabilities(IRP, *F, State); 5721 if (State.isKnown(NO_CAPTURE)) { 5722 A.manifestAttrs(IRP, 5723 Attribute::get(V.getContext(), Attribute::NoCapture)); 5724 return true; 5725 } 5726 } 5727 5728 return false; 5729 } 5730 5731 /// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known 5732 /// depending on the ability of the function associated with \p IRP to capture 5733 /// state in memory and through "returning/throwing", respectively. 5734 void AANoCapture::determineFunctionCaptureCapabilities(const IRPosition &IRP, 5735 const Function &F, 5736 BitIntegerState &State) { 5737 // TODO: Once we have memory behavior attributes we should use them here. 5738 5739 // If we know we cannot communicate or write to memory, we do not care about 5740 // ptr2int anymore. 5741 bool ReadOnly = F.onlyReadsMemory(); 5742 bool NoThrow = F.doesNotThrow(); 5743 bool IsVoidReturn = F.getReturnType()->isVoidTy(); 5744 if (ReadOnly && NoThrow && IsVoidReturn) { 5745 State.addKnownBits(NO_CAPTURE); 5746 return; 5747 } 5748 5749 // A function cannot capture state in memory if it only reads memory, it can 5750 // however return/throw state and the state might be influenced by the 5751 // pointer value, e.g., loading from a returned pointer might reveal a bit. 5752 if (ReadOnly) 5753 State.addKnownBits(NOT_CAPTURED_IN_MEM); 5754 5755 // A function cannot communicate state back if it does not through 5756 // exceptions and doesn not return values. 5757 if (NoThrow && IsVoidReturn) 5758 State.addKnownBits(NOT_CAPTURED_IN_RET); 5759 5760 // Check existing "returned" attributes. 5761 int ArgNo = IRP.getCalleeArgNo(); 5762 if (!NoThrow || ArgNo < 0 || 5763 !F.getAttributes().hasAttrSomewhere(Attribute::Returned)) 5764 return; 5765 5766 for (unsigned U = 0, E = F.arg_size(); U < E; ++U) 5767 if (F.hasParamAttribute(U, Attribute::Returned)) { 5768 if (U == unsigned(ArgNo)) 5769 State.removeAssumedBits(NOT_CAPTURED_IN_RET); 5770 else if (ReadOnly) 5771 State.addKnownBits(NO_CAPTURE); 5772 else 5773 State.addKnownBits(NOT_CAPTURED_IN_RET); 5774 break; 5775 } 5776 } 5777 5778 namespace { 5779 /// A class to hold the state of for no-capture attributes. 5780 struct AANoCaptureImpl : public AANoCapture { 5781 AANoCaptureImpl(const IRPosition &IRP, Attributor &A) : AANoCapture(IRP, A) {} 5782 5783 /// See AbstractAttribute::initialize(...). 5784 void initialize(Attributor &A) override { 5785 bool IsKnown; 5786 assert(!AA::hasAssumedIRAttr<Attribute::NoCapture>( 5787 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown)); 5788 (void)IsKnown; 5789 } 5790 5791 /// See AbstractAttribute::updateImpl(...). 5792 ChangeStatus updateImpl(Attributor &A) override; 5793 5794 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...). 5795 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, 5796 SmallVectorImpl<Attribute> &Attrs) const override { 5797 if (!isAssumedNoCaptureMaybeReturned()) 5798 return; 5799 5800 if (isArgumentPosition()) { 5801 if (isAssumedNoCapture()) 5802 Attrs.emplace_back(Attribute::get(Ctx, Attribute::NoCapture)); 5803 else if (ManifestInternal) 5804 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned")); 5805 } 5806 } 5807 5808 /// See AbstractState::getAsStr(). 5809 const std::string getAsStr(Attributor *A) const override { 5810 if (isKnownNoCapture()) 5811 return "known not-captured"; 5812 if (isAssumedNoCapture()) 5813 return "assumed not-captured"; 5814 if (isKnownNoCaptureMaybeReturned()) 5815 return "known not-captured-maybe-returned"; 5816 if (isAssumedNoCaptureMaybeReturned()) 5817 return "assumed not-captured-maybe-returned"; 5818 return "assumed-captured"; 5819 } 5820 5821 /// Check the use \p U and update \p State accordingly. Return true if we 5822 /// should continue to update the state. 5823 bool checkUse(Attributor &A, AANoCapture::StateType &State, const Use &U, 5824 bool &Follow) { 5825 Instruction *UInst = cast<Instruction>(U.getUser()); 5826 LLVM_DEBUG(dbgs() << "[AANoCapture] Check use: " << *U.get() << " in " 5827 << *UInst << "\n"); 5828 5829 // Deal with ptr2int by following uses. 5830 if (isa<PtrToIntInst>(UInst)) { 5831 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n"); 5832 return isCapturedIn(State, /* Memory */ true, /* Integer */ true, 5833 /* Return */ true); 5834 } 5835 5836 // For stores we already checked if we can follow them, if they make it 5837 // here we give up. 5838 if (isa<StoreInst>(UInst)) 5839 return isCapturedIn(State, /* Memory */ true, /* Integer */ true, 5840 /* Return */ true); 5841 5842 // Explicitly catch return instructions. 5843 if (isa<ReturnInst>(UInst)) { 5844 if (UInst->getFunction() == getAnchorScope()) 5845 return isCapturedIn(State, /* Memory */ false, /* Integer */ false, 5846 /* Return */ true); 5847 return isCapturedIn(State, /* Memory */ true, /* Integer */ true, 5848 /* Return */ true); 5849 } 5850 5851 // For now we only use special logic for call sites. However, the tracker 5852 // itself knows about a lot of other non-capturing cases already. 5853 auto *CB = dyn_cast<CallBase>(UInst); 5854 if (!CB || !CB->isArgOperand(&U)) 5855 return isCapturedIn(State, /* Memory */ true, /* Integer */ true, 5856 /* Return */ true); 5857 5858 unsigned ArgNo = CB->getArgOperandNo(&U); 5859 const IRPosition &CSArgPos = IRPosition::callsite_argument(*CB, ArgNo); 5860 // If we have a abstract no-capture attribute for the argument we can use 5861 // it to justify a non-capture attribute here. This allows recursion! 5862 bool IsKnownNoCapture; 5863 const AANoCapture *ArgNoCaptureAA = nullptr; 5864 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>( 5865 A, this, CSArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false, 5866 &ArgNoCaptureAA); 5867 if (IsAssumedNoCapture) 5868 return isCapturedIn(State, /* Memory */ false, /* Integer */ false, 5869 /* Return */ false); 5870 if (ArgNoCaptureAA && ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned()) { 5871 Follow = true; 5872 return isCapturedIn(State, /* Memory */ false, /* Integer */ false, 5873 /* Return */ false); 5874 } 5875 5876 // Lastly, we could not find a reason no-capture can be assumed so we don't. 5877 return isCapturedIn(State, /* Memory */ true, /* Integer */ true, 5878 /* Return */ true); 5879 } 5880 5881 /// Update \p State according to \p CapturedInMem, \p CapturedInInt, and 5882 /// \p CapturedInRet, then return true if we should continue updating the 5883 /// state. 5884 static bool isCapturedIn(AANoCapture::StateType &State, bool CapturedInMem, 5885 bool CapturedInInt, bool CapturedInRet) { 5886 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int " 5887 << CapturedInInt << "|Ret " << CapturedInRet << "]\n"); 5888 if (CapturedInMem) 5889 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM); 5890 if (CapturedInInt) 5891 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT); 5892 if (CapturedInRet) 5893 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET); 5894 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED); 5895 } 5896 }; 5897 5898 ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) { 5899 const IRPosition &IRP = getIRPosition(); 5900 Value *V = isArgumentPosition() ? IRP.getAssociatedArgument() 5901 : &IRP.getAssociatedValue(); 5902 if (!V) 5903 return indicatePessimisticFixpoint(); 5904 5905 const Function *F = 5906 isArgumentPosition() ? IRP.getAssociatedFunction() : IRP.getAnchorScope(); 5907 5908 // TODO: Is the checkForAllUses below useful for constants? 5909 if (!F) 5910 return indicatePessimisticFixpoint(); 5911 5912 AANoCapture::StateType T; 5913 const IRPosition &FnPos = IRPosition::function(*F); 5914 5915 // Readonly means we cannot capture through memory. 5916 bool IsKnown; 5917 if (AA::isAssumedReadOnly(A, FnPos, *this, IsKnown)) { 5918 T.addKnownBits(NOT_CAPTURED_IN_MEM); 5919 if (IsKnown) 5920 addKnownBits(NOT_CAPTURED_IN_MEM); 5921 } 5922 5923 // Make sure all returned values are different than the underlying value. 5924 // TODO: we could do this in a more sophisticated way inside 5925 // AAReturnedValues, e.g., track all values that escape through returns 5926 // directly somehow. 5927 auto CheckReturnedArgs = [&](bool &UsedAssumedInformation) { 5928 SmallVector<AA::ValueAndContext> Values; 5929 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*F), this, Values, 5930 AA::ValueScope::Intraprocedural, 5931 UsedAssumedInformation)) 5932 return false; 5933 bool SeenConstant = false; 5934 for (const AA::ValueAndContext &VAC : Values) { 5935 if (isa<Constant>(VAC.getValue())) { 5936 if (SeenConstant) 5937 return false; 5938 SeenConstant = true; 5939 } else if (!isa<Argument>(VAC.getValue()) || 5940 VAC.getValue() == getAssociatedArgument()) 5941 return false; 5942 } 5943 return true; 5944 }; 5945 5946 bool IsKnownNoUnwind; 5947 if (AA::hasAssumedIRAttr<Attribute::NoUnwind>( 5948 A, this, FnPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) { 5949 bool IsVoidTy = F->getReturnType()->isVoidTy(); 5950 bool UsedAssumedInformation = false; 5951 if (IsVoidTy || CheckReturnedArgs(UsedAssumedInformation)) { 5952 T.addKnownBits(NOT_CAPTURED_IN_RET); 5953 if (T.isKnown(NOT_CAPTURED_IN_MEM)) 5954 return ChangeStatus::UNCHANGED; 5955 if (IsKnownNoUnwind && (IsVoidTy || !UsedAssumedInformation)) { 5956 addKnownBits(NOT_CAPTURED_IN_RET); 5957 if (isKnown(NOT_CAPTURED_IN_MEM)) 5958 return indicateOptimisticFixpoint(); 5959 } 5960 } 5961 } 5962 5963 auto IsDereferenceableOrNull = [&](Value *O, const DataLayout &DL) { 5964 const auto *DerefAA = A.getAAFor<AADereferenceable>( 5965 *this, IRPosition::value(*O), DepClassTy::OPTIONAL); 5966 return DerefAA && DerefAA->getAssumedDereferenceableBytes(); 5967 }; 5968 5969 auto UseCheck = [&](const Use &U, bool &Follow) -> bool { 5970 switch (DetermineUseCaptureKind(U, IsDereferenceableOrNull)) { 5971 case UseCaptureKind::NO_CAPTURE: 5972 return true; 5973 case UseCaptureKind::MAY_CAPTURE: 5974 return checkUse(A, T, U, Follow); 5975 case UseCaptureKind::PASSTHROUGH: 5976 Follow = true; 5977 return true; 5978 } 5979 llvm_unreachable("Unexpected use capture kind!"); 5980 }; 5981 5982 if (!A.checkForAllUses(UseCheck, *this, *V)) 5983 return indicatePessimisticFixpoint(); 5984 5985 AANoCapture::StateType &S = getState(); 5986 auto Assumed = S.getAssumed(); 5987 S.intersectAssumedBits(T.getAssumed()); 5988 if (!isAssumedNoCaptureMaybeReturned()) 5989 return indicatePessimisticFixpoint(); 5990 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED 5991 : ChangeStatus::CHANGED; 5992 } 5993 5994 /// NoCapture attribute for function arguments. 5995 struct AANoCaptureArgument final : AANoCaptureImpl { 5996 AANoCaptureArgument(const IRPosition &IRP, Attributor &A) 5997 : AANoCaptureImpl(IRP, A) {} 5998 5999 /// See AbstractAttribute::trackStatistics() 6000 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) } 6001 }; 6002 6003 /// NoCapture attribute for call site arguments. 6004 struct AANoCaptureCallSiteArgument final : AANoCaptureImpl { 6005 AANoCaptureCallSiteArgument(const IRPosition &IRP, Attributor &A) 6006 : AANoCaptureImpl(IRP, A) {} 6007 6008 /// See AbstractAttribute::updateImpl(...). 6009 ChangeStatus updateImpl(Attributor &A) override { 6010 // TODO: Once we have call site specific value information we can provide 6011 // call site specific liveness information and then it makes 6012 // sense to specialize attributes for call sites arguments instead of 6013 // redirecting requests to the callee argument. 6014 Argument *Arg = getAssociatedArgument(); 6015 if (!Arg) 6016 return indicatePessimisticFixpoint(); 6017 const IRPosition &ArgPos = IRPosition::argument(*Arg); 6018 bool IsKnownNoCapture; 6019 const AANoCapture *ArgAA = nullptr; 6020 if (AA::hasAssumedIRAttr<Attribute::NoCapture>( 6021 A, this, ArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false, 6022 &ArgAA)) 6023 return ChangeStatus::UNCHANGED; 6024 if (!ArgAA || !ArgAA->isAssumedNoCaptureMaybeReturned()) 6025 return indicatePessimisticFixpoint(); 6026 return clampStateAndIndicateChange(getState(), ArgAA->getState()); 6027 } 6028 6029 /// See AbstractAttribute::trackStatistics() 6030 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nocapture)}; 6031 }; 6032 6033 /// NoCapture attribute for floating values. 6034 struct AANoCaptureFloating final : AANoCaptureImpl { 6035 AANoCaptureFloating(const IRPosition &IRP, Attributor &A) 6036 : AANoCaptureImpl(IRP, A) {} 6037 6038 /// See AbstractAttribute::trackStatistics() 6039 void trackStatistics() const override { 6040 STATS_DECLTRACK_FLOATING_ATTR(nocapture) 6041 } 6042 }; 6043 6044 /// NoCapture attribute for function return value. 6045 struct AANoCaptureReturned final : AANoCaptureImpl { 6046 AANoCaptureReturned(const IRPosition &IRP, Attributor &A) 6047 : AANoCaptureImpl(IRP, A) { 6048 llvm_unreachable("NoCapture is not applicable to function returns!"); 6049 } 6050 6051 /// See AbstractAttribute::initialize(...). 6052 void initialize(Attributor &A) override { 6053 llvm_unreachable("NoCapture is not applicable to function returns!"); 6054 } 6055 6056 /// See AbstractAttribute::updateImpl(...). 6057 ChangeStatus updateImpl(Attributor &A) override { 6058 llvm_unreachable("NoCapture is not applicable to function returns!"); 6059 } 6060 6061 /// See AbstractAttribute::trackStatistics() 6062 void trackStatistics() const override {} 6063 }; 6064 6065 /// NoCapture attribute deduction for a call site return value. 6066 struct AANoCaptureCallSiteReturned final : AANoCaptureImpl { 6067 AANoCaptureCallSiteReturned(const IRPosition &IRP, Attributor &A) 6068 : AANoCaptureImpl(IRP, A) {} 6069 6070 /// See AbstractAttribute::initialize(...). 6071 void initialize(Attributor &A) override { 6072 const Function *F = getAnchorScope(); 6073 // Check what state the associated function can actually capture. 6074 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this); 6075 } 6076 6077 /// See AbstractAttribute::trackStatistics() 6078 void trackStatistics() const override { 6079 STATS_DECLTRACK_CSRET_ATTR(nocapture) 6080 } 6081 }; 6082 } // namespace 6083 6084 /// ------------------ Value Simplify Attribute ---------------------------- 6085 6086 bool ValueSimplifyStateType::unionAssumed(std::optional<Value *> Other) { 6087 // FIXME: Add a typecast support. 6088 SimplifiedAssociatedValue = AA::combineOptionalValuesInAAValueLatice( 6089 SimplifiedAssociatedValue, Other, Ty); 6090 if (SimplifiedAssociatedValue == std::optional<Value *>(nullptr)) 6091 return false; 6092 6093 LLVM_DEBUG({ 6094 if (SimplifiedAssociatedValue) 6095 dbgs() << "[ValueSimplify] is assumed to be " 6096 << **SimplifiedAssociatedValue << "\n"; 6097 else 6098 dbgs() << "[ValueSimplify] is assumed to be <none>\n"; 6099 }); 6100 return true; 6101 } 6102 6103 namespace { 6104 struct AAValueSimplifyImpl : AAValueSimplify { 6105 AAValueSimplifyImpl(const IRPosition &IRP, Attributor &A) 6106 : AAValueSimplify(IRP, A) {} 6107 6108 /// See AbstractAttribute::initialize(...). 6109 void initialize(Attributor &A) override { 6110 if (getAssociatedValue().getType()->isVoidTy()) 6111 indicatePessimisticFixpoint(); 6112 if (A.hasSimplificationCallback(getIRPosition())) 6113 indicatePessimisticFixpoint(); 6114 } 6115 6116 /// See AbstractAttribute::getAsStr(). 6117 const std::string getAsStr(Attributor *A) const override { 6118 LLVM_DEBUG({ 6119 dbgs() << "SAV: " << (bool)SimplifiedAssociatedValue << " "; 6120 if (SimplifiedAssociatedValue && *SimplifiedAssociatedValue) 6121 dbgs() << "SAV: " << **SimplifiedAssociatedValue << " "; 6122 }); 6123 return isValidState() ? (isAtFixpoint() ? "simplified" : "maybe-simple") 6124 : "not-simple"; 6125 } 6126 6127 /// See AbstractAttribute::trackStatistics() 6128 void trackStatistics() const override {} 6129 6130 /// See AAValueSimplify::getAssumedSimplifiedValue() 6131 std::optional<Value *> 6132 getAssumedSimplifiedValue(Attributor &A) const override { 6133 return SimplifiedAssociatedValue; 6134 } 6135 6136 /// Ensure the return value is \p V with type \p Ty, if not possible return 6137 /// nullptr. If \p Check is true we will only verify such an operation would 6138 /// suceed and return a non-nullptr value if that is the case. No IR is 6139 /// generated or modified. 6140 static Value *ensureType(Attributor &A, Value &V, Type &Ty, Instruction *CtxI, 6141 bool Check) { 6142 if (auto *TypedV = AA::getWithType(V, Ty)) 6143 return TypedV; 6144 if (CtxI && V.getType()->canLosslesslyBitCastTo(&Ty)) 6145 return Check ? &V 6146 : BitCastInst::CreatePointerBitCastOrAddrSpaceCast( 6147 &V, &Ty, "", CtxI->getIterator()); 6148 return nullptr; 6149 } 6150 6151 /// Reproduce \p I with type \p Ty or return nullptr if that is not posisble. 6152 /// If \p Check is true we will only verify such an operation would suceed and 6153 /// return a non-nullptr value if that is the case. No IR is generated or 6154 /// modified. 6155 static Value *reproduceInst(Attributor &A, 6156 const AbstractAttribute &QueryingAA, 6157 Instruction &I, Type &Ty, Instruction *CtxI, 6158 bool Check, ValueToValueMapTy &VMap) { 6159 assert(CtxI && "Cannot reproduce an instruction without context!"); 6160 if (Check && (I.mayReadFromMemory() || 6161 !isSafeToSpeculativelyExecute(&I, CtxI, /* DT */ nullptr, 6162 /* TLI */ nullptr))) 6163 return nullptr; 6164 for (Value *Op : I.operands()) { 6165 Value *NewOp = reproduceValue(A, QueryingAA, *Op, Ty, CtxI, Check, VMap); 6166 if (!NewOp) { 6167 assert(Check && "Manifest of new value unexpectedly failed!"); 6168 return nullptr; 6169 } 6170 if (!Check) 6171 VMap[Op] = NewOp; 6172 } 6173 if (Check) 6174 return &I; 6175 6176 Instruction *CloneI = I.clone(); 6177 // TODO: Try to salvage debug information here. 6178 CloneI->setDebugLoc(DebugLoc()); 6179 VMap[&I] = CloneI; 6180 CloneI->insertBefore(CtxI); 6181 RemapInstruction(CloneI, VMap); 6182 return CloneI; 6183 } 6184 6185 /// Reproduce \p V with type \p Ty or return nullptr if that is not posisble. 6186 /// If \p Check is true we will only verify such an operation would suceed and 6187 /// return a non-nullptr value if that is the case. No IR is generated or 6188 /// modified. 6189 static Value *reproduceValue(Attributor &A, 6190 const AbstractAttribute &QueryingAA, Value &V, 6191 Type &Ty, Instruction *CtxI, bool Check, 6192 ValueToValueMapTy &VMap) { 6193 if (const auto &NewV = VMap.lookup(&V)) 6194 return NewV; 6195 bool UsedAssumedInformation = false; 6196 std::optional<Value *> SimpleV = A.getAssumedSimplified( 6197 V, QueryingAA, UsedAssumedInformation, AA::Interprocedural); 6198 if (!SimpleV.has_value()) 6199 return PoisonValue::get(&Ty); 6200 Value *EffectiveV = &V; 6201 if (*SimpleV) 6202 EffectiveV = *SimpleV; 6203 if (auto *C = dyn_cast<Constant>(EffectiveV)) 6204 return C; 6205 if (CtxI && AA::isValidAtPosition(AA::ValueAndContext(*EffectiveV, *CtxI), 6206 A.getInfoCache())) 6207 return ensureType(A, *EffectiveV, Ty, CtxI, Check); 6208 if (auto *I = dyn_cast<Instruction>(EffectiveV)) 6209 if (Value *NewV = reproduceInst(A, QueryingAA, *I, Ty, CtxI, Check, VMap)) 6210 return ensureType(A, *NewV, Ty, CtxI, Check); 6211 return nullptr; 6212 } 6213 6214 /// Return a value we can use as replacement for the associated one, or 6215 /// nullptr if we don't have one that makes sense. 6216 Value *manifestReplacementValue(Attributor &A, Instruction *CtxI) const { 6217 Value *NewV = SimplifiedAssociatedValue 6218 ? *SimplifiedAssociatedValue 6219 : UndefValue::get(getAssociatedType()); 6220 if (NewV && NewV != &getAssociatedValue()) { 6221 ValueToValueMapTy VMap; 6222 // First verify we can reprduce the value with the required type at the 6223 // context location before we actually start modifying the IR. 6224 if (reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI, 6225 /* CheckOnly */ true, VMap)) 6226 return reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI, 6227 /* CheckOnly */ false, VMap); 6228 } 6229 return nullptr; 6230 } 6231 6232 /// Helper function for querying AAValueSimplify and updating candidate. 6233 /// \param IRP The value position we are trying to unify with SimplifiedValue 6234 bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA, 6235 const IRPosition &IRP, bool Simplify = true) { 6236 bool UsedAssumedInformation = false; 6237 std::optional<Value *> QueryingValueSimplified = &IRP.getAssociatedValue(); 6238 if (Simplify) 6239 QueryingValueSimplified = A.getAssumedSimplified( 6240 IRP, QueryingAA, UsedAssumedInformation, AA::Interprocedural); 6241 return unionAssumed(QueryingValueSimplified); 6242 } 6243 6244 /// Returns a candidate is found or not 6245 template <typename AAType> bool askSimplifiedValueFor(Attributor &A) { 6246 if (!getAssociatedValue().getType()->isIntegerTy()) 6247 return false; 6248 6249 // This will also pass the call base context. 6250 const auto *AA = 6251 A.getAAFor<AAType>(*this, getIRPosition(), DepClassTy::NONE); 6252 if (!AA) 6253 return false; 6254 6255 std::optional<Constant *> COpt = AA->getAssumedConstant(A); 6256 6257 if (!COpt) { 6258 SimplifiedAssociatedValue = std::nullopt; 6259 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL); 6260 return true; 6261 } 6262 if (auto *C = *COpt) { 6263 SimplifiedAssociatedValue = C; 6264 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL); 6265 return true; 6266 } 6267 return false; 6268 } 6269 6270 bool askSimplifiedValueForOtherAAs(Attributor &A) { 6271 if (askSimplifiedValueFor<AAValueConstantRange>(A)) 6272 return true; 6273 if (askSimplifiedValueFor<AAPotentialConstantValues>(A)) 6274 return true; 6275 return false; 6276 } 6277 6278 /// See AbstractAttribute::manifest(...). 6279 ChangeStatus manifest(Attributor &A) override { 6280 ChangeStatus Changed = ChangeStatus::UNCHANGED; 6281 for (auto &U : getAssociatedValue().uses()) { 6282 // Check if we need to adjust the insertion point to make sure the IR is 6283 // valid. 6284 Instruction *IP = dyn_cast<Instruction>(U.getUser()); 6285 if (auto *PHI = dyn_cast_or_null<PHINode>(IP)) 6286 IP = PHI->getIncomingBlock(U)->getTerminator(); 6287 if (auto *NewV = manifestReplacementValue(A, IP)) { 6288 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << getAssociatedValue() 6289 << " -> " << *NewV << " :: " << *this << "\n"); 6290 if (A.changeUseAfterManifest(U, *NewV)) 6291 Changed = ChangeStatus::CHANGED; 6292 } 6293 } 6294 6295 return Changed | AAValueSimplify::manifest(A); 6296 } 6297 6298 /// See AbstractState::indicatePessimisticFixpoint(...). 6299 ChangeStatus indicatePessimisticFixpoint() override { 6300 SimplifiedAssociatedValue = &getAssociatedValue(); 6301 return AAValueSimplify::indicatePessimisticFixpoint(); 6302 } 6303 }; 6304 6305 struct AAValueSimplifyArgument final : AAValueSimplifyImpl { 6306 AAValueSimplifyArgument(const IRPosition &IRP, Attributor &A) 6307 : AAValueSimplifyImpl(IRP, A) {} 6308 6309 void initialize(Attributor &A) override { 6310 AAValueSimplifyImpl::initialize(A); 6311 if (A.hasAttr(getIRPosition(), 6312 {Attribute::InAlloca, Attribute::Preallocated, 6313 Attribute::StructRet, Attribute::Nest, Attribute::ByVal}, 6314 /* IgnoreSubsumingPositions */ true)) 6315 indicatePessimisticFixpoint(); 6316 } 6317 6318 /// See AbstractAttribute::updateImpl(...). 6319 ChangeStatus updateImpl(Attributor &A) override { 6320 // Byval is only replacable if it is readonly otherwise we would write into 6321 // the replaced value and not the copy that byval creates implicitly. 6322 Argument *Arg = getAssociatedArgument(); 6323 if (Arg->hasByValAttr()) { 6324 // TODO: We probably need to verify synchronization is not an issue, e.g., 6325 // there is no race by not copying a constant byval. 6326 bool IsKnown; 6327 if (!AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown)) 6328 return indicatePessimisticFixpoint(); 6329 } 6330 6331 auto Before = SimplifiedAssociatedValue; 6332 6333 auto PredForCallSite = [&](AbstractCallSite ACS) { 6334 const IRPosition &ACSArgPos = 6335 IRPosition::callsite_argument(ACS, getCallSiteArgNo()); 6336 // Check if a coresponding argument was found or if it is on not 6337 // associated (which can happen for callback calls). 6338 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID) 6339 return false; 6340 6341 // Simplify the argument operand explicitly and check if the result is 6342 // valid in the current scope. This avoids refering to simplified values 6343 // in other functions, e.g., we don't want to say a an argument in a 6344 // static function is actually an argument in a different function. 6345 bool UsedAssumedInformation = false; 6346 std::optional<Constant *> SimpleArgOp = 6347 A.getAssumedConstant(ACSArgPos, *this, UsedAssumedInformation); 6348 if (!SimpleArgOp) 6349 return true; 6350 if (!*SimpleArgOp) 6351 return false; 6352 if (!AA::isDynamicallyUnique(A, *this, **SimpleArgOp)) 6353 return false; 6354 return unionAssumed(*SimpleArgOp); 6355 }; 6356 6357 // Generate a answer specific to a call site context. 6358 bool Success; 6359 bool UsedAssumedInformation = false; 6360 if (hasCallBaseContext() && 6361 getCallBaseContext()->getCalledOperand() == Arg->getParent()) 6362 Success = PredForCallSite( 6363 AbstractCallSite(&getCallBaseContext()->getCalledOperandUse())); 6364 else 6365 Success = A.checkForAllCallSites(PredForCallSite, *this, true, 6366 UsedAssumedInformation); 6367 6368 if (!Success) 6369 if (!askSimplifiedValueForOtherAAs(A)) 6370 return indicatePessimisticFixpoint(); 6371 6372 // If a candidate was found in this update, return CHANGED. 6373 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED 6374 : ChangeStatus ::CHANGED; 6375 } 6376 6377 /// See AbstractAttribute::trackStatistics() 6378 void trackStatistics() const override { 6379 STATS_DECLTRACK_ARG_ATTR(value_simplify) 6380 } 6381 }; 6382 6383 struct AAValueSimplifyReturned : AAValueSimplifyImpl { 6384 AAValueSimplifyReturned(const IRPosition &IRP, Attributor &A) 6385 : AAValueSimplifyImpl(IRP, A) {} 6386 6387 /// See AAValueSimplify::getAssumedSimplifiedValue() 6388 std::optional<Value *> 6389 getAssumedSimplifiedValue(Attributor &A) const override { 6390 if (!isValidState()) 6391 return nullptr; 6392 return SimplifiedAssociatedValue; 6393 } 6394 6395 /// See AbstractAttribute::updateImpl(...). 6396 ChangeStatus updateImpl(Attributor &A) override { 6397 auto Before = SimplifiedAssociatedValue; 6398 6399 auto ReturnInstCB = [&](Instruction &I) { 6400 auto &RI = cast<ReturnInst>(I); 6401 return checkAndUpdate( 6402 A, *this, 6403 IRPosition::value(*RI.getReturnValue(), getCallBaseContext())); 6404 }; 6405 6406 bool UsedAssumedInformation = false; 6407 if (!A.checkForAllInstructions(ReturnInstCB, *this, {Instruction::Ret}, 6408 UsedAssumedInformation)) 6409 if (!askSimplifiedValueForOtherAAs(A)) 6410 return indicatePessimisticFixpoint(); 6411 6412 // If a candidate was found in this update, return CHANGED. 6413 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED 6414 : ChangeStatus ::CHANGED; 6415 } 6416 6417 ChangeStatus manifest(Attributor &A) override { 6418 // We queried AAValueSimplify for the returned values so they will be 6419 // replaced if a simplified form was found. Nothing to do here. 6420 return ChangeStatus::UNCHANGED; 6421 } 6422 6423 /// See AbstractAttribute::trackStatistics() 6424 void trackStatistics() const override { 6425 STATS_DECLTRACK_FNRET_ATTR(value_simplify) 6426 } 6427 }; 6428 6429 struct AAValueSimplifyFloating : AAValueSimplifyImpl { 6430 AAValueSimplifyFloating(const IRPosition &IRP, Attributor &A) 6431 : AAValueSimplifyImpl(IRP, A) {} 6432 6433 /// See AbstractAttribute::initialize(...). 6434 void initialize(Attributor &A) override { 6435 AAValueSimplifyImpl::initialize(A); 6436 Value &V = getAnchorValue(); 6437 6438 // TODO: add other stuffs 6439 if (isa<Constant>(V)) 6440 indicatePessimisticFixpoint(); 6441 } 6442 6443 /// See AbstractAttribute::updateImpl(...). 6444 ChangeStatus updateImpl(Attributor &A) override { 6445 auto Before = SimplifiedAssociatedValue; 6446 if (!askSimplifiedValueForOtherAAs(A)) 6447 return indicatePessimisticFixpoint(); 6448 6449 // If a candidate was found in this update, return CHANGED. 6450 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED 6451 : ChangeStatus ::CHANGED; 6452 } 6453 6454 /// See AbstractAttribute::trackStatistics() 6455 void trackStatistics() const override { 6456 STATS_DECLTRACK_FLOATING_ATTR(value_simplify) 6457 } 6458 }; 6459 6460 struct AAValueSimplifyFunction : AAValueSimplifyImpl { 6461 AAValueSimplifyFunction(const IRPosition &IRP, Attributor &A) 6462 : AAValueSimplifyImpl(IRP, A) {} 6463 6464 /// See AbstractAttribute::initialize(...). 6465 void initialize(Attributor &A) override { 6466 SimplifiedAssociatedValue = nullptr; 6467 indicateOptimisticFixpoint(); 6468 } 6469 /// See AbstractAttribute::initialize(...). 6470 ChangeStatus updateImpl(Attributor &A) override { 6471 llvm_unreachable( 6472 "AAValueSimplify(Function|CallSite)::updateImpl will not be called"); 6473 } 6474 /// See AbstractAttribute::trackStatistics() 6475 void trackStatistics() const override { 6476 STATS_DECLTRACK_FN_ATTR(value_simplify) 6477 } 6478 }; 6479 6480 struct AAValueSimplifyCallSite : AAValueSimplifyFunction { 6481 AAValueSimplifyCallSite(const IRPosition &IRP, Attributor &A) 6482 : AAValueSimplifyFunction(IRP, A) {} 6483 /// See AbstractAttribute::trackStatistics() 6484 void trackStatistics() const override { 6485 STATS_DECLTRACK_CS_ATTR(value_simplify) 6486 } 6487 }; 6488 6489 struct AAValueSimplifyCallSiteReturned : AAValueSimplifyImpl { 6490 AAValueSimplifyCallSiteReturned(const IRPosition &IRP, Attributor &A) 6491 : AAValueSimplifyImpl(IRP, A) {} 6492 6493 void initialize(Attributor &A) override { 6494 AAValueSimplifyImpl::initialize(A); 6495 Function *Fn = getAssociatedFunction(); 6496 assert(Fn && "Did expect an associted function"); 6497 for (Argument &Arg : Fn->args()) { 6498 if (Arg.hasReturnedAttr()) { 6499 auto IRP = IRPosition::callsite_argument(*cast<CallBase>(getCtxI()), 6500 Arg.getArgNo()); 6501 if (IRP.getPositionKind() == IRPosition::IRP_CALL_SITE_ARGUMENT && 6502 checkAndUpdate(A, *this, IRP)) 6503 indicateOptimisticFixpoint(); 6504 else 6505 indicatePessimisticFixpoint(); 6506 return; 6507 } 6508 } 6509 } 6510 6511 /// See AbstractAttribute::updateImpl(...). 6512 ChangeStatus updateImpl(Attributor &A) override { 6513 return indicatePessimisticFixpoint(); 6514 } 6515 6516 void trackStatistics() const override { 6517 STATS_DECLTRACK_CSRET_ATTR(value_simplify) 6518 } 6519 }; 6520 6521 struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating { 6522 AAValueSimplifyCallSiteArgument(const IRPosition &IRP, Attributor &A) 6523 : AAValueSimplifyFloating(IRP, A) {} 6524 6525 /// See AbstractAttribute::manifest(...). 6526 ChangeStatus manifest(Attributor &A) override { 6527 ChangeStatus Changed = ChangeStatus::UNCHANGED; 6528 // TODO: We should avoid simplification duplication to begin with. 6529 auto *FloatAA = A.lookupAAFor<AAValueSimplify>( 6530 IRPosition::value(getAssociatedValue()), this, DepClassTy::NONE); 6531 if (FloatAA && FloatAA->getState().isValidState()) 6532 return Changed; 6533 6534 if (auto *NewV = manifestReplacementValue(A, getCtxI())) { 6535 Use &U = cast<CallBase>(&getAnchorValue()) 6536 ->getArgOperandUse(getCallSiteArgNo()); 6537 if (A.changeUseAfterManifest(U, *NewV)) 6538 Changed = ChangeStatus::CHANGED; 6539 } 6540 6541 return Changed | AAValueSimplify::manifest(A); 6542 } 6543 6544 void trackStatistics() const override { 6545 STATS_DECLTRACK_CSARG_ATTR(value_simplify) 6546 } 6547 }; 6548 } // namespace 6549 6550 /// ----------------------- Heap-To-Stack Conversion --------------------------- 6551 namespace { 6552 struct AAHeapToStackFunction final : public AAHeapToStack { 6553 6554 struct AllocationInfo { 6555 /// The call that allocates the memory. 6556 CallBase *const CB; 6557 6558 /// The library function id for the allocation. 6559 LibFunc LibraryFunctionId = NotLibFunc; 6560 6561 /// The status wrt. a rewrite. 6562 enum { 6563 STACK_DUE_TO_USE, 6564 STACK_DUE_TO_FREE, 6565 INVALID, 6566 } Status = STACK_DUE_TO_USE; 6567 6568 /// Flag to indicate if we encountered a use that might free this allocation 6569 /// but which is not in the deallocation infos. 6570 bool HasPotentiallyFreeingUnknownUses = false; 6571 6572 /// Flag to indicate that we should place the new alloca in the function 6573 /// entry block rather than where the call site (CB) is. 6574 bool MoveAllocaIntoEntry = true; 6575 6576 /// The set of free calls that use this allocation. 6577 SmallSetVector<CallBase *, 1> PotentialFreeCalls{}; 6578 }; 6579 6580 struct DeallocationInfo { 6581 /// The call that deallocates the memory. 6582 CallBase *const CB; 6583 /// The value freed by the call. 6584 Value *FreedOp; 6585 6586 /// Flag to indicate if we don't know all objects this deallocation might 6587 /// free. 6588 bool MightFreeUnknownObjects = false; 6589 6590 /// The set of allocation calls that are potentially freed. 6591 SmallSetVector<CallBase *, 1> PotentialAllocationCalls{}; 6592 }; 6593 6594 AAHeapToStackFunction(const IRPosition &IRP, Attributor &A) 6595 : AAHeapToStack(IRP, A) {} 6596 6597 ~AAHeapToStackFunction() { 6598 // Ensure we call the destructor so we release any memory allocated in the 6599 // sets. 6600 for (auto &It : AllocationInfos) 6601 It.second->~AllocationInfo(); 6602 for (auto &It : DeallocationInfos) 6603 It.second->~DeallocationInfo(); 6604 } 6605 6606 void initialize(Attributor &A) override { 6607 AAHeapToStack::initialize(A); 6608 6609 const Function *F = getAnchorScope(); 6610 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F); 6611 6612 auto AllocationIdentifierCB = [&](Instruction &I) { 6613 CallBase *CB = dyn_cast<CallBase>(&I); 6614 if (!CB) 6615 return true; 6616 if (Value *FreedOp = getFreedOperand(CB, TLI)) { 6617 DeallocationInfos[CB] = new (A.Allocator) DeallocationInfo{CB, FreedOp}; 6618 return true; 6619 } 6620 // To do heap to stack, we need to know that the allocation itself is 6621 // removable once uses are rewritten, and that we can initialize the 6622 // alloca to the same pattern as the original allocation result. 6623 if (isRemovableAlloc(CB, TLI)) { 6624 auto *I8Ty = Type::getInt8Ty(CB->getParent()->getContext()); 6625 if (nullptr != getInitialValueOfAllocation(CB, TLI, I8Ty)) { 6626 AllocationInfo *AI = new (A.Allocator) AllocationInfo{CB}; 6627 AllocationInfos[CB] = AI; 6628 if (TLI) 6629 TLI->getLibFunc(*CB, AI->LibraryFunctionId); 6630 } 6631 } 6632 return true; 6633 }; 6634 6635 bool UsedAssumedInformation = false; 6636 bool Success = A.checkForAllCallLikeInstructions( 6637 AllocationIdentifierCB, *this, UsedAssumedInformation, 6638 /* CheckBBLivenessOnly */ false, 6639 /* CheckPotentiallyDead */ true); 6640 (void)Success; 6641 assert(Success && "Did not expect the call base visit callback to fail!"); 6642 6643 Attributor::SimplifictionCallbackTy SCB = 6644 [](const IRPosition &, const AbstractAttribute *, 6645 bool &) -> std::optional<Value *> { return nullptr; }; 6646 for (const auto &It : AllocationInfos) 6647 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first), 6648 SCB); 6649 for (const auto &It : DeallocationInfos) 6650 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first), 6651 SCB); 6652 } 6653 6654 const std::string getAsStr(Attributor *A) const override { 6655 unsigned NumH2SMallocs = 0, NumInvalidMallocs = 0; 6656 for (const auto &It : AllocationInfos) { 6657 if (It.second->Status == AllocationInfo::INVALID) 6658 ++NumInvalidMallocs; 6659 else 6660 ++NumH2SMallocs; 6661 } 6662 return "[H2S] Mallocs Good/Bad: " + std::to_string(NumH2SMallocs) + "/" + 6663 std::to_string(NumInvalidMallocs); 6664 } 6665 6666 /// See AbstractAttribute::trackStatistics(). 6667 void trackStatistics() const override { 6668 STATS_DECL( 6669 MallocCalls, Function, 6670 "Number of malloc/calloc/aligned_alloc calls converted to allocas"); 6671 for (const auto &It : AllocationInfos) 6672 if (It.second->Status != AllocationInfo::INVALID) 6673 ++BUILD_STAT_NAME(MallocCalls, Function); 6674 } 6675 6676 bool isAssumedHeapToStack(const CallBase &CB) const override { 6677 if (isValidState()) 6678 if (AllocationInfo *AI = 6679 AllocationInfos.lookup(const_cast<CallBase *>(&CB))) 6680 return AI->Status != AllocationInfo::INVALID; 6681 return false; 6682 } 6683 6684 bool isAssumedHeapToStackRemovedFree(CallBase &CB) const override { 6685 if (!isValidState()) 6686 return false; 6687 6688 for (const auto &It : AllocationInfos) { 6689 AllocationInfo &AI = *It.second; 6690 if (AI.Status == AllocationInfo::INVALID) 6691 continue; 6692 6693 if (AI.PotentialFreeCalls.count(&CB)) 6694 return true; 6695 } 6696 6697 return false; 6698 } 6699 6700 ChangeStatus manifest(Attributor &A) override { 6701 assert(getState().isValidState() && 6702 "Attempted to manifest an invalid state!"); 6703 6704 ChangeStatus HasChanged = ChangeStatus::UNCHANGED; 6705 Function *F = getAnchorScope(); 6706 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F); 6707 6708 for (auto &It : AllocationInfos) { 6709 AllocationInfo &AI = *It.second; 6710 if (AI.Status == AllocationInfo::INVALID) 6711 continue; 6712 6713 for (CallBase *FreeCall : AI.PotentialFreeCalls) { 6714 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n"); 6715 A.deleteAfterManifest(*FreeCall); 6716 HasChanged = ChangeStatus::CHANGED; 6717 } 6718 6719 LLVM_DEBUG(dbgs() << "H2S: Removing malloc-like call: " << *AI.CB 6720 << "\n"); 6721 6722 auto Remark = [&](OptimizationRemark OR) { 6723 LibFunc IsAllocShared; 6724 if (TLI->getLibFunc(*AI.CB, IsAllocShared)) 6725 if (IsAllocShared == LibFunc___kmpc_alloc_shared) 6726 return OR << "Moving globalized variable to the stack."; 6727 return OR << "Moving memory allocation from the heap to the stack."; 6728 }; 6729 if (AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared) 6730 A.emitRemark<OptimizationRemark>(AI.CB, "OMP110", Remark); 6731 else 6732 A.emitRemark<OptimizationRemark>(AI.CB, "HeapToStack", Remark); 6733 6734 const DataLayout &DL = A.getInfoCache().getDL(); 6735 Value *Size; 6736 std::optional<APInt> SizeAPI = getSize(A, *this, AI); 6737 if (SizeAPI) { 6738 Size = ConstantInt::get(AI.CB->getContext(), *SizeAPI); 6739 } else { 6740 LLVMContext &Ctx = AI.CB->getContext(); 6741 ObjectSizeOpts Opts; 6742 ObjectSizeOffsetEvaluator Eval(DL, TLI, Ctx, Opts); 6743 SizeOffsetValue SizeOffsetPair = Eval.compute(AI.CB); 6744 assert(SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown() && 6745 cast<ConstantInt>(SizeOffsetPair.Offset)->isZero()); 6746 Size = SizeOffsetPair.Size; 6747 } 6748 6749 BasicBlock::iterator IP = AI.MoveAllocaIntoEntry 6750 ? F->getEntryBlock().begin() 6751 : AI.CB->getIterator(); 6752 6753 Align Alignment(1); 6754 if (MaybeAlign RetAlign = AI.CB->getRetAlign()) 6755 Alignment = std::max(Alignment, *RetAlign); 6756 if (Value *Align = getAllocAlignment(AI.CB, TLI)) { 6757 std::optional<APInt> AlignmentAPI = getAPInt(A, *this, *Align); 6758 assert(AlignmentAPI && AlignmentAPI->getZExtValue() > 0 && 6759 "Expected an alignment during manifest!"); 6760 Alignment = 6761 std::max(Alignment, assumeAligned(AlignmentAPI->getZExtValue())); 6762 } 6763 6764 // TODO: Hoist the alloca towards the function entry. 6765 unsigned AS = DL.getAllocaAddrSpace(); 6766 Instruction *Alloca = 6767 new AllocaInst(Type::getInt8Ty(F->getContext()), AS, Size, Alignment, 6768 AI.CB->getName() + ".h2s", IP); 6769 6770 if (Alloca->getType() != AI.CB->getType()) 6771 Alloca = BitCastInst::CreatePointerBitCastOrAddrSpaceCast( 6772 Alloca, AI.CB->getType(), "malloc_cast", AI.CB->getIterator()); 6773 6774 auto *I8Ty = Type::getInt8Ty(F->getContext()); 6775 auto *InitVal = getInitialValueOfAllocation(AI.CB, TLI, I8Ty); 6776 assert(InitVal && 6777 "Must be able to materialize initial memory state of allocation"); 6778 6779 A.changeAfterManifest(IRPosition::inst(*AI.CB), *Alloca); 6780 6781 if (auto *II = dyn_cast<InvokeInst>(AI.CB)) { 6782 auto *NBB = II->getNormalDest(); 6783 BranchInst::Create(NBB, AI.CB->getParent()); 6784 A.deleteAfterManifest(*AI.CB); 6785 } else { 6786 A.deleteAfterManifest(*AI.CB); 6787 } 6788 6789 // Initialize the alloca with the same value as used by the allocation 6790 // function. We can skip undef as the initial value of an alloc is 6791 // undef, and the memset would simply end up being DSEd. 6792 if (!isa<UndefValue>(InitVal)) { 6793 IRBuilder<> Builder(Alloca->getNextNode()); 6794 // TODO: Use alignment above if align!=1 6795 Builder.CreateMemSet(Alloca, InitVal, Size, std::nullopt); 6796 } 6797 HasChanged = ChangeStatus::CHANGED; 6798 } 6799 6800 return HasChanged; 6801 } 6802 6803 std::optional<APInt> getAPInt(Attributor &A, const AbstractAttribute &AA, 6804 Value &V) { 6805 bool UsedAssumedInformation = false; 6806 std::optional<Constant *> SimpleV = 6807 A.getAssumedConstant(V, AA, UsedAssumedInformation); 6808 if (!SimpleV) 6809 return APInt(64, 0); 6810 if (auto *CI = dyn_cast_or_null<ConstantInt>(*SimpleV)) 6811 return CI->getValue(); 6812 return std::nullopt; 6813 } 6814 6815 std::optional<APInt> getSize(Attributor &A, const AbstractAttribute &AA, 6816 AllocationInfo &AI) { 6817 auto Mapper = [&](const Value *V) -> const Value * { 6818 bool UsedAssumedInformation = false; 6819 if (std::optional<Constant *> SimpleV = 6820 A.getAssumedConstant(*V, AA, UsedAssumedInformation)) 6821 if (*SimpleV) 6822 return *SimpleV; 6823 return V; 6824 }; 6825 6826 const Function *F = getAnchorScope(); 6827 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F); 6828 return getAllocSize(AI.CB, TLI, Mapper); 6829 } 6830 6831 /// Collection of all malloc-like calls in a function with associated 6832 /// information. 6833 MapVector<CallBase *, AllocationInfo *> AllocationInfos; 6834 6835 /// Collection of all free-like calls in a function with associated 6836 /// information. 6837 MapVector<CallBase *, DeallocationInfo *> DeallocationInfos; 6838 6839 ChangeStatus updateImpl(Attributor &A) override; 6840 }; 6841 6842 ChangeStatus AAHeapToStackFunction::updateImpl(Attributor &A) { 6843 ChangeStatus Changed = ChangeStatus::UNCHANGED; 6844 const Function *F = getAnchorScope(); 6845 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F); 6846 6847 const auto *LivenessAA = 6848 A.getAAFor<AAIsDead>(*this, IRPosition::function(*F), DepClassTy::NONE); 6849 6850 MustBeExecutedContextExplorer *Explorer = 6851 A.getInfoCache().getMustBeExecutedContextExplorer(); 6852 6853 bool StackIsAccessibleByOtherThreads = 6854 A.getInfoCache().stackIsAccessibleByOtherThreads(); 6855 6856 LoopInfo *LI = 6857 A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(*F); 6858 std::optional<bool> MayContainIrreducibleControl; 6859 auto IsInLoop = [&](BasicBlock &BB) { 6860 if (&F->getEntryBlock() == &BB) 6861 return false; 6862 if (!MayContainIrreducibleControl.has_value()) 6863 MayContainIrreducibleControl = mayContainIrreducibleControl(*F, LI); 6864 if (*MayContainIrreducibleControl) 6865 return true; 6866 if (!LI) 6867 return true; 6868 return LI->getLoopFor(&BB) != nullptr; 6869 }; 6870 6871 // Flag to ensure we update our deallocation information at most once per 6872 // updateImpl call and only if we use the free check reasoning. 6873 bool HasUpdatedFrees = false; 6874 6875 auto UpdateFrees = [&]() { 6876 HasUpdatedFrees = true; 6877 6878 for (auto &It : DeallocationInfos) { 6879 DeallocationInfo &DI = *It.second; 6880 // For now we cannot use deallocations that have unknown inputs, skip 6881 // them. 6882 if (DI.MightFreeUnknownObjects) 6883 continue; 6884 6885 // No need to analyze dead calls, ignore them instead. 6886 bool UsedAssumedInformation = false; 6887 if (A.isAssumedDead(*DI.CB, this, LivenessAA, UsedAssumedInformation, 6888 /* CheckBBLivenessOnly */ true)) 6889 continue; 6890 6891 // Use the non-optimistic version to get the freed object. 6892 Value *Obj = getUnderlyingObject(DI.FreedOp); 6893 if (!Obj) { 6894 LLVM_DEBUG(dbgs() << "[H2S] Unknown underlying object for free!\n"); 6895 DI.MightFreeUnknownObjects = true; 6896 continue; 6897 } 6898 6899 // Free of null and undef can be ignored as no-ops (or UB in the latter 6900 // case). 6901 if (isa<ConstantPointerNull>(Obj) || isa<UndefValue>(Obj)) 6902 continue; 6903 6904 CallBase *ObjCB = dyn_cast<CallBase>(Obj); 6905 if (!ObjCB) { 6906 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-call object: " << *Obj 6907 << "\n"); 6908 DI.MightFreeUnknownObjects = true; 6909 continue; 6910 } 6911 6912 AllocationInfo *AI = AllocationInfos.lookup(ObjCB); 6913 if (!AI) { 6914 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-allocation object: " << *Obj 6915 << "\n"); 6916 DI.MightFreeUnknownObjects = true; 6917 continue; 6918 } 6919 6920 DI.PotentialAllocationCalls.insert(ObjCB); 6921 } 6922 }; 6923 6924 auto FreeCheck = [&](AllocationInfo &AI) { 6925 // If the stack is not accessible by other threads, the "must-free" logic 6926 // doesn't apply as the pointer could be shared and needs to be places in 6927 // "shareable" memory. 6928 if (!StackIsAccessibleByOtherThreads) { 6929 bool IsKnownNoSycn; 6930 if (!AA::hasAssumedIRAttr<Attribute::NoSync>( 6931 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoSycn)) { 6932 LLVM_DEBUG( 6933 dbgs() << "[H2S] found an escaping use, stack is not accessible by " 6934 "other threads and function is not nosync:\n"); 6935 return false; 6936 } 6937 } 6938 if (!HasUpdatedFrees) 6939 UpdateFrees(); 6940 6941 // TODO: Allow multi exit functions that have different free calls. 6942 if (AI.PotentialFreeCalls.size() != 1) { 6943 LLVM_DEBUG(dbgs() << "[H2S] did not find one free call but " 6944 << AI.PotentialFreeCalls.size() << "\n"); 6945 return false; 6946 } 6947 CallBase *UniqueFree = *AI.PotentialFreeCalls.begin(); 6948 DeallocationInfo *DI = DeallocationInfos.lookup(UniqueFree); 6949 if (!DI) { 6950 LLVM_DEBUG( 6951 dbgs() << "[H2S] unique free call was not known as deallocation call " 6952 << *UniqueFree << "\n"); 6953 return false; 6954 } 6955 if (DI->MightFreeUnknownObjects) { 6956 LLVM_DEBUG( 6957 dbgs() << "[H2S] unique free call might free unknown allocations\n"); 6958 return false; 6959 } 6960 if (DI->PotentialAllocationCalls.empty()) 6961 return true; 6962 if (DI->PotentialAllocationCalls.size() > 1) { 6963 LLVM_DEBUG(dbgs() << "[H2S] unique free call might free " 6964 << DI->PotentialAllocationCalls.size() 6965 << " different allocations\n"); 6966 return false; 6967 } 6968 if (*DI->PotentialAllocationCalls.begin() != AI.CB) { 6969 LLVM_DEBUG( 6970 dbgs() 6971 << "[H2S] unique free call not known to free this allocation but " 6972 << **DI->PotentialAllocationCalls.begin() << "\n"); 6973 return false; 6974 } 6975 6976 // __kmpc_alloc_shared and __kmpc_alloc_free are by construction matched. 6977 if (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared) { 6978 Instruction *CtxI = isa<InvokeInst>(AI.CB) ? AI.CB : AI.CB->getNextNode(); 6979 if (!Explorer || !Explorer->findInContextOf(UniqueFree, CtxI)) { 6980 LLVM_DEBUG(dbgs() << "[H2S] unique free call might not be executed " 6981 "with the allocation " 6982 << *UniqueFree << "\n"); 6983 return false; 6984 } 6985 } 6986 return true; 6987 }; 6988 6989 auto UsesCheck = [&](AllocationInfo &AI) { 6990 bool ValidUsesOnly = true; 6991 6992 auto Pred = [&](const Use &U, bool &Follow) -> bool { 6993 Instruction *UserI = cast<Instruction>(U.getUser()); 6994 if (isa<LoadInst>(UserI)) 6995 return true; 6996 if (auto *SI = dyn_cast<StoreInst>(UserI)) { 6997 if (SI->getValueOperand() == U.get()) { 6998 LLVM_DEBUG(dbgs() 6999 << "[H2S] escaping store to memory: " << *UserI << "\n"); 7000 ValidUsesOnly = false; 7001 } else { 7002 // A store into the malloc'ed memory is fine. 7003 } 7004 return true; 7005 } 7006 if (auto *CB = dyn_cast<CallBase>(UserI)) { 7007 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd()) 7008 return true; 7009 if (DeallocationInfos.count(CB)) { 7010 AI.PotentialFreeCalls.insert(CB); 7011 return true; 7012 } 7013 7014 unsigned ArgNo = CB->getArgOperandNo(&U); 7015 auto CBIRP = IRPosition::callsite_argument(*CB, ArgNo); 7016 7017 bool IsKnownNoCapture; 7018 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>( 7019 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoCapture); 7020 7021 // If a call site argument use is nofree, we are fine. 7022 bool IsKnownNoFree; 7023 bool IsAssumedNoFree = AA::hasAssumedIRAttr<Attribute::NoFree>( 7024 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoFree); 7025 7026 if (!IsAssumedNoCapture || 7027 (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared && 7028 !IsAssumedNoFree)) { 7029 AI.HasPotentiallyFreeingUnknownUses |= !IsAssumedNoFree; 7030 7031 // Emit a missed remark if this is missed OpenMP globalization. 7032 auto Remark = [&](OptimizationRemarkMissed ORM) { 7033 return ORM 7034 << "Could not move globalized variable to the stack. " 7035 "Variable is potentially captured in call. Mark " 7036 "parameter as `__attribute__((noescape))` to override."; 7037 }; 7038 7039 if (ValidUsesOnly && 7040 AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared) 7041 A.emitRemark<OptimizationRemarkMissed>(CB, "OMP113", Remark); 7042 7043 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n"); 7044 ValidUsesOnly = false; 7045 } 7046 return true; 7047 } 7048 7049 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) || 7050 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) { 7051 Follow = true; 7052 return true; 7053 } 7054 // Unknown user for which we can not track uses further (in a way that 7055 // makes sense). 7056 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n"); 7057 ValidUsesOnly = false; 7058 return true; 7059 }; 7060 if (!A.checkForAllUses(Pred, *this, *AI.CB, /* CheckBBLivenessOnly */ false, 7061 DepClassTy::OPTIONAL, /* IgnoreDroppableUses */ true, 7062 [&](const Use &OldU, const Use &NewU) { 7063 auto *SI = dyn_cast<StoreInst>(OldU.getUser()); 7064 return !SI || StackIsAccessibleByOtherThreads || 7065 AA::isAssumedThreadLocalObject( 7066 A, *SI->getPointerOperand(), *this); 7067 })) 7068 return false; 7069 return ValidUsesOnly; 7070 }; 7071 7072 // The actual update starts here. We look at all allocations and depending on 7073 // their status perform the appropriate check(s). 7074 for (auto &It : AllocationInfos) { 7075 AllocationInfo &AI = *It.second; 7076 if (AI.Status == AllocationInfo::INVALID) 7077 continue; 7078 7079 if (Value *Align = getAllocAlignment(AI.CB, TLI)) { 7080 std::optional<APInt> APAlign = getAPInt(A, *this, *Align); 7081 if (!APAlign) { 7082 // Can't generate an alloca which respects the required alignment 7083 // on the allocation. 7084 LLVM_DEBUG(dbgs() << "[H2S] Unknown allocation alignment: " << *AI.CB 7085 << "\n"); 7086 AI.Status = AllocationInfo::INVALID; 7087 Changed = ChangeStatus::CHANGED; 7088 continue; 7089 } 7090 if (APAlign->ugt(llvm::Value::MaximumAlignment) || 7091 !APAlign->isPowerOf2()) { 7092 LLVM_DEBUG(dbgs() << "[H2S] Invalid allocation alignment: " << APAlign 7093 << "\n"); 7094 AI.Status = AllocationInfo::INVALID; 7095 Changed = ChangeStatus::CHANGED; 7096 continue; 7097 } 7098 } 7099 7100 std::optional<APInt> Size = getSize(A, *this, AI); 7101 if (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared && 7102 MaxHeapToStackSize != -1) { 7103 if (!Size || Size->ugt(MaxHeapToStackSize)) { 7104 LLVM_DEBUG({ 7105 if (!Size) 7106 dbgs() << "[H2S] Unknown allocation size: " << *AI.CB << "\n"; 7107 else 7108 dbgs() << "[H2S] Allocation size too large: " << *AI.CB << " vs. " 7109 << MaxHeapToStackSize << "\n"; 7110 }); 7111 7112 AI.Status = AllocationInfo::INVALID; 7113 Changed = ChangeStatus::CHANGED; 7114 continue; 7115 } 7116 } 7117 7118 switch (AI.Status) { 7119 case AllocationInfo::STACK_DUE_TO_USE: 7120 if (UsesCheck(AI)) 7121 break; 7122 AI.Status = AllocationInfo::STACK_DUE_TO_FREE; 7123 [[fallthrough]]; 7124 case AllocationInfo::STACK_DUE_TO_FREE: 7125 if (FreeCheck(AI)) 7126 break; 7127 AI.Status = AllocationInfo::INVALID; 7128 Changed = ChangeStatus::CHANGED; 7129 break; 7130 case AllocationInfo::INVALID: 7131 llvm_unreachable("Invalid allocations should never reach this point!"); 7132 }; 7133 7134 // Check if we still think we can move it into the entry block. If the 7135 // alloca comes from a converted __kmpc_alloc_shared then we can usually 7136 // ignore the potential compilations associated with loops. 7137 bool IsGlobalizedLocal = 7138 AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared; 7139 if (AI.MoveAllocaIntoEntry && 7140 (!Size.has_value() || 7141 (!IsGlobalizedLocal && IsInLoop(*AI.CB->getParent())))) 7142 AI.MoveAllocaIntoEntry = false; 7143 } 7144 7145 return Changed; 7146 } 7147 } // namespace 7148 7149 /// ----------------------- Privatizable Pointers ------------------------------ 7150 namespace { 7151 struct AAPrivatizablePtrImpl : public AAPrivatizablePtr { 7152 AAPrivatizablePtrImpl(const IRPosition &IRP, Attributor &A) 7153 : AAPrivatizablePtr(IRP, A), PrivatizableType(std::nullopt) {} 7154 7155 ChangeStatus indicatePessimisticFixpoint() override { 7156 AAPrivatizablePtr::indicatePessimisticFixpoint(); 7157 PrivatizableType = nullptr; 7158 return ChangeStatus::CHANGED; 7159 } 7160 7161 /// Identify the type we can chose for a private copy of the underlying 7162 /// argument. std::nullopt means it is not clear yet, nullptr means there is 7163 /// none. 7164 virtual std::optional<Type *> identifyPrivatizableType(Attributor &A) = 0; 7165 7166 /// Return a privatizable type that encloses both T0 and T1. 7167 /// TODO: This is merely a stub for now as we should manage a mapping as well. 7168 std::optional<Type *> combineTypes(std::optional<Type *> T0, 7169 std::optional<Type *> T1) { 7170 if (!T0) 7171 return T1; 7172 if (!T1) 7173 return T0; 7174 if (T0 == T1) 7175 return T0; 7176 return nullptr; 7177 } 7178 7179 std::optional<Type *> getPrivatizableType() const override { 7180 return PrivatizableType; 7181 } 7182 7183 const std::string getAsStr(Attributor *A) const override { 7184 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]"; 7185 } 7186 7187 protected: 7188 std::optional<Type *> PrivatizableType; 7189 }; 7190 7191 // TODO: Do this for call site arguments (probably also other values) as well. 7192 7193 struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl { 7194 AAPrivatizablePtrArgument(const IRPosition &IRP, Attributor &A) 7195 : AAPrivatizablePtrImpl(IRP, A) {} 7196 7197 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...) 7198 std::optional<Type *> identifyPrivatizableType(Attributor &A) override { 7199 // If this is a byval argument and we know all the call sites (so we can 7200 // rewrite them), there is no need to check them explicitly. 7201 bool UsedAssumedInformation = false; 7202 SmallVector<Attribute, 1> Attrs; 7203 A.getAttrs(getIRPosition(), {Attribute::ByVal}, Attrs, 7204 /* IgnoreSubsumingPositions */ true); 7205 if (!Attrs.empty() && 7206 A.checkForAllCallSites([](AbstractCallSite ACS) { return true; }, *this, 7207 true, UsedAssumedInformation)) 7208 return Attrs[0].getValueAsType(); 7209 7210 std::optional<Type *> Ty; 7211 unsigned ArgNo = getIRPosition().getCallSiteArgNo(); 7212 7213 // Make sure the associated call site argument has the same type at all call 7214 // sites and it is an allocation we know is safe to privatize, for now that 7215 // means we only allow alloca instructions. 7216 // TODO: We can additionally analyze the accesses in the callee to create 7217 // the type from that information instead. That is a little more 7218 // involved and will be done in a follow up patch. 7219 auto CallSiteCheck = [&](AbstractCallSite ACS) { 7220 IRPosition ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo); 7221 // Check if a coresponding argument was found or if it is one not 7222 // associated (which can happen for callback calls). 7223 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID) 7224 return false; 7225 7226 // Check that all call sites agree on a type. 7227 auto *PrivCSArgAA = 7228 A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos, DepClassTy::REQUIRED); 7229 if (!PrivCSArgAA) 7230 return false; 7231 std::optional<Type *> CSTy = PrivCSArgAA->getPrivatizableType(); 7232 7233 LLVM_DEBUG({ 7234 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: "; 7235 if (CSTy && *CSTy) 7236 (*CSTy)->print(dbgs()); 7237 else if (CSTy) 7238 dbgs() << "<nullptr>"; 7239 else 7240 dbgs() << "<none>"; 7241 }); 7242 7243 Ty = combineTypes(Ty, CSTy); 7244 7245 LLVM_DEBUG({ 7246 dbgs() << " : New Type: "; 7247 if (Ty && *Ty) 7248 (*Ty)->print(dbgs()); 7249 else if (Ty) 7250 dbgs() << "<nullptr>"; 7251 else 7252 dbgs() << "<none>"; 7253 dbgs() << "\n"; 7254 }); 7255 7256 return !Ty || *Ty; 7257 }; 7258 7259 if (!A.checkForAllCallSites(CallSiteCheck, *this, true, 7260 UsedAssumedInformation)) 7261 return nullptr; 7262 return Ty; 7263 } 7264 7265 /// See AbstractAttribute::updateImpl(...). 7266 ChangeStatus updateImpl(Attributor &A) override { 7267 PrivatizableType = identifyPrivatizableType(A); 7268 if (!PrivatizableType) 7269 return ChangeStatus::UNCHANGED; 7270 if (!*PrivatizableType) 7271 return indicatePessimisticFixpoint(); 7272 7273 // The dependence is optional so we don't give up once we give up on the 7274 // alignment. 7275 A.getAAFor<AAAlign>(*this, IRPosition::value(getAssociatedValue()), 7276 DepClassTy::OPTIONAL); 7277 7278 // Avoid arguments with padding for now. 7279 if (!A.hasAttr(getIRPosition(), Attribute::ByVal) && 7280 !isDenselyPacked(*PrivatizableType, A.getInfoCache().getDL())) { 7281 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n"); 7282 return indicatePessimisticFixpoint(); 7283 } 7284 7285 // Collect the types that will replace the privatizable type in the function 7286 // signature. 7287 SmallVector<Type *, 16> ReplacementTypes; 7288 identifyReplacementTypes(*PrivatizableType, ReplacementTypes); 7289 7290 // Verify callee and caller agree on how the promoted argument would be 7291 // passed. 7292 Function &Fn = *getIRPosition().getAnchorScope(); 7293 const auto *TTI = 7294 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn); 7295 if (!TTI) { 7296 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Missing TTI for function " 7297 << Fn.getName() << "\n"); 7298 return indicatePessimisticFixpoint(); 7299 } 7300 7301 auto CallSiteCheck = [&](AbstractCallSite ACS) { 7302 CallBase *CB = ACS.getInstruction(); 7303 return TTI->areTypesABICompatible( 7304 CB->getCaller(), 7305 dyn_cast_if_present<Function>(CB->getCalledOperand()), 7306 ReplacementTypes); 7307 }; 7308 bool UsedAssumedInformation = false; 7309 if (!A.checkForAllCallSites(CallSiteCheck, *this, true, 7310 UsedAssumedInformation)) { 7311 LLVM_DEBUG( 7312 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for " 7313 << Fn.getName() << "\n"); 7314 return indicatePessimisticFixpoint(); 7315 } 7316 7317 // Register a rewrite of the argument. 7318 Argument *Arg = getAssociatedArgument(); 7319 if (!A.isValidFunctionSignatureRewrite(*Arg, ReplacementTypes)) { 7320 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n"); 7321 return indicatePessimisticFixpoint(); 7322 } 7323 7324 unsigned ArgNo = Arg->getArgNo(); 7325 7326 // Helper to check if for the given call site the associated argument is 7327 // passed to a callback where the privatization would be different. 7328 auto IsCompatiblePrivArgOfCallback = [&](CallBase &CB) { 7329 SmallVector<const Use *, 4> CallbackUses; 7330 AbstractCallSite::getCallbackUses(CB, CallbackUses); 7331 for (const Use *U : CallbackUses) { 7332 AbstractCallSite CBACS(U); 7333 assert(CBACS && CBACS.isCallbackCall()); 7334 for (Argument &CBArg : CBACS.getCalledFunction()->args()) { 7335 int CBArgNo = CBACS.getCallArgOperandNo(CBArg); 7336 7337 LLVM_DEBUG({ 7338 dbgs() 7339 << "[AAPrivatizablePtr] Argument " << *Arg 7340 << "check if can be privatized in the context of its parent (" 7341 << Arg->getParent()->getName() 7342 << ")\n[AAPrivatizablePtr] because it is an argument in a " 7343 "callback (" 7344 << CBArgNo << "@" << CBACS.getCalledFunction()->getName() 7345 << ")\n[AAPrivatizablePtr] " << CBArg << " : " 7346 << CBACS.getCallArgOperand(CBArg) << " vs " 7347 << CB.getArgOperand(ArgNo) << "\n" 7348 << "[AAPrivatizablePtr] " << CBArg << " : " 7349 << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n"; 7350 }); 7351 7352 if (CBArgNo != int(ArgNo)) 7353 continue; 7354 const auto *CBArgPrivAA = A.getAAFor<AAPrivatizablePtr>( 7355 *this, IRPosition::argument(CBArg), DepClassTy::REQUIRED); 7356 if (CBArgPrivAA && CBArgPrivAA->isValidState()) { 7357 auto CBArgPrivTy = CBArgPrivAA->getPrivatizableType(); 7358 if (!CBArgPrivTy) 7359 continue; 7360 if (*CBArgPrivTy == PrivatizableType) 7361 continue; 7362 } 7363 7364 LLVM_DEBUG({ 7365 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg 7366 << " cannot be privatized in the context of its parent (" 7367 << Arg->getParent()->getName() 7368 << ")\n[AAPrivatizablePtr] because it is an argument in a " 7369 "callback (" 7370 << CBArgNo << "@" << CBACS.getCalledFunction()->getName() 7371 << ").\n[AAPrivatizablePtr] for which the argument " 7372 "privatization is not compatible.\n"; 7373 }); 7374 return false; 7375 } 7376 } 7377 return true; 7378 }; 7379 7380 // Helper to check if for the given call site the associated argument is 7381 // passed to a direct call where the privatization would be different. 7382 auto IsCompatiblePrivArgOfDirectCS = [&](AbstractCallSite ACS) { 7383 CallBase *DC = cast<CallBase>(ACS.getInstruction()); 7384 int DCArgNo = ACS.getCallArgOperandNo(ArgNo); 7385 assert(DCArgNo >= 0 && unsigned(DCArgNo) < DC->arg_size() && 7386 "Expected a direct call operand for callback call operand"); 7387 7388 Function *DCCallee = 7389 dyn_cast_if_present<Function>(DC->getCalledOperand()); 7390 LLVM_DEBUG({ 7391 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg 7392 << " check if be privatized in the context of its parent (" 7393 << Arg->getParent()->getName() 7394 << ")\n[AAPrivatizablePtr] because it is an argument in a " 7395 "direct call of (" 7396 << DCArgNo << "@" << DCCallee->getName() << ").\n"; 7397 }); 7398 7399 if (unsigned(DCArgNo) < DCCallee->arg_size()) { 7400 const auto *DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>( 7401 *this, IRPosition::argument(*DCCallee->getArg(DCArgNo)), 7402 DepClassTy::REQUIRED); 7403 if (DCArgPrivAA && DCArgPrivAA->isValidState()) { 7404 auto DCArgPrivTy = DCArgPrivAA->getPrivatizableType(); 7405 if (!DCArgPrivTy) 7406 return true; 7407 if (*DCArgPrivTy == PrivatizableType) 7408 return true; 7409 } 7410 } 7411 7412 LLVM_DEBUG({ 7413 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg 7414 << " cannot be privatized in the context of its parent (" 7415 << Arg->getParent()->getName() 7416 << ")\n[AAPrivatizablePtr] because it is an argument in a " 7417 "direct call of (" 7418 << ACS.getInstruction()->getCalledOperand()->getName() 7419 << ").\n[AAPrivatizablePtr] for which the argument " 7420 "privatization is not compatible.\n"; 7421 }); 7422 return false; 7423 }; 7424 7425 // Helper to check if the associated argument is used at the given abstract 7426 // call site in a way that is incompatible with the privatization assumed 7427 // here. 7428 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) { 7429 if (ACS.isDirectCall()) 7430 return IsCompatiblePrivArgOfCallback(*ACS.getInstruction()); 7431 if (ACS.isCallbackCall()) 7432 return IsCompatiblePrivArgOfDirectCS(ACS); 7433 return false; 7434 }; 7435 7436 if (!A.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite, *this, true, 7437 UsedAssumedInformation)) 7438 return indicatePessimisticFixpoint(); 7439 7440 return ChangeStatus::UNCHANGED; 7441 } 7442 7443 /// Given a type to private \p PrivType, collect the constituates (which are 7444 /// used) in \p ReplacementTypes. 7445 static void 7446 identifyReplacementTypes(Type *PrivType, 7447 SmallVectorImpl<Type *> &ReplacementTypes) { 7448 // TODO: For now we expand the privatization type to the fullest which can 7449 // lead to dead arguments that need to be removed later. 7450 assert(PrivType && "Expected privatizable type!"); 7451 7452 // Traverse the type, extract constituate types on the outermost level. 7453 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) { 7454 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) 7455 ReplacementTypes.push_back(PrivStructType->getElementType(u)); 7456 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) { 7457 ReplacementTypes.append(PrivArrayType->getNumElements(), 7458 PrivArrayType->getElementType()); 7459 } else { 7460 ReplacementTypes.push_back(PrivType); 7461 } 7462 } 7463 7464 /// Initialize \p Base according to the type \p PrivType at position \p IP. 7465 /// The values needed are taken from the arguments of \p F starting at 7466 /// position \p ArgNo. 7467 static void createInitialization(Type *PrivType, Value &Base, Function &F, 7468 unsigned ArgNo, BasicBlock::iterator IP) { 7469 assert(PrivType && "Expected privatizable type!"); 7470 7471 IRBuilder<NoFolder> IRB(IP->getParent(), IP); 7472 const DataLayout &DL = F.getDataLayout(); 7473 7474 // Traverse the type, build GEPs and stores. 7475 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) { 7476 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType); 7477 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) { 7478 Value *Ptr = 7479 constructPointer(&Base, PrivStructLayout->getElementOffset(u), IRB); 7480 new StoreInst(F.getArg(ArgNo + u), Ptr, IP); 7481 } 7482 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) { 7483 Type *PointeeTy = PrivArrayType->getElementType(); 7484 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy); 7485 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) { 7486 Value *Ptr = constructPointer(&Base, u * PointeeTySize, IRB); 7487 new StoreInst(F.getArg(ArgNo + u), Ptr, IP); 7488 } 7489 } else { 7490 new StoreInst(F.getArg(ArgNo), &Base, IP); 7491 } 7492 } 7493 7494 /// Extract values from \p Base according to the type \p PrivType at the 7495 /// call position \p ACS. The values are appended to \p ReplacementValues. 7496 void createReplacementValues(Align Alignment, Type *PrivType, 7497 AbstractCallSite ACS, Value *Base, 7498 SmallVectorImpl<Value *> &ReplacementValues) { 7499 assert(Base && "Expected base value!"); 7500 assert(PrivType && "Expected privatizable type!"); 7501 Instruction *IP = ACS.getInstruction(); 7502 7503 IRBuilder<NoFolder> IRB(IP); 7504 const DataLayout &DL = IP->getDataLayout(); 7505 7506 // Traverse the type, build GEPs and loads. 7507 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) { 7508 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType); 7509 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) { 7510 Type *PointeeTy = PrivStructType->getElementType(u); 7511 Value *Ptr = 7512 constructPointer(Base, PrivStructLayout->getElementOffset(u), IRB); 7513 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator()); 7514 L->setAlignment(Alignment); 7515 ReplacementValues.push_back(L); 7516 } 7517 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) { 7518 Type *PointeeTy = PrivArrayType->getElementType(); 7519 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy); 7520 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) { 7521 Value *Ptr = constructPointer(Base, u * PointeeTySize, IRB); 7522 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator()); 7523 L->setAlignment(Alignment); 7524 ReplacementValues.push_back(L); 7525 } 7526 } else { 7527 LoadInst *L = new LoadInst(PrivType, Base, "", IP->getIterator()); 7528 L->setAlignment(Alignment); 7529 ReplacementValues.push_back(L); 7530 } 7531 } 7532 7533 /// See AbstractAttribute::manifest(...) 7534 ChangeStatus manifest(Attributor &A) override { 7535 if (!PrivatizableType) 7536 return ChangeStatus::UNCHANGED; 7537 assert(*PrivatizableType && "Expected privatizable type!"); 7538 7539 // Collect all tail calls in the function as we cannot allow new allocas to 7540 // escape into tail recursion. 7541 // TODO: Be smarter about new allocas escaping into tail calls. 7542 SmallVector<CallInst *, 16> TailCalls; 7543 bool UsedAssumedInformation = false; 7544 if (!A.checkForAllInstructions( 7545 [&](Instruction &I) { 7546 CallInst &CI = cast<CallInst>(I); 7547 if (CI.isTailCall()) 7548 TailCalls.push_back(&CI); 7549 return true; 7550 }, 7551 *this, {Instruction::Call}, UsedAssumedInformation)) 7552 return ChangeStatus::UNCHANGED; 7553 7554 Argument *Arg = getAssociatedArgument(); 7555 // Query AAAlign attribute for alignment of associated argument to 7556 // determine the best alignment of loads. 7557 const auto *AlignAA = 7558 A.getAAFor<AAAlign>(*this, IRPosition::value(*Arg), DepClassTy::NONE); 7559 7560 // Callback to repair the associated function. A new alloca is placed at the 7561 // beginning and initialized with the values passed through arguments. The 7562 // new alloca replaces the use of the old pointer argument. 7563 Attributor::ArgumentReplacementInfo::CalleeRepairCBTy FnRepairCB = 7564 [=](const Attributor::ArgumentReplacementInfo &ARI, 7565 Function &ReplacementFn, Function::arg_iterator ArgIt) { 7566 BasicBlock &EntryBB = ReplacementFn.getEntryBlock(); 7567 BasicBlock::iterator IP = EntryBB.getFirstInsertionPt(); 7568 const DataLayout &DL = IP->getDataLayout(); 7569 unsigned AS = DL.getAllocaAddrSpace(); 7570 Instruction *AI = new AllocaInst(*PrivatizableType, AS, 7571 Arg->getName() + ".priv", IP); 7572 createInitialization(*PrivatizableType, *AI, ReplacementFn, 7573 ArgIt->getArgNo(), IP); 7574 7575 if (AI->getType() != Arg->getType()) 7576 AI = BitCastInst::CreatePointerBitCastOrAddrSpaceCast( 7577 AI, Arg->getType(), "", IP); 7578 Arg->replaceAllUsesWith(AI); 7579 7580 for (CallInst *CI : TailCalls) 7581 CI->setTailCall(false); 7582 }; 7583 7584 // Callback to repair a call site of the associated function. The elements 7585 // of the privatizable type are loaded prior to the call and passed to the 7586 // new function version. 7587 Attributor::ArgumentReplacementInfo::ACSRepairCBTy ACSRepairCB = 7588 [=](const Attributor::ArgumentReplacementInfo &ARI, 7589 AbstractCallSite ACS, SmallVectorImpl<Value *> &NewArgOperands) { 7590 // When no alignment is specified for the load instruction, 7591 // natural alignment is assumed. 7592 createReplacementValues( 7593 AlignAA ? AlignAA->getAssumedAlign() : Align(0), 7594 *PrivatizableType, ACS, 7595 ACS.getCallArgOperand(ARI.getReplacedArg().getArgNo()), 7596 NewArgOperands); 7597 }; 7598 7599 // Collect the types that will replace the privatizable type in the function 7600 // signature. 7601 SmallVector<Type *, 16> ReplacementTypes; 7602 identifyReplacementTypes(*PrivatizableType, ReplacementTypes); 7603 7604 // Register a rewrite of the argument. 7605 if (A.registerFunctionSignatureRewrite(*Arg, ReplacementTypes, 7606 std::move(FnRepairCB), 7607 std::move(ACSRepairCB))) 7608 return ChangeStatus::CHANGED; 7609 return ChangeStatus::UNCHANGED; 7610 } 7611 7612 /// See AbstractAttribute::trackStatistics() 7613 void trackStatistics() const override { 7614 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr); 7615 } 7616 }; 7617 7618 struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl { 7619 AAPrivatizablePtrFloating(const IRPosition &IRP, Attributor &A) 7620 : AAPrivatizablePtrImpl(IRP, A) {} 7621 7622 /// See AbstractAttribute::initialize(...). 7623 void initialize(Attributor &A) override { 7624 // TODO: We can privatize more than arguments. 7625 indicatePessimisticFixpoint(); 7626 } 7627 7628 ChangeStatus updateImpl(Attributor &A) override { 7629 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::" 7630 "updateImpl will not be called"); 7631 } 7632 7633 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...) 7634 std::optional<Type *> identifyPrivatizableType(Attributor &A) override { 7635 Value *Obj = getUnderlyingObject(&getAssociatedValue()); 7636 if (!Obj) { 7637 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n"); 7638 return nullptr; 7639 } 7640 7641 if (auto *AI = dyn_cast<AllocaInst>(Obj)) 7642 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize())) 7643 if (CI->isOne()) 7644 return AI->getAllocatedType(); 7645 if (auto *Arg = dyn_cast<Argument>(Obj)) { 7646 auto *PrivArgAA = A.getAAFor<AAPrivatizablePtr>( 7647 *this, IRPosition::argument(*Arg), DepClassTy::REQUIRED); 7648 if (PrivArgAA && PrivArgAA->isAssumedPrivatizablePtr()) 7649 return PrivArgAA->getPrivatizableType(); 7650 } 7651 7652 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid " 7653 "alloca nor privatizable argument: " 7654 << *Obj << "!\n"); 7655 return nullptr; 7656 } 7657 7658 /// See AbstractAttribute::trackStatistics() 7659 void trackStatistics() const override { 7660 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr); 7661 } 7662 }; 7663 7664 struct AAPrivatizablePtrCallSiteArgument final 7665 : public AAPrivatizablePtrFloating { 7666 AAPrivatizablePtrCallSiteArgument(const IRPosition &IRP, Attributor &A) 7667 : AAPrivatizablePtrFloating(IRP, A) {} 7668 7669 /// See AbstractAttribute::initialize(...). 7670 void initialize(Attributor &A) override { 7671 if (A.hasAttr(getIRPosition(), Attribute::ByVal)) 7672 indicateOptimisticFixpoint(); 7673 } 7674 7675 /// See AbstractAttribute::updateImpl(...). 7676 ChangeStatus updateImpl(Attributor &A) override { 7677 PrivatizableType = identifyPrivatizableType(A); 7678 if (!PrivatizableType) 7679 return ChangeStatus::UNCHANGED; 7680 if (!*PrivatizableType) 7681 return indicatePessimisticFixpoint(); 7682 7683 const IRPosition &IRP = getIRPosition(); 7684 bool IsKnownNoCapture; 7685 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>( 7686 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoCapture); 7687 if (!IsAssumedNoCapture) { 7688 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n"); 7689 return indicatePessimisticFixpoint(); 7690 } 7691 7692 bool IsKnownNoAlias; 7693 if (!AA::hasAssumedIRAttr<Attribute::NoAlias>( 7694 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoAlias)) { 7695 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n"); 7696 return indicatePessimisticFixpoint(); 7697 } 7698 7699 bool IsKnown; 7700 if (!AA::isAssumedReadOnly(A, IRP, *this, IsKnown)) { 7701 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n"); 7702 return indicatePessimisticFixpoint(); 7703 } 7704 7705 return ChangeStatus::UNCHANGED; 7706 } 7707 7708 /// See AbstractAttribute::trackStatistics() 7709 void trackStatistics() const override { 7710 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr); 7711 } 7712 }; 7713 7714 struct AAPrivatizablePtrCallSiteReturned final 7715 : public AAPrivatizablePtrFloating { 7716 AAPrivatizablePtrCallSiteReturned(const IRPosition &IRP, Attributor &A) 7717 : AAPrivatizablePtrFloating(IRP, A) {} 7718 7719 /// See AbstractAttribute::initialize(...). 7720 void initialize(Attributor &A) override { 7721 // TODO: We can privatize more than arguments. 7722 indicatePessimisticFixpoint(); 7723 } 7724 7725 /// See AbstractAttribute::trackStatistics() 7726 void trackStatistics() const override { 7727 STATS_DECLTRACK_CSRET_ATTR(privatizable_ptr); 7728 } 7729 }; 7730 7731 struct AAPrivatizablePtrReturned final : public AAPrivatizablePtrFloating { 7732 AAPrivatizablePtrReturned(const IRPosition &IRP, Attributor &A) 7733 : AAPrivatizablePtrFloating(IRP, A) {} 7734 7735 /// See AbstractAttribute::initialize(...). 7736 void initialize(Attributor &A) override { 7737 // TODO: We can privatize more than arguments. 7738 indicatePessimisticFixpoint(); 7739 } 7740 7741 /// See AbstractAttribute::trackStatistics() 7742 void trackStatistics() const override { 7743 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr); 7744 } 7745 }; 7746 } // namespace 7747 7748 /// -------------------- Memory Behavior Attributes ---------------------------- 7749 /// Includes read-none, read-only, and write-only. 7750 /// ---------------------------------------------------------------------------- 7751 namespace { 7752 struct AAMemoryBehaviorImpl : public AAMemoryBehavior { 7753 AAMemoryBehaviorImpl(const IRPosition &IRP, Attributor &A) 7754 : AAMemoryBehavior(IRP, A) {} 7755 7756 /// See AbstractAttribute::initialize(...). 7757 void initialize(Attributor &A) override { 7758 intersectAssumedBits(BEST_STATE); 7759 getKnownStateFromValue(A, getIRPosition(), getState()); 7760 AAMemoryBehavior::initialize(A); 7761 } 7762 7763 /// Return the memory behavior information encoded in the IR for \p IRP. 7764 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP, 7765 BitIntegerState &State, 7766 bool IgnoreSubsumingPositions = false) { 7767 SmallVector<Attribute, 2> Attrs; 7768 A.getAttrs(IRP, AttrKinds, Attrs, IgnoreSubsumingPositions); 7769 for (const Attribute &Attr : Attrs) { 7770 switch (Attr.getKindAsEnum()) { 7771 case Attribute::ReadNone: 7772 State.addKnownBits(NO_ACCESSES); 7773 break; 7774 case Attribute::ReadOnly: 7775 State.addKnownBits(NO_WRITES); 7776 break; 7777 case Attribute::WriteOnly: 7778 State.addKnownBits(NO_READS); 7779 break; 7780 default: 7781 llvm_unreachable("Unexpected attribute!"); 7782 } 7783 } 7784 7785 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) { 7786 if (!I->mayReadFromMemory()) 7787 State.addKnownBits(NO_READS); 7788 if (!I->mayWriteToMemory()) 7789 State.addKnownBits(NO_WRITES); 7790 } 7791 } 7792 7793 /// See AbstractAttribute::getDeducedAttributes(...). 7794 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, 7795 SmallVectorImpl<Attribute> &Attrs) const override { 7796 assert(Attrs.size() == 0); 7797 if (isAssumedReadNone()) 7798 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone)); 7799 else if (isAssumedReadOnly()) 7800 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly)); 7801 else if (isAssumedWriteOnly()) 7802 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly)); 7803 assert(Attrs.size() <= 1); 7804 } 7805 7806 /// See AbstractAttribute::manifest(...). 7807 ChangeStatus manifest(Attributor &A) override { 7808 const IRPosition &IRP = getIRPosition(); 7809 7810 if (A.hasAttr(IRP, Attribute::ReadNone, 7811 /* IgnoreSubsumingPositions */ true)) 7812 return ChangeStatus::UNCHANGED; 7813 7814 // Check if we would improve the existing attributes first. 7815 SmallVector<Attribute, 4> DeducedAttrs; 7816 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs); 7817 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) { 7818 return A.hasAttr(IRP, Attr.getKindAsEnum(), 7819 /* IgnoreSubsumingPositions */ true); 7820 })) 7821 return ChangeStatus::UNCHANGED; 7822 7823 // Clear existing attributes. 7824 A.removeAttrs(IRP, AttrKinds); 7825 // Clear conflicting writable attribute. 7826 if (isAssumedReadOnly()) 7827 A.removeAttrs(IRP, Attribute::Writable); 7828 7829 // Use the generic manifest method. 7830 return IRAttribute::manifest(A); 7831 } 7832 7833 /// See AbstractState::getAsStr(). 7834 const std::string getAsStr(Attributor *A) const override { 7835 if (isAssumedReadNone()) 7836 return "readnone"; 7837 if (isAssumedReadOnly()) 7838 return "readonly"; 7839 if (isAssumedWriteOnly()) 7840 return "writeonly"; 7841 return "may-read/write"; 7842 } 7843 7844 /// The set of IR attributes AAMemoryBehavior deals with. 7845 static const Attribute::AttrKind AttrKinds[3]; 7846 }; 7847 7848 const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = { 7849 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly}; 7850 7851 /// Memory behavior attribute for a floating value. 7852 struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl { 7853 AAMemoryBehaviorFloating(const IRPosition &IRP, Attributor &A) 7854 : AAMemoryBehaviorImpl(IRP, A) {} 7855 7856 /// See AbstractAttribute::updateImpl(...). 7857 ChangeStatus updateImpl(Attributor &A) override; 7858 7859 /// See AbstractAttribute::trackStatistics() 7860 void trackStatistics() const override { 7861 if (isAssumedReadNone()) 7862 STATS_DECLTRACK_FLOATING_ATTR(readnone) 7863 else if (isAssumedReadOnly()) 7864 STATS_DECLTRACK_FLOATING_ATTR(readonly) 7865 else if (isAssumedWriteOnly()) 7866 STATS_DECLTRACK_FLOATING_ATTR(writeonly) 7867 } 7868 7869 private: 7870 /// Return true if users of \p UserI might access the underlying 7871 /// variable/location described by \p U and should therefore be analyzed. 7872 bool followUsersOfUseIn(Attributor &A, const Use &U, 7873 const Instruction *UserI); 7874 7875 /// Update the state according to the effect of use \p U in \p UserI. 7876 void analyzeUseIn(Attributor &A, const Use &U, const Instruction *UserI); 7877 }; 7878 7879 /// Memory behavior attribute for function argument. 7880 struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating { 7881 AAMemoryBehaviorArgument(const IRPosition &IRP, Attributor &A) 7882 : AAMemoryBehaviorFloating(IRP, A) {} 7883 7884 /// See AbstractAttribute::initialize(...). 7885 void initialize(Attributor &A) override { 7886 intersectAssumedBits(BEST_STATE); 7887 const IRPosition &IRP = getIRPosition(); 7888 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we 7889 // can query it when we use has/getAttr. That would allow us to reuse the 7890 // initialize of the base class here. 7891 bool HasByVal = A.hasAttr(IRP, {Attribute::ByVal}, 7892 /* IgnoreSubsumingPositions */ true); 7893 getKnownStateFromValue(A, IRP, getState(), 7894 /* IgnoreSubsumingPositions */ HasByVal); 7895 } 7896 7897 ChangeStatus manifest(Attributor &A) override { 7898 // TODO: Pointer arguments are not supported on vectors of pointers yet. 7899 if (!getAssociatedValue().getType()->isPointerTy()) 7900 return ChangeStatus::UNCHANGED; 7901 7902 // TODO: From readattrs.ll: "inalloca parameters are always 7903 // considered written" 7904 if (A.hasAttr(getIRPosition(), 7905 {Attribute::InAlloca, Attribute::Preallocated})) { 7906 removeKnownBits(NO_WRITES); 7907 removeAssumedBits(NO_WRITES); 7908 } 7909 A.removeAttrs(getIRPosition(), AttrKinds); 7910 return AAMemoryBehaviorFloating::manifest(A); 7911 } 7912 7913 /// See AbstractAttribute::trackStatistics() 7914 void trackStatistics() const override { 7915 if (isAssumedReadNone()) 7916 STATS_DECLTRACK_ARG_ATTR(readnone) 7917 else if (isAssumedReadOnly()) 7918 STATS_DECLTRACK_ARG_ATTR(readonly) 7919 else if (isAssumedWriteOnly()) 7920 STATS_DECLTRACK_ARG_ATTR(writeonly) 7921 } 7922 }; 7923 7924 struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument { 7925 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP, Attributor &A) 7926 : AAMemoryBehaviorArgument(IRP, A) {} 7927 7928 /// See AbstractAttribute::initialize(...). 7929 void initialize(Attributor &A) override { 7930 // If we don't have an associated attribute this is either a variadic call 7931 // or an indirect call, either way, nothing to do here. 7932 Argument *Arg = getAssociatedArgument(); 7933 if (!Arg) { 7934 indicatePessimisticFixpoint(); 7935 return; 7936 } 7937 if (Arg->hasByValAttr()) { 7938 addKnownBits(NO_WRITES); 7939 removeKnownBits(NO_READS); 7940 removeAssumedBits(NO_READS); 7941 } 7942 AAMemoryBehaviorArgument::initialize(A); 7943 if (getAssociatedFunction()->isDeclaration()) 7944 indicatePessimisticFixpoint(); 7945 } 7946 7947 /// See AbstractAttribute::updateImpl(...). 7948 ChangeStatus updateImpl(Attributor &A) override { 7949 // TODO: Once we have call site specific value information we can provide 7950 // call site specific liveness liveness information and then it makes 7951 // sense to specialize attributes for call sites arguments instead of 7952 // redirecting requests to the callee argument. 7953 Argument *Arg = getAssociatedArgument(); 7954 const IRPosition &ArgPos = IRPosition::argument(*Arg); 7955 auto *ArgAA = 7956 A.getAAFor<AAMemoryBehavior>(*this, ArgPos, DepClassTy::REQUIRED); 7957 if (!ArgAA) 7958 return indicatePessimisticFixpoint(); 7959 return clampStateAndIndicateChange(getState(), ArgAA->getState()); 7960 } 7961 7962 /// See AbstractAttribute::trackStatistics() 7963 void trackStatistics() const override { 7964 if (isAssumedReadNone()) 7965 STATS_DECLTRACK_CSARG_ATTR(readnone) 7966 else if (isAssumedReadOnly()) 7967 STATS_DECLTRACK_CSARG_ATTR(readonly) 7968 else if (isAssumedWriteOnly()) 7969 STATS_DECLTRACK_CSARG_ATTR(writeonly) 7970 } 7971 }; 7972 7973 /// Memory behavior attribute for a call site return position. 7974 struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating { 7975 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP, Attributor &A) 7976 : AAMemoryBehaviorFloating(IRP, A) {} 7977 7978 /// See AbstractAttribute::initialize(...). 7979 void initialize(Attributor &A) override { 7980 AAMemoryBehaviorImpl::initialize(A); 7981 } 7982 /// See AbstractAttribute::manifest(...). 7983 ChangeStatus manifest(Attributor &A) override { 7984 // We do not annotate returned values. 7985 return ChangeStatus::UNCHANGED; 7986 } 7987 7988 /// See AbstractAttribute::trackStatistics() 7989 void trackStatistics() const override {} 7990 }; 7991 7992 /// An AA to represent the memory behavior function attributes. 7993 struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl { 7994 AAMemoryBehaviorFunction(const IRPosition &IRP, Attributor &A) 7995 : AAMemoryBehaviorImpl(IRP, A) {} 7996 7997 /// See AbstractAttribute::updateImpl(Attributor &A). 7998 ChangeStatus updateImpl(Attributor &A) override; 7999 8000 /// See AbstractAttribute::manifest(...). 8001 ChangeStatus manifest(Attributor &A) override { 8002 // TODO: It would be better to merge this with AAMemoryLocation, so that 8003 // we could determine read/write per location. This would also have the 8004 // benefit of only one place trying to manifest the memory attribute. 8005 Function &F = cast<Function>(getAnchorValue()); 8006 MemoryEffects ME = MemoryEffects::unknown(); 8007 if (isAssumedReadNone()) 8008 ME = MemoryEffects::none(); 8009 else if (isAssumedReadOnly()) 8010 ME = MemoryEffects::readOnly(); 8011 else if (isAssumedWriteOnly()) 8012 ME = MemoryEffects::writeOnly(); 8013 8014 A.removeAttrs(getIRPosition(), AttrKinds); 8015 // Clear conflicting writable attribute. 8016 if (ME.onlyReadsMemory()) 8017 for (Argument &Arg : F.args()) 8018 A.removeAttrs(IRPosition::argument(Arg), Attribute::Writable); 8019 return A.manifestAttrs(getIRPosition(), 8020 Attribute::getWithMemoryEffects(F.getContext(), ME)); 8021 } 8022 8023 /// See AbstractAttribute::trackStatistics() 8024 void trackStatistics() const override { 8025 if (isAssumedReadNone()) 8026 STATS_DECLTRACK_FN_ATTR(readnone) 8027 else if (isAssumedReadOnly()) 8028 STATS_DECLTRACK_FN_ATTR(readonly) 8029 else if (isAssumedWriteOnly()) 8030 STATS_DECLTRACK_FN_ATTR(writeonly) 8031 } 8032 }; 8033 8034 /// AAMemoryBehavior attribute for call sites. 8035 struct AAMemoryBehaviorCallSite final 8036 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl> { 8037 AAMemoryBehaviorCallSite(const IRPosition &IRP, Attributor &A) 8038 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl>(IRP, A) {} 8039 8040 /// See AbstractAttribute::manifest(...). 8041 ChangeStatus manifest(Attributor &A) override { 8042 // TODO: Deduplicate this with AAMemoryBehaviorFunction. 8043 CallBase &CB = cast<CallBase>(getAnchorValue()); 8044 MemoryEffects ME = MemoryEffects::unknown(); 8045 if (isAssumedReadNone()) 8046 ME = MemoryEffects::none(); 8047 else if (isAssumedReadOnly()) 8048 ME = MemoryEffects::readOnly(); 8049 else if (isAssumedWriteOnly()) 8050 ME = MemoryEffects::writeOnly(); 8051 8052 A.removeAttrs(getIRPosition(), AttrKinds); 8053 // Clear conflicting writable attribute. 8054 if (ME.onlyReadsMemory()) 8055 for (Use &U : CB.args()) 8056 A.removeAttrs(IRPosition::callsite_argument(CB, U.getOperandNo()), 8057 Attribute::Writable); 8058 return A.manifestAttrs( 8059 getIRPosition(), Attribute::getWithMemoryEffects(CB.getContext(), ME)); 8060 } 8061 8062 /// See AbstractAttribute::trackStatistics() 8063 void trackStatistics() const override { 8064 if (isAssumedReadNone()) 8065 STATS_DECLTRACK_CS_ATTR(readnone) 8066 else if (isAssumedReadOnly()) 8067 STATS_DECLTRACK_CS_ATTR(readonly) 8068 else if (isAssumedWriteOnly()) 8069 STATS_DECLTRACK_CS_ATTR(writeonly) 8070 } 8071 }; 8072 8073 ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) { 8074 8075 // The current assumed state used to determine a change. 8076 auto AssumedState = getAssumed(); 8077 8078 auto CheckRWInst = [&](Instruction &I) { 8079 // If the instruction has an own memory behavior state, use it to restrict 8080 // the local state. No further analysis is required as the other memory 8081 // state is as optimistic as it gets. 8082 if (const auto *CB = dyn_cast<CallBase>(&I)) { 8083 const auto *MemBehaviorAA = A.getAAFor<AAMemoryBehavior>( 8084 *this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED); 8085 if (MemBehaviorAA) { 8086 intersectAssumedBits(MemBehaviorAA->getAssumed()); 8087 return !isAtFixpoint(); 8088 } 8089 } 8090 8091 // Remove access kind modifiers if necessary. 8092 if (I.mayReadFromMemory()) 8093 removeAssumedBits(NO_READS); 8094 if (I.mayWriteToMemory()) 8095 removeAssumedBits(NO_WRITES); 8096 return !isAtFixpoint(); 8097 }; 8098 8099 bool UsedAssumedInformation = false; 8100 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this, 8101 UsedAssumedInformation)) 8102 return indicatePessimisticFixpoint(); 8103 8104 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED 8105 : ChangeStatus::UNCHANGED; 8106 } 8107 8108 ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) { 8109 8110 const IRPosition &IRP = getIRPosition(); 8111 const IRPosition &FnPos = IRPosition::function_scope(IRP); 8112 AAMemoryBehavior::StateType &S = getState(); 8113 8114 // First, check the function scope. We take the known information and we avoid 8115 // work if the assumed information implies the current assumed information for 8116 // this attribute. This is a valid for all but byval arguments. 8117 Argument *Arg = IRP.getAssociatedArgument(); 8118 AAMemoryBehavior::base_t FnMemAssumedState = 8119 AAMemoryBehavior::StateType::getWorstState(); 8120 if (!Arg || !Arg->hasByValAttr()) { 8121 const auto *FnMemAA = 8122 A.getAAFor<AAMemoryBehavior>(*this, FnPos, DepClassTy::OPTIONAL); 8123 if (FnMemAA) { 8124 FnMemAssumedState = FnMemAA->getAssumed(); 8125 S.addKnownBits(FnMemAA->getKnown()); 8126 if ((S.getAssumed() & FnMemAA->getAssumed()) == S.getAssumed()) 8127 return ChangeStatus::UNCHANGED; 8128 } 8129 } 8130 8131 // The current assumed state used to determine a change. 8132 auto AssumedState = S.getAssumed(); 8133 8134 // Make sure the value is not captured (except through "return"), if 8135 // it is, any information derived would be irrelevant anyway as we cannot 8136 // check the potential aliases introduced by the capture. However, no need 8137 // to fall back to anythign less optimistic than the function state. 8138 bool IsKnownNoCapture; 8139 const AANoCapture *ArgNoCaptureAA = nullptr; 8140 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::NoCapture>( 8141 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture, false, 8142 &ArgNoCaptureAA); 8143 8144 if (!IsAssumedNoCapture && 8145 (!ArgNoCaptureAA || !ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned())) { 8146 S.intersectAssumedBits(FnMemAssumedState); 8147 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED 8148 : ChangeStatus::UNCHANGED; 8149 } 8150 8151 // Visit and expand uses until all are analyzed or a fixpoint is reached. 8152 auto UsePred = [&](const Use &U, bool &Follow) -> bool { 8153 Instruction *UserI = cast<Instruction>(U.getUser()); 8154 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << *U << " in " << *UserI 8155 << " \n"); 8156 8157 // Droppable users, e.g., llvm::assume does not actually perform any action. 8158 if (UserI->isDroppable()) 8159 return true; 8160 8161 // Check if the users of UserI should also be visited. 8162 Follow = followUsersOfUseIn(A, U, UserI); 8163 8164 // If UserI might touch memory we analyze the use in detail. 8165 if (UserI->mayReadOrWriteMemory()) 8166 analyzeUseIn(A, U, UserI); 8167 8168 return !isAtFixpoint(); 8169 }; 8170 8171 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) 8172 return indicatePessimisticFixpoint(); 8173 8174 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED 8175 : ChangeStatus::UNCHANGED; 8176 } 8177 8178 bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use &U, 8179 const Instruction *UserI) { 8180 // The loaded value is unrelated to the pointer argument, no need to 8181 // follow the users of the load. 8182 if (isa<LoadInst>(UserI) || isa<ReturnInst>(UserI)) 8183 return false; 8184 8185 // By default we follow all uses assuming UserI might leak information on U, 8186 // we have special handling for call sites operands though. 8187 const auto *CB = dyn_cast<CallBase>(UserI); 8188 if (!CB || !CB->isArgOperand(&U)) 8189 return true; 8190 8191 // If the use is a call argument known not to be captured, the users of 8192 // the call do not need to be visited because they have to be unrelated to 8193 // the input. Note that this check is not trivial even though we disallow 8194 // general capturing of the underlying argument. The reason is that the 8195 // call might the argument "through return", which we allow and for which we 8196 // need to check call users. 8197 if (U.get()->getType()->isPointerTy()) { 8198 unsigned ArgNo = CB->getArgOperandNo(&U); 8199 bool IsKnownNoCapture; 8200 return !AA::hasAssumedIRAttr<Attribute::NoCapture>( 8201 A, this, IRPosition::callsite_argument(*CB, ArgNo), 8202 DepClassTy::OPTIONAL, IsKnownNoCapture); 8203 } 8204 8205 return true; 8206 } 8207 8208 void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use &U, 8209 const Instruction *UserI) { 8210 assert(UserI->mayReadOrWriteMemory()); 8211 8212 switch (UserI->getOpcode()) { 8213 default: 8214 // TODO: Handle all atomics and other side-effect operations we know of. 8215 break; 8216 case Instruction::Load: 8217 // Loads cause the NO_READS property to disappear. 8218 removeAssumedBits(NO_READS); 8219 return; 8220 8221 case Instruction::Store: 8222 // Stores cause the NO_WRITES property to disappear if the use is the 8223 // pointer operand. Note that while capturing was taken care of somewhere 8224 // else we need to deal with stores of the value that is not looked through. 8225 if (cast<StoreInst>(UserI)->getPointerOperand() == U.get()) 8226 removeAssumedBits(NO_WRITES); 8227 else 8228 indicatePessimisticFixpoint(); 8229 return; 8230 8231 case Instruction::Call: 8232 case Instruction::CallBr: 8233 case Instruction::Invoke: { 8234 // For call sites we look at the argument memory behavior attribute (this 8235 // could be recursive!) in order to restrict our own state. 8236 const auto *CB = cast<CallBase>(UserI); 8237 8238 // Give up on operand bundles. 8239 if (CB->isBundleOperand(&U)) { 8240 indicatePessimisticFixpoint(); 8241 return; 8242 } 8243 8244 // Calling a function does read the function pointer, maybe write it if the 8245 // function is self-modifying. 8246 if (CB->isCallee(&U)) { 8247 removeAssumedBits(NO_READS); 8248 break; 8249 } 8250 8251 // Adjust the possible access behavior based on the information on the 8252 // argument. 8253 IRPosition Pos; 8254 if (U.get()->getType()->isPointerTy()) 8255 Pos = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U)); 8256 else 8257 Pos = IRPosition::callsite_function(*CB); 8258 const auto *MemBehaviorAA = 8259 A.getAAFor<AAMemoryBehavior>(*this, Pos, DepClassTy::OPTIONAL); 8260 if (!MemBehaviorAA) 8261 break; 8262 // "assumed" has at most the same bits as the MemBehaviorAA assumed 8263 // and at least "known". 8264 intersectAssumedBits(MemBehaviorAA->getAssumed()); 8265 return; 8266 } 8267 }; 8268 8269 // Generally, look at the "may-properties" and adjust the assumed state if we 8270 // did not trigger special handling before. 8271 if (UserI->mayReadFromMemory()) 8272 removeAssumedBits(NO_READS); 8273 if (UserI->mayWriteToMemory()) 8274 removeAssumedBits(NO_WRITES); 8275 } 8276 } // namespace 8277 8278 /// -------------------- Memory Locations Attributes --------------------------- 8279 /// Includes read-none, argmemonly, inaccessiblememonly, 8280 /// inaccessiblememorargmemonly 8281 /// ---------------------------------------------------------------------------- 8282 8283 std::string AAMemoryLocation::getMemoryLocationsAsStr( 8284 AAMemoryLocation::MemoryLocationsKind MLK) { 8285 if (0 == (MLK & AAMemoryLocation::NO_LOCATIONS)) 8286 return "all memory"; 8287 if (MLK == AAMemoryLocation::NO_LOCATIONS) 8288 return "no memory"; 8289 std::string S = "memory:"; 8290 if (0 == (MLK & AAMemoryLocation::NO_LOCAL_MEM)) 8291 S += "stack,"; 8292 if (0 == (MLK & AAMemoryLocation::NO_CONST_MEM)) 8293 S += "constant,"; 8294 if (0 == (MLK & AAMemoryLocation::NO_GLOBAL_INTERNAL_MEM)) 8295 S += "internal global,"; 8296 if (0 == (MLK & AAMemoryLocation::NO_GLOBAL_EXTERNAL_MEM)) 8297 S += "external global,"; 8298 if (0 == (MLK & AAMemoryLocation::NO_ARGUMENT_MEM)) 8299 S += "argument,"; 8300 if (0 == (MLK & AAMemoryLocation::NO_INACCESSIBLE_MEM)) 8301 S += "inaccessible,"; 8302 if (0 == (MLK & AAMemoryLocation::NO_MALLOCED_MEM)) 8303 S += "malloced,"; 8304 if (0 == (MLK & AAMemoryLocation::NO_UNKOWN_MEM)) 8305 S += "unknown,"; 8306 S.pop_back(); 8307 return S; 8308 } 8309 8310 namespace { 8311 struct AAMemoryLocationImpl : public AAMemoryLocation { 8312 8313 AAMemoryLocationImpl(const IRPosition &IRP, Attributor &A) 8314 : AAMemoryLocation(IRP, A), Allocator(A.Allocator) { 8315 AccessKind2Accesses.fill(nullptr); 8316 } 8317 8318 ~AAMemoryLocationImpl() { 8319 // The AccessSets are allocated via a BumpPtrAllocator, we call 8320 // the destructor manually. 8321 for (AccessSet *AS : AccessKind2Accesses) 8322 if (AS) 8323 AS->~AccessSet(); 8324 } 8325 8326 /// See AbstractAttribute::initialize(...). 8327 void initialize(Attributor &A) override { 8328 intersectAssumedBits(BEST_STATE); 8329 getKnownStateFromValue(A, getIRPosition(), getState()); 8330 AAMemoryLocation::initialize(A); 8331 } 8332 8333 /// Return the memory behavior information encoded in the IR for \p IRP. 8334 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP, 8335 BitIntegerState &State, 8336 bool IgnoreSubsumingPositions = false) { 8337 // For internal functions we ignore `argmemonly` and 8338 // `inaccessiblememorargmemonly` as we might break it via interprocedural 8339 // constant propagation. It is unclear if this is the best way but it is 8340 // unlikely this will cause real performance problems. If we are deriving 8341 // attributes for the anchor function we even remove the attribute in 8342 // addition to ignoring it. 8343 // TODO: A better way to handle this would be to add ~NO_GLOBAL_MEM / 8344 // MemoryEffects::Other as a possible location. 8345 bool UseArgMemOnly = true; 8346 Function *AnchorFn = IRP.getAnchorScope(); 8347 if (AnchorFn && A.isRunOn(*AnchorFn)) 8348 UseArgMemOnly = !AnchorFn->hasLocalLinkage(); 8349 8350 SmallVector<Attribute, 2> Attrs; 8351 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions); 8352 for (const Attribute &Attr : Attrs) { 8353 // TODO: We can map MemoryEffects to Attributor locations more precisely. 8354 MemoryEffects ME = Attr.getMemoryEffects(); 8355 if (ME.doesNotAccessMemory()) { 8356 State.addKnownBits(NO_LOCAL_MEM | NO_CONST_MEM); 8357 continue; 8358 } 8359 if (ME.onlyAccessesInaccessibleMem()) { 8360 State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true)); 8361 continue; 8362 } 8363 if (ME.onlyAccessesArgPointees()) { 8364 if (UseArgMemOnly) 8365 State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true)); 8366 else { 8367 // Remove location information, only keep read/write info. 8368 ME = MemoryEffects(ME.getModRef()); 8369 A.manifestAttrs(IRP, 8370 Attribute::getWithMemoryEffects( 8371 IRP.getAnchorValue().getContext(), ME), 8372 /*ForceReplace*/ true); 8373 } 8374 continue; 8375 } 8376 if (ME.onlyAccessesInaccessibleOrArgMem()) { 8377 if (UseArgMemOnly) 8378 State.addKnownBits(inverseLocation( 8379 NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true)); 8380 else { 8381 // Remove location information, only keep read/write info. 8382 ME = MemoryEffects(ME.getModRef()); 8383 A.manifestAttrs(IRP, 8384 Attribute::getWithMemoryEffects( 8385 IRP.getAnchorValue().getContext(), ME), 8386 /*ForceReplace*/ true); 8387 } 8388 continue; 8389 } 8390 } 8391 } 8392 8393 /// See AbstractAttribute::getDeducedAttributes(...). 8394 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, 8395 SmallVectorImpl<Attribute> &Attrs) const override { 8396 // TODO: We can map Attributor locations to MemoryEffects more precisely. 8397 assert(Attrs.size() == 0); 8398 if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION) { 8399 if (isAssumedReadNone()) 8400 Attrs.push_back( 8401 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::none())); 8402 else if (isAssumedInaccessibleMemOnly()) 8403 Attrs.push_back(Attribute::getWithMemoryEffects( 8404 Ctx, MemoryEffects::inaccessibleMemOnly())); 8405 else if (isAssumedArgMemOnly()) 8406 Attrs.push_back( 8407 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::argMemOnly())); 8408 else if (isAssumedInaccessibleOrArgMemOnly()) 8409 Attrs.push_back(Attribute::getWithMemoryEffects( 8410 Ctx, MemoryEffects::inaccessibleOrArgMemOnly())); 8411 } 8412 assert(Attrs.size() <= 1); 8413 } 8414 8415 /// See AbstractAttribute::manifest(...). 8416 ChangeStatus manifest(Attributor &A) override { 8417 // TODO: If AAMemoryLocation and AAMemoryBehavior are merged, we could 8418 // provide per-location modref information here. 8419 const IRPosition &IRP = getIRPosition(); 8420 8421 SmallVector<Attribute, 1> DeducedAttrs; 8422 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs); 8423 if (DeducedAttrs.size() != 1) 8424 return ChangeStatus::UNCHANGED; 8425 MemoryEffects ME = DeducedAttrs[0].getMemoryEffects(); 8426 8427 return A.manifestAttrs(IRP, Attribute::getWithMemoryEffects( 8428 IRP.getAnchorValue().getContext(), ME)); 8429 } 8430 8431 /// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...). 8432 bool checkForAllAccessesToMemoryKind( 8433 function_ref<bool(const Instruction *, const Value *, AccessKind, 8434 MemoryLocationsKind)> 8435 Pred, 8436 MemoryLocationsKind RequestedMLK) const override { 8437 if (!isValidState()) 8438 return false; 8439 8440 MemoryLocationsKind AssumedMLK = getAssumedNotAccessedLocation(); 8441 if (AssumedMLK == NO_LOCATIONS) 8442 return true; 8443 8444 unsigned Idx = 0; 8445 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; 8446 CurMLK *= 2, ++Idx) { 8447 if (CurMLK & RequestedMLK) 8448 continue; 8449 8450 if (const AccessSet *Accesses = AccessKind2Accesses[Idx]) 8451 for (const AccessInfo &AI : *Accesses) 8452 if (!Pred(AI.I, AI.Ptr, AI.Kind, CurMLK)) 8453 return false; 8454 } 8455 8456 return true; 8457 } 8458 8459 ChangeStatus indicatePessimisticFixpoint() override { 8460 // If we give up and indicate a pessimistic fixpoint this instruction will 8461 // become an access for all potential access kinds: 8462 // TODO: Add pointers for argmemonly and globals to improve the results of 8463 // checkForAllAccessesToMemoryKind. 8464 bool Changed = false; 8465 MemoryLocationsKind KnownMLK = getKnown(); 8466 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()); 8467 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) 8468 if (!(CurMLK & KnownMLK)) 8469 updateStateAndAccessesMap(getState(), CurMLK, I, nullptr, Changed, 8470 getAccessKindFromInst(I)); 8471 return AAMemoryLocation::indicatePessimisticFixpoint(); 8472 } 8473 8474 protected: 8475 /// Helper struct to tie together an instruction that has a read or write 8476 /// effect with the pointer it accesses (if any). 8477 struct AccessInfo { 8478 8479 /// The instruction that caused the access. 8480 const Instruction *I; 8481 8482 /// The base pointer that is accessed, or null if unknown. 8483 const Value *Ptr; 8484 8485 /// The kind of access (read/write/read+write). 8486 AccessKind Kind; 8487 8488 bool operator==(const AccessInfo &RHS) const { 8489 return I == RHS.I && Ptr == RHS.Ptr && Kind == RHS.Kind; 8490 } 8491 bool operator()(const AccessInfo &LHS, const AccessInfo &RHS) const { 8492 if (LHS.I != RHS.I) 8493 return LHS.I < RHS.I; 8494 if (LHS.Ptr != RHS.Ptr) 8495 return LHS.Ptr < RHS.Ptr; 8496 if (LHS.Kind != RHS.Kind) 8497 return LHS.Kind < RHS.Kind; 8498 return false; 8499 } 8500 }; 8501 8502 /// Mapping from *single* memory location kinds, e.g., LOCAL_MEM with the 8503 /// value of NO_LOCAL_MEM, to the accesses encountered for this memory kind. 8504 using AccessSet = SmallSet<AccessInfo, 2, AccessInfo>; 8505 std::array<AccessSet *, llvm::CTLog2<VALID_STATE>()> AccessKind2Accesses; 8506 8507 /// Categorize the pointer arguments of CB that might access memory in 8508 /// AccessedLoc and update the state and access map accordingly. 8509 void 8510 categorizeArgumentPointerLocations(Attributor &A, CallBase &CB, 8511 AAMemoryLocation::StateType &AccessedLocs, 8512 bool &Changed); 8513 8514 /// Return the kind(s) of location that may be accessed by \p V. 8515 AAMemoryLocation::MemoryLocationsKind 8516 categorizeAccessedLocations(Attributor &A, Instruction &I, bool &Changed); 8517 8518 /// Return the access kind as determined by \p I. 8519 AccessKind getAccessKindFromInst(const Instruction *I) { 8520 AccessKind AK = READ_WRITE; 8521 if (I) { 8522 AK = I->mayReadFromMemory() ? READ : NONE; 8523 AK = AccessKind(AK | (I->mayWriteToMemory() ? WRITE : NONE)); 8524 } 8525 return AK; 8526 } 8527 8528 /// Update the state \p State and the AccessKind2Accesses given that \p I is 8529 /// an access of kind \p AK to a \p MLK memory location with the access 8530 /// pointer \p Ptr. 8531 void updateStateAndAccessesMap(AAMemoryLocation::StateType &State, 8532 MemoryLocationsKind MLK, const Instruction *I, 8533 const Value *Ptr, bool &Changed, 8534 AccessKind AK = READ_WRITE) { 8535 8536 assert(isPowerOf2_32(MLK) && "Expected a single location set!"); 8537 auto *&Accesses = AccessKind2Accesses[llvm::Log2_32(MLK)]; 8538 if (!Accesses) 8539 Accesses = new (Allocator) AccessSet(); 8540 Changed |= Accesses->insert(AccessInfo{I, Ptr, AK}).second; 8541 if (MLK == NO_UNKOWN_MEM) 8542 MLK = NO_LOCATIONS; 8543 State.removeAssumedBits(MLK); 8544 } 8545 8546 /// Determine the underlying locations kinds for \p Ptr, e.g., globals or 8547 /// arguments, and update the state and access map accordingly. 8548 void categorizePtrValue(Attributor &A, const Instruction &I, const Value &Ptr, 8549 AAMemoryLocation::StateType &State, bool &Changed, 8550 unsigned AccessAS = 0); 8551 8552 /// Used to allocate access sets. 8553 BumpPtrAllocator &Allocator; 8554 }; 8555 8556 void AAMemoryLocationImpl::categorizePtrValue( 8557 Attributor &A, const Instruction &I, const Value &Ptr, 8558 AAMemoryLocation::StateType &State, bool &Changed, unsigned AccessAS) { 8559 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize pointer locations for " 8560 << Ptr << " [" 8561 << getMemoryLocationsAsStr(State.getAssumed()) << "]\n"); 8562 8563 auto Pred = [&](Value &Obj) { 8564 unsigned ObjectAS = Obj.getType()->getPointerAddressSpace(); 8565 // TODO: recognize the TBAA used for constant accesses. 8566 MemoryLocationsKind MLK = NO_LOCATIONS; 8567 8568 // Filter accesses to constant (GPU) memory if we have an AS at the access 8569 // site or the object is known to actually have the associated AS. 8570 if ((AccessAS == (unsigned)AA::GPUAddressSpace::Constant || 8571 (ObjectAS == (unsigned)AA::GPUAddressSpace::Constant && 8572 isIdentifiedObject(&Obj))) && 8573 AA::isGPU(*I.getModule())) 8574 return true; 8575 8576 if (isa<UndefValue>(&Obj)) 8577 return true; 8578 if (isa<Argument>(&Obj)) { 8579 // TODO: For now we do not treat byval arguments as local copies performed 8580 // on the call edge, though, we should. To make that happen we need to 8581 // teach various passes, e.g., DSE, about the copy effect of a byval. That 8582 // would also allow us to mark functions only accessing byval arguments as 8583 // readnone again, arguably their accesses have no effect outside of the 8584 // function, like accesses to allocas. 8585 MLK = NO_ARGUMENT_MEM; 8586 } else if (auto *GV = dyn_cast<GlobalValue>(&Obj)) { 8587 // Reading constant memory is not treated as a read "effect" by the 8588 // function attr pass so we won't neither. Constants defined by TBAA are 8589 // similar. (We know we do not write it because it is constant.) 8590 if (auto *GVar = dyn_cast<GlobalVariable>(GV)) 8591 if (GVar->isConstant()) 8592 return true; 8593 8594 if (GV->hasLocalLinkage()) 8595 MLK = NO_GLOBAL_INTERNAL_MEM; 8596 else 8597 MLK = NO_GLOBAL_EXTERNAL_MEM; 8598 } else if (isa<ConstantPointerNull>(&Obj) && 8599 (!NullPointerIsDefined(getAssociatedFunction(), AccessAS) || 8600 !NullPointerIsDefined(getAssociatedFunction(), ObjectAS))) { 8601 return true; 8602 } else if (isa<AllocaInst>(&Obj)) { 8603 MLK = NO_LOCAL_MEM; 8604 } else if (const auto *CB = dyn_cast<CallBase>(&Obj)) { 8605 bool IsKnownNoAlias; 8606 if (AA::hasAssumedIRAttr<Attribute::NoAlias>( 8607 A, this, IRPosition::callsite_returned(*CB), DepClassTy::OPTIONAL, 8608 IsKnownNoAlias)) 8609 MLK = NO_MALLOCED_MEM; 8610 else 8611 MLK = NO_UNKOWN_MEM; 8612 } else { 8613 MLK = NO_UNKOWN_MEM; 8614 } 8615 8616 assert(MLK != NO_LOCATIONS && "No location specified!"); 8617 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Ptr value can be categorized: " 8618 << Obj << " -> " << getMemoryLocationsAsStr(MLK) << "\n"); 8619 updateStateAndAccessesMap(State, MLK, &I, &Obj, Changed, 8620 getAccessKindFromInst(&I)); 8621 8622 return true; 8623 }; 8624 8625 const auto *AA = A.getAAFor<AAUnderlyingObjects>( 8626 *this, IRPosition::value(Ptr), DepClassTy::OPTIONAL); 8627 if (!AA || !AA->forallUnderlyingObjects(Pred, AA::Intraprocedural)) { 8628 LLVM_DEBUG( 8629 dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n"); 8630 updateStateAndAccessesMap(State, NO_UNKOWN_MEM, &I, nullptr, Changed, 8631 getAccessKindFromInst(&I)); 8632 return; 8633 } 8634 8635 LLVM_DEBUG( 8636 dbgs() << "[AAMemoryLocation] Accessed locations with pointer locations: " 8637 << getMemoryLocationsAsStr(State.getAssumed()) << "\n"); 8638 } 8639 8640 void AAMemoryLocationImpl::categorizeArgumentPointerLocations( 8641 Attributor &A, CallBase &CB, AAMemoryLocation::StateType &AccessedLocs, 8642 bool &Changed) { 8643 for (unsigned ArgNo = 0, E = CB.arg_size(); ArgNo < E; ++ArgNo) { 8644 8645 // Skip non-pointer arguments. 8646 const Value *ArgOp = CB.getArgOperand(ArgNo); 8647 if (!ArgOp->getType()->isPtrOrPtrVectorTy()) 8648 continue; 8649 8650 // Skip readnone arguments. 8651 const IRPosition &ArgOpIRP = IRPosition::callsite_argument(CB, ArgNo); 8652 const auto *ArgOpMemLocationAA = 8653 A.getAAFor<AAMemoryBehavior>(*this, ArgOpIRP, DepClassTy::OPTIONAL); 8654 8655 if (ArgOpMemLocationAA && ArgOpMemLocationAA->isAssumedReadNone()) 8656 continue; 8657 8658 // Categorize potentially accessed pointer arguments as if there was an 8659 // access instruction with them as pointer. 8660 categorizePtrValue(A, CB, *ArgOp, AccessedLocs, Changed); 8661 } 8662 } 8663 8664 AAMemoryLocation::MemoryLocationsKind 8665 AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I, 8666 bool &Changed) { 8667 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize accessed locations for " 8668 << I << "\n"); 8669 8670 AAMemoryLocation::StateType AccessedLocs; 8671 AccessedLocs.intersectAssumedBits(NO_LOCATIONS); 8672 8673 if (auto *CB = dyn_cast<CallBase>(&I)) { 8674 8675 // First check if we assume any memory is access is visible. 8676 const auto *CBMemLocationAA = A.getAAFor<AAMemoryLocation>( 8677 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL); 8678 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I 8679 << " [" << CBMemLocationAA << "]\n"); 8680 if (!CBMemLocationAA) { 8681 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr, 8682 Changed, getAccessKindFromInst(&I)); 8683 return NO_UNKOWN_MEM; 8684 } 8685 8686 if (CBMemLocationAA->isAssumedReadNone()) 8687 return NO_LOCATIONS; 8688 8689 if (CBMemLocationAA->isAssumedInaccessibleMemOnly()) { 8690 updateStateAndAccessesMap(AccessedLocs, NO_INACCESSIBLE_MEM, &I, nullptr, 8691 Changed, getAccessKindFromInst(&I)); 8692 return AccessedLocs.getAssumed(); 8693 } 8694 8695 uint32_t CBAssumedNotAccessedLocs = 8696 CBMemLocationAA->getAssumedNotAccessedLocation(); 8697 8698 // Set the argmemonly and global bit as we handle them separately below. 8699 uint32_t CBAssumedNotAccessedLocsNoArgMem = 8700 CBAssumedNotAccessedLocs | NO_ARGUMENT_MEM | NO_GLOBAL_MEM; 8701 8702 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) { 8703 if (CBAssumedNotAccessedLocsNoArgMem & CurMLK) 8704 continue; 8705 updateStateAndAccessesMap(AccessedLocs, CurMLK, &I, nullptr, Changed, 8706 getAccessKindFromInst(&I)); 8707 } 8708 8709 // Now handle global memory if it might be accessed. This is slightly tricky 8710 // as NO_GLOBAL_MEM has multiple bits set. 8711 bool HasGlobalAccesses = ((~CBAssumedNotAccessedLocs) & NO_GLOBAL_MEM); 8712 if (HasGlobalAccesses) { 8713 auto AccessPred = [&](const Instruction *, const Value *Ptr, 8714 AccessKind Kind, MemoryLocationsKind MLK) { 8715 updateStateAndAccessesMap(AccessedLocs, MLK, &I, Ptr, Changed, 8716 getAccessKindFromInst(&I)); 8717 return true; 8718 }; 8719 if (!CBMemLocationAA->checkForAllAccessesToMemoryKind( 8720 AccessPred, inverseLocation(NO_GLOBAL_MEM, false, false))) 8721 return AccessedLocs.getWorstState(); 8722 } 8723 8724 LLVM_DEBUG( 8725 dbgs() << "[AAMemoryLocation] Accessed state before argument handling: " 8726 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n"); 8727 8728 // Now handle argument memory if it might be accessed. 8729 bool HasArgAccesses = ((~CBAssumedNotAccessedLocs) & NO_ARGUMENT_MEM); 8730 if (HasArgAccesses) 8731 categorizeArgumentPointerLocations(A, *CB, AccessedLocs, Changed); 8732 8733 LLVM_DEBUG( 8734 dbgs() << "[AAMemoryLocation] Accessed state after argument handling: " 8735 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n"); 8736 8737 return AccessedLocs.getAssumed(); 8738 } 8739 8740 if (const Value *Ptr = getPointerOperand(&I, /* AllowVolatile */ true)) { 8741 LLVM_DEBUG( 8742 dbgs() << "[AAMemoryLocation] Categorize memory access with pointer: " 8743 << I << " [" << *Ptr << "]\n"); 8744 categorizePtrValue(A, I, *Ptr, AccessedLocs, Changed, 8745 Ptr->getType()->getPointerAddressSpace()); 8746 return AccessedLocs.getAssumed(); 8747 } 8748 8749 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Failed to categorize instruction: " 8750 << I << "\n"); 8751 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr, Changed, 8752 getAccessKindFromInst(&I)); 8753 return AccessedLocs.getAssumed(); 8754 } 8755 8756 /// An AA to represent the memory behavior function attributes. 8757 struct AAMemoryLocationFunction final : public AAMemoryLocationImpl { 8758 AAMemoryLocationFunction(const IRPosition &IRP, Attributor &A) 8759 : AAMemoryLocationImpl(IRP, A) {} 8760 8761 /// See AbstractAttribute::updateImpl(Attributor &A). 8762 ChangeStatus updateImpl(Attributor &A) override { 8763 8764 const auto *MemBehaviorAA = 8765 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE); 8766 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) { 8767 if (MemBehaviorAA->isKnownReadNone()) 8768 return indicateOptimisticFixpoint(); 8769 assert(isAssumedReadNone() && 8770 "AAMemoryLocation was not read-none but AAMemoryBehavior was!"); 8771 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL); 8772 return ChangeStatus::UNCHANGED; 8773 } 8774 8775 // The current assumed state used to determine a change. 8776 auto AssumedState = getAssumed(); 8777 bool Changed = false; 8778 8779 auto CheckRWInst = [&](Instruction &I) { 8780 MemoryLocationsKind MLK = categorizeAccessedLocations(A, I, Changed); 8781 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I 8782 << ": " << getMemoryLocationsAsStr(MLK) << "\n"); 8783 removeAssumedBits(inverseLocation(MLK, false, false)); 8784 // Stop once only the valid bit set in the *not assumed location*, thus 8785 // once we don't actually exclude any memory locations in the state. 8786 return getAssumedNotAccessedLocation() != VALID_STATE; 8787 }; 8788 8789 bool UsedAssumedInformation = false; 8790 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this, 8791 UsedAssumedInformation)) 8792 return indicatePessimisticFixpoint(); 8793 8794 Changed |= AssumedState != getAssumed(); 8795 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 8796 } 8797 8798 /// See AbstractAttribute::trackStatistics() 8799 void trackStatistics() const override { 8800 if (isAssumedReadNone()) 8801 STATS_DECLTRACK_FN_ATTR(readnone) 8802 else if (isAssumedArgMemOnly()) 8803 STATS_DECLTRACK_FN_ATTR(argmemonly) 8804 else if (isAssumedInaccessibleMemOnly()) 8805 STATS_DECLTRACK_FN_ATTR(inaccessiblememonly) 8806 else if (isAssumedInaccessibleOrArgMemOnly()) 8807 STATS_DECLTRACK_FN_ATTR(inaccessiblememorargmemonly) 8808 } 8809 }; 8810 8811 /// AAMemoryLocation attribute for call sites. 8812 struct AAMemoryLocationCallSite final : AAMemoryLocationImpl { 8813 AAMemoryLocationCallSite(const IRPosition &IRP, Attributor &A) 8814 : AAMemoryLocationImpl(IRP, A) {} 8815 8816 /// See AbstractAttribute::updateImpl(...). 8817 ChangeStatus updateImpl(Attributor &A) override { 8818 // TODO: Once we have call site specific value information we can provide 8819 // call site specific liveness liveness information and then it makes 8820 // sense to specialize attributes for call sites arguments instead of 8821 // redirecting requests to the callee argument. 8822 Function *F = getAssociatedFunction(); 8823 const IRPosition &FnPos = IRPosition::function(*F); 8824 auto *FnAA = 8825 A.getAAFor<AAMemoryLocation>(*this, FnPos, DepClassTy::REQUIRED); 8826 if (!FnAA) 8827 return indicatePessimisticFixpoint(); 8828 bool Changed = false; 8829 auto AccessPred = [&](const Instruction *I, const Value *Ptr, 8830 AccessKind Kind, MemoryLocationsKind MLK) { 8831 updateStateAndAccessesMap(getState(), MLK, I, Ptr, Changed, 8832 getAccessKindFromInst(I)); 8833 return true; 8834 }; 8835 if (!FnAA->checkForAllAccessesToMemoryKind(AccessPred, ALL_LOCATIONS)) 8836 return indicatePessimisticFixpoint(); 8837 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 8838 } 8839 8840 /// See AbstractAttribute::trackStatistics() 8841 void trackStatistics() const override { 8842 if (isAssumedReadNone()) 8843 STATS_DECLTRACK_CS_ATTR(readnone) 8844 } 8845 }; 8846 } // namespace 8847 8848 /// ------------------ denormal-fp-math Attribute ------------------------- 8849 8850 namespace { 8851 struct AADenormalFPMathImpl : public AADenormalFPMath { 8852 AADenormalFPMathImpl(const IRPosition &IRP, Attributor &A) 8853 : AADenormalFPMath(IRP, A) {} 8854 8855 const std::string getAsStr(Attributor *A) const override { 8856 std::string Str("AADenormalFPMath["); 8857 raw_string_ostream OS(Str); 8858 8859 DenormalState Known = getKnown(); 8860 if (Known.Mode.isValid()) 8861 OS << "denormal-fp-math=" << Known.Mode; 8862 else 8863 OS << "invalid"; 8864 8865 if (Known.ModeF32.isValid()) 8866 OS << " denormal-fp-math-f32=" << Known.ModeF32; 8867 OS << ']'; 8868 return Str; 8869 } 8870 }; 8871 8872 struct AADenormalFPMathFunction final : AADenormalFPMathImpl { 8873 AADenormalFPMathFunction(const IRPosition &IRP, Attributor &A) 8874 : AADenormalFPMathImpl(IRP, A) {} 8875 8876 void initialize(Attributor &A) override { 8877 const Function *F = getAnchorScope(); 8878 DenormalMode Mode = F->getDenormalModeRaw(); 8879 DenormalMode ModeF32 = F->getDenormalModeF32Raw(); 8880 8881 // TODO: Handling this here prevents handling the case where a callee has a 8882 // fixed denormal-fp-math with dynamic denormal-fp-math-f32, but called from 8883 // a function with a fully fixed mode. 8884 if (ModeF32 == DenormalMode::getInvalid()) 8885 ModeF32 = Mode; 8886 Known = DenormalState{Mode, ModeF32}; 8887 if (isModeFixed()) 8888 indicateFixpoint(); 8889 } 8890 8891 ChangeStatus updateImpl(Attributor &A) override { 8892 ChangeStatus Change = ChangeStatus::UNCHANGED; 8893 8894 auto CheckCallSite = [=, &Change, &A](AbstractCallSite CS) { 8895 Function *Caller = CS.getInstruction()->getFunction(); 8896 LLVM_DEBUG(dbgs() << "[AADenormalFPMath] Call " << Caller->getName() 8897 << "->" << getAssociatedFunction()->getName() << '\n'); 8898 8899 const auto *CallerInfo = A.getAAFor<AADenormalFPMath>( 8900 *this, IRPosition::function(*Caller), DepClassTy::REQUIRED); 8901 if (!CallerInfo) 8902 return false; 8903 8904 Change = Change | clampStateAndIndicateChange(this->getState(), 8905 CallerInfo->getState()); 8906 return true; 8907 }; 8908 8909 bool AllCallSitesKnown = true; 8910 if (!A.checkForAllCallSites(CheckCallSite, *this, true, AllCallSitesKnown)) 8911 return indicatePessimisticFixpoint(); 8912 8913 if (Change == ChangeStatus::CHANGED && isModeFixed()) 8914 indicateFixpoint(); 8915 return Change; 8916 } 8917 8918 ChangeStatus manifest(Attributor &A) override { 8919 LLVMContext &Ctx = getAssociatedFunction()->getContext(); 8920 8921 SmallVector<Attribute, 2> AttrToAdd; 8922 SmallVector<StringRef, 2> AttrToRemove; 8923 if (Known.Mode == DenormalMode::getDefault()) { 8924 AttrToRemove.push_back("denormal-fp-math"); 8925 } else { 8926 AttrToAdd.push_back( 8927 Attribute::get(Ctx, "denormal-fp-math", Known.Mode.str())); 8928 } 8929 8930 if (Known.ModeF32 != Known.Mode) { 8931 AttrToAdd.push_back( 8932 Attribute::get(Ctx, "denormal-fp-math-f32", Known.ModeF32.str())); 8933 } else { 8934 AttrToRemove.push_back("denormal-fp-math-f32"); 8935 } 8936 8937 auto &IRP = getIRPosition(); 8938 8939 // TODO: There should be a combined add and remove API. 8940 return A.removeAttrs(IRP, AttrToRemove) | 8941 A.manifestAttrs(IRP, AttrToAdd, /*ForceReplace=*/true); 8942 } 8943 8944 void trackStatistics() const override { 8945 STATS_DECLTRACK_FN_ATTR(denormal_fp_math) 8946 } 8947 }; 8948 } // namespace 8949 8950 /// ------------------ Value Constant Range Attribute ------------------------- 8951 8952 namespace { 8953 struct AAValueConstantRangeImpl : AAValueConstantRange { 8954 using StateType = IntegerRangeState; 8955 AAValueConstantRangeImpl(const IRPosition &IRP, Attributor &A) 8956 : AAValueConstantRange(IRP, A) {} 8957 8958 /// See AbstractAttribute::initialize(..). 8959 void initialize(Attributor &A) override { 8960 if (A.hasSimplificationCallback(getIRPosition())) { 8961 indicatePessimisticFixpoint(); 8962 return; 8963 } 8964 8965 // Intersect a range given by SCEV. 8966 intersectKnown(getConstantRangeFromSCEV(A, getCtxI())); 8967 8968 // Intersect a range given by LVI. 8969 intersectKnown(getConstantRangeFromLVI(A, getCtxI())); 8970 } 8971 8972 /// See AbstractAttribute::getAsStr(). 8973 const std::string getAsStr(Attributor *A) const override { 8974 std::string Str; 8975 llvm::raw_string_ostream OS(Str); 8976 OS << "range(" << getBitWidth() << ")<"; 8977 getKnown().print(OS); 8978 OS << " / "; 8979 getAssumed().print(OS); 8980 OS << ">"; 8981 return Str; 8982 } 8983 8984 /// Helper function to get a SCEV expr for the associated value at program 8985 /// point \p I. 8986 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const { 8987 if (!getAnchorScope()) 8988 return nullptr; 8989 8990 ScalarEvolution *SE = 8991 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>( 8992 *getAnchorScope()); 8993 8994 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>( 8995 *getAnchorScope()); 8996 8997 if (!SE || !LI) 8998 return nullptr; 8999 9000 const SCEV *S = SE->getSCEV(&getAssociatedValue()); 9001 if (!I) 9002 return S; 9003 9004 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent())); 9005 } 9006 9007 /// Helper function to get a range from SCEV for the associated value at 9008 /// program point \p I. 9009 ConstantRange getConstantRangeFromSCEV(Attributor &A, 9010 const Instruction *I = nullptr) const { 9011 if (!getAnchorScope()) 9012 return getWorstState(getBitWidth()); 9013 9014 ScalarEvolution *SE = 9015 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>( 9016 *getAnchorScope()); 9017 9018 const SCEV *S = getSCEV(A, I); 9019 if (!SE || !S) 9020 return getWorstState(getBitWidth()); 9021 9022 return SE->getUnsignedRange(S); 9023 } 9024 9025 /// Helper function to get a range from LVI for the associated value at 9026 /// program point \p I. 9027 ConstantRange 9028 getConstantRangeFromLVI(Attributor &A, 9029 const Instruction *CtxI = nullptr) const { 9030 if (!getAnchorScope()) 9031 return getWorstState(getBitWidth()); 9032 9033 LazyValueInfo *LVI = 9034 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>( 9035 *getAnchorScope()); 9036 9037 if (!LVI || !CtxI) 9038 return getWorstState(getBitWidth()); 9039 return LVI->getConstantRange(&getAssociatedValue(), 9040 const_cast<Instruction *>(CtxI), 9041 /*UndefAllowed*/ false); 9042 } 9043 9044 /// Return true if \p CtxI is valid for querying outside analyses. 9045 /// This basically makes sure we do not ask intra-procedural analysis 9046 /// about a context in the wrong function or a context that violates 9047 /// dominance assumptions they might have. The \p AllowAACtxI flag indicates 9048 /// if the original context of this AA is OK or should be considered invalid. 9049 bool isValidCtxInstructionForOutsideAnalysis(Attributor &A, 9050 const Instruction *CtxI, 9051 bool AllowAACtxI) const { 9052 if (!CtxI || (!AllowAACtxI && CtxI == getCtxI())) 9053 return false; 9054 9055 // Our context might be in a different function, neither intra-procedural 9056 // analysis (ScalarEvolution nor LazyValueInfo) can handle that. 9057 if (!AA::isValidInScope(getAssociatedValue(), CtxI->getFunction())) 9058 return false; 9059 9060 // If the context is not dominated by the value there are paths to the 9061 // context that do not define the value. This cannot be handled by 9062 // LazyValueInfo so we need to bail. 9063 if (auto *I = dyn_cast<Instruction>(&getAssociatedValue())) { 9064 InformationCache &InfoCache = A.getInfoCache(); 9065 const DominatorTree *DT = 9066 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>( 9067 *I->getFunction()); 9068 return DT && DT->dominates(I, CtxI); 9069 } 9070 9071 return true; 9072 } 9073 9074 /// See AAValueConstantRange::getKnownConstantRange(..). 9075 ConstantRange 9076 getKnownConstantRange(Attributor &A, 9077 const Instruction *CtxI = nullptr) const override { 9078 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI, 9079 /* AllowAACtxI */ false)) 9080 return getKnown(); 9081 9082 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI); 9083 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI); 9084 return getKnown().intersectWith(SCEVR).intersectWith(LVIR); 9085 } 9086 9087 /// See AAValueConstantRange::getAssumedConstantRange(..). 9088 ConstantRange 9089 getAssumedConstantRange(Attributor &A, 9090 const Instruction *CtxI = nullptr) const override { 9091 // TODO: Make SCEV use Attributor assumption. 9092 // We may be able to bound a variable range via assumptions in 9093 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to 9094 // evolve to x^2 + x, then we can say that y is in [2, 12]. 9095 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI, 9096 /* AllowAACtxI */ false)) 9097 return getAssumed(); 9098 9099 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI); 9100 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI); 9101 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR); 9102 } 9103 9104 /// Helper function to create MDNode for range metadata. 9105 static MDNode * 9106 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx, 9107 const ConstantRange &AssumedConstantRange) { 9108 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get( 9109 Ty, AssumedConstantRange.getLower())), 9110 ConstantAsMetadata::get(ConstantInt::get( 9111 Ty, AssumedConstantRange.getUpper()))}; 9112 return MDNode::get(Ctx, LowAndHigh); 9113 } 9114 9115 /// Return true if \p Assumed is included in \p KnownRanges. 9116 static bool isBetterRange(const ConstantRange &Assumed, MDNode *KnownRanges) { 9117 9118 if (Assumed.isFullSet()) 9119 return false; 9120 9121 if (!KnownRanges) 9122 return true; 9123 9124 // If multiple ranges are annotated in IR, we give up to annotate assumed 9125 // range for now. 9126 9127 // TODO: If there exists a known range which containts assumed range, we 9128 // can say assumed range is better. 9129 if (KnownRanges->getNumOperands() > 2) 9130 return false; 9131 9132 ConstantInt *Lower = 9133 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0)); 9134 ConstantInt *Upper = 9135 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1)); 9136 9137 ConstantRange Known(Lower->getValue(), Upper->getValue()); 9138 return Known.contains(Assumed) && Known != Assumed; 9139 } 9140 9141 /// Helper function to set range metadata. 9142 static bool 9143 setRangeMetadataIfisBetterRange(Instruction *I, 9144 const ConstantRange &AssumedConstantRange) { 9145 auto *OldRangeMD = I->getMetadata(LLVMContext::MD_range); 9146 if (isBetterRange(AssumedConstantRange, OldRangeMD)) { 9147 if (!AssumedConstantRange.isEmptySet()) { 9148 I->setMetadata(LLVMContext::MD_range, 9149 getMDNodeForConstantRange(I->getType(), I->getContext(), 9150 AssumedConstantRange)); 9151 return true; 9152 } 9153 } 9154 return false; 9155 } 9156 9157 /// See AbstractAttribute::manifest() 9158 ChangeStatus manifest(Attributor &A) override { 9159 ChangeStatus Changed = ChangeStatus::UNCHANGED; 9160 ConstantRange AssumedConstantRange = getAssumedConstantRange(A); 9161 assert(!AssumedConstantRange.isFullSet() && "Invalid state"); 9162 9163 auto &V = getAssociatedValue(); 9164 if (!AssumedConstantRange.isEmptySet() && 9165 !AssumedConstantRange.isSingleElement()) { 9166 if (Instruction *I = dyn_cast<Instruction>(&V)) { 9167 assert(I == getCtxI() && "Should not annotate an instruction which is " 9168 "not the context instruction"); 9169 if (isa<CallInst>(I) || isa<LoadInst>(I)) 9170 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange)) 9171 Changed = ChangeStatus::CHANGED; 9172 } 9173 } 9174 9175 return Changed; 9176 } 9177 }; 9178 9179 struct AAValueConstantRangeArgument final 9180 : AAArgumentFromCallSiteArguments< 9181 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState, 9182 true /* BridgeCallBaseContext */> { 9183 using Base = AAArgumentFromCallSiteArguments< 9184 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState, 9185 true /* BridgeCallBaseContext */>; 9186 AAValueConstantRangeArgument(const IRPosition &IRP, Attributor &A) 9187 : Base(IRP, A) {} 9188 9189 /// See AbstractAttribute::trackStatistics() 9190 void trackStatistics() const override { 9191 STATS_DECLTRACK_ARG_ATTR(value_range) 9192 } 9193 }; 9194 9195 struct AAValueConstantRangeReturned 9196 : AAReturnedFromReturnedValues<AAValueConstantRange, 9197 AAValueConstantRangeImpl, 9198 AAValueConstantRangeImpl::StateType, 9199 /* PropogateCallBaseContext */ true> { 9200 using Base = 9201 AAReturnedFromReturnedValues<AAValueConstantRange, 9202 AAValueConstantRangeImpl, 9203 AAValueConstantRangeImpl::StateType, 9204 /* PropogateCallBaseContext */ true>; 9205 AAValueConstantRangeReturned(const IRPosition &IRP, Attributor &A) 9206 : Base(IRP, A) {} 9207 9208 /// See AbstractAttribute::initialize(...). 9209 void initialize(Attributor &A) override { 9210 if (!A.isFunctionIPOAmendable(*getAssociatedFunction())) 9211 indicatePessimisticFixpoint(); 9212 } 9213 9214 /// See AbstractAttribute::trackStatistics() 9215 void trackStatistics() const override { 9216 STATS_DECLTRACK_FNRET_ATTR(value_range) 9217 } 9218 }; 9219 9220 struct AAValueConstantRangeFloating : AAValueConstantRangeImpl { 9221 AAValueConstantRangeFloating(const IRPosition &IRP, Attributor &A) 9222 : AAValueConstantRangeImpl(IRP, A) {} 9223 9224 /// See AbstractAttribute::initialize(...). 9225 void initialize(Attributor &A) override { 9226 AAValueConstantRangeImpl::initialize(A); 9227 if (isAtFixpoint()) 9228 return; 9229 9230 Value &V = getAssociatedValue(); 9231 9232 if (auto *C = dyn_cast<ConstantInt>(&V)) { 9233 unionAssumed(ConstantRange(C->getValue())); 9234 indicateOptimisticFixpoint(); 9235 return; 9236 } 9237 9238 if (isa<UndefValue>(&V)) { 9239 // Collapse the undef state to 0. 9240 unionAssumed(ConstantRange(APInt(getBitWidth(), 0))); 9241 indicateOptimisticFixpoint(); 9242 return; 9243 } 9244 9245 if (isa<CallBase>(&V)) 9246 return; 9247 9248 if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V)) 9249 return; 9250 9251 // If it is a load instruction with range metadata, use it. 9252 if (LoadInst *LI = dyn_cast<LoadInst>(&V)) 9253 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) { 9254 intersectKnown(getConstantRangeFromMetadata(*RangeMD)); 9255 return; 9256 } 9257 9258 // We can work with PHI and select instruction as we traverse their operands 9259 // during update. 9260 if (isa<SelectInst>(V) || isa<PHINode>(V)) 9261 return; 9262 9263 // Otherwise we give up. 9264 indicatePessimisticFixpoint(); 9265 9266 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: " 9267 << getAssociatedValue() << "\n"); 9268 } 9269 9270 bool calculateBinaryOperator( 9271 Attributor &A, BinaryOperator *BinOp, IntegerRangeState &T, 9272 const Instruction *CtxI, 9273 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) { 9274 Value *LHS = BinOp->getOperand(0); 9275 Value *RHS = BinOp->getOperand(1); 9276 9277 // Simplify the operands first. 9278 bool UsedAssumedInformation = false; 9279 const auto &SimplifiedLHS = A.getAssumedSimplified( 9280 IRPosition::value(*LHS, getCallBaseContext()), *this, 9281 UsedAssumedInformation, AA::Interprocedural); 9282 if (!SimplifiedLHS.has_value()) 9283 return true; 9284 if (!*SimplifiedLHS) 9285 return false; 9286 LHS = *SimplifiedLHS; 9287 9288 const auto &SimplifiedRHS = A.getAssumedSimplified( 9289 IRPosition::value(*RHS, getCallBaseContext()), *this, 9290 UsedAssumedInformation, AA::Interprocedural); 9291 if (!SimplifiedRHS.has_value()) 9292 return true; 9293 if (!*SimplifiedRHS) 9294 return false; 9295 RHS = *SimplifiedRHS; 9296 9297 // TODO: Allow non integers as well. 9298 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy()) 9299 return false; 9300 9301 auto *LHSAA = A.getAAFor<AAValueConstantRange>( 9302 *this, IRPosition::value(*LHS, getCallBaseContext()), 9303 DepClassTy::REQUIRED); 9304 if (!LHSAA) 9305 return false; 9306 QuerriedAAs.push_back(LHSAA); 9307 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI); 9308 9309 auto *RHSAA = A.getAAFor<AAValueConstantRange>( 9310 *this, IRPosition::value(*RHS, getCallBaseContext()), 9311 DepClassTy::REQUIRED); 9312 if (!RHSAA) 9313 return false; 9314 QuerriedAAs.push_back(RHSAA); 9315 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI); 9316 9317 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange); 9318 9319 T.unionAssumed(AssumedRange); 9320 9321 // TODO: Track a known state too. 9322 9323 return T.isValidState(); 9324 } 9325 9326 bool calculateCastInst( 9327 Attributor &A, CastInst *CastI, IntegerRangeState &T, 9328 const Instruction *CtxI, 9329 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) { 9330 assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!"); 9331 // TODO: Allow non integers as well. 9332 Value *OpV = CastI->getOperand(0); 9333 9334 // Simplify the operand first. 9335 bool UsedAssumedInformation = false; 9336 const auto &SimplifiedOpV = A.getAssumedSimplified( 9337 IRPosition::value(*OpV, getCallBaseContext()), *this, 9338 UsedAssumedInformation, AA::Interprocedural); 9339 if (!SimplifiedOpV.has_value()) 9340 return true; 9341 if (!*SimplifiedOpV) 9342 return false; 9343 OpV = *SimplifiedOpV; 9344 9345 if (!OpV->getType()->isIntegerTy()) 9346 return false; 9347 9348 auto *OpAA = A.getAAFor<AAValueConstantRange>( 9349 *this, IRPosition::value(*OpV, getCallBaseContext()), 9350 DepClassTy::REQUIRED); 9351 if (!OpAA) 9352 return false; 9353 QuerriedAAs.push_back(OpAA); 9354 T.unionAssumed(OpAA->getAssumed().castOp(CastI->getOpcode(), 9355 getState().getBitWidth())); 9356 return T.isValidState(); 9357 } 9358 9359 bool 9360 calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T, 9361 const Instruction *CtxI, 9362 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) { 9363 Value *LHS = CmpI->getOperand(0); 9364 Value *RHS = CmpI->getOperand(1); 9365 9366 // Simplify the operands first. 9367 bool UsedAssumedInformation = false; 9368 const auto &SimplifiedLHS = A.getAssumedSimplified( 9369 IRPosition::value(*LHS, getCallBaseContext()), *this, 9370 UsedAssumedInformation, AA::Interprocedural); 9371 if (!SimplifiedLHS.has_value()) 9372 return true; 9373 if (!*SimplifiedLHS) 9374 return false; 9375 LHS = *SimplifiedLHS; 9376 9377 const auto &SimplifiedRHS = A.getAssumedSimplified( 9378 IRPosition::value(*RHS, getCallBaseContext()), *this, 9379 UsedAssumedInformation, AA::Interprocedural); 9380 if (!SimplifiedRHS.has_value()) 9381 return true; 9382 if (!*SimplifiedRHS) 9383 return false; 9384 RHS = *SimplifiedRHS; 9385 9386 // TODO: Allow non integers as well. 9387 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy()) 9388 return false; 9389 9390 auto *LHSAA = A.getAAFor<AAValueConstantRange>( 9391 *this, IRPosition::value(*LHS, getCallBaseContext()), 9392 DepClassTy::REQUIRED); 9393 if (!LHSAA) 9394 return false; 9395 QuerriedAAs.push_back(LHSAA); 9396 auto *RHSAA = A.getAAFor<AAValueConstantRange>( 9397 *this, IRPosition::value(*RHS, getCallBaseContext()), 9398 DepClassTy::REQUIRED); 9399 if (!RHSAA) 9400 return false; 9401 QuerriedAAs.push_back(RHSAA); 9402 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI); 9403 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI); 9404 9405 // If one of them is empty set, we can't decide. 9406 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet()) 9407 return true; 9408 9409 bool MustTrue = false, MustFalse = false; 9410 9411 auto AllowedRegion = 9412 ConstantRange::makeAllowedICmpRegion(CmpI->getPredicate(), RHSAARange); 9413 9414 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet()) 9415 MustFalse = true; 9416 9417 if (LHSAARange.icmp(CmpI->getPredicate(), RHSAARange)) 9418 MustTrue = true; 9419 9420 assert((!MustTrue || !MustFalse) && 9421 "Either MustTrue or MustFalse should be false!"); 9422 9423 if (MustTrue) 9424 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1))); 9425 else if (MustFalse) 9426 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0))); 9427 else 9428 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true)); 9429 9430 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " after " 9431 << (MustTrue ? "true" : (MustFalse ? "false" : "unknown")) 9432 << ": " << T << "\n\t" << *LHSAA << "\t<op>\n\t" 9433 << *RHSAA); 9434 9435 // TODO: Track a known state too. 9436 return T.isValidState(); 9437 } 9438 9439 /// See AbstractAttribute::updateImpl(...). 9440 ChangeStatus updateImpl(Attributor &A) override { 9441 9442 IntegerRangeState T(getBitWidth()); 9443 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool { 9444 Instruction *I = dyn_cast<Instruction>(&V); 9445 if (!I || isa<CallBase>(I)) { 9446 9447 // Simplify the operand first. 9448 bool UsedAssumedInformation = false; 9449 const auto &SimplifiedOpV = A.getAssumedSimplified( 9450 IRPosition::value(V, getCallBaseContext()), *this, 9451 UsedAssumedInformation, AA::Interprocedural); 9452 if (!SimplifiedOpV.has_value()) 9453 return true; 9454 if (!*SimplifiedOpV) 9455 return false; 9456 Value *VPtr = *SimplifiedOpV; 9457 9458 // If the value is not instruction, we query AA to Attributor. 9459 const auto *AA = A.getAAFor<AAValueConstantRange>( 9460 *this, IRPosition::value(*VPtr, getCallBaseContext()), 9461 DepClassTy::REQUIRED); 9462 9463 // Clamp operator is not used to utilize a program point CtxI. 9464 if (AA) 9465 T.unionAssumed(AA->getAssumedConstantRange(A, CtxI)); 9466 else 9467 return false; 9468 9469 return T.isValidState(); 9470 } 9471 9472 SmallVector<const AAValueConstantRange *, 4> QuerriedAAs; 9473 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) { 9474 if (!calculateBinaryOperator(A, BinOp, T, CtxI, QuerriedAAs)) 9475 return false; 9476 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) { 9477 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs)) 9478 return false; 9479 } else if (auto *CastI = dyn_cast<CastInst>(I)) { 9480 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs)) 9481 return false; 9482 } else { 9483 // Give up with other instructions. 9484 // TODO: Add other instructions 9485 9486 T.indicatePessimisticFixpoint(); 9487 return false; 9488 } 9489 9490 // Catch circular reasoning in a pessimistic way for now. 9491 // TODO: Check how the range evolves and if we stripped anything, see also 9492 // AADereferenceable or AAAlign for similar situations. 9493 for (const AAValueConstantRange *QueriedAA : QuerriedAAs) { 9494 if (QueriedAA != this) 9495 continue; 9496 // If we are in a stady state we do not need to worry. 9497 if (T.getAssumed() == getState().getAssumed()) 9498 continue; 9499 T.indicatePessimisticFixpoint(); 9500 } 9501 9502 return T.isValidState(); 9503 }; 9504 9505 if (!VisitValueCB(getAssociatedValue(), getCtxI())) 9506 return indicatePessimisticFixpoint(); 9507 9508 // Ensure that long def-use chains can't cause circular reasoning either by 9509 // introducing a cutoff below. 9510 if (clampStateAndIndicateChange(getState(), T) == ChangeStatus::UNCHANGED) 9511 return ChangeStatus::UNCHANGED; 9512 if (++NumChanges > MaxNumChanges) { 9513 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] performed " << NumChanges 9514 << " but only " << MaxNumChanges 9515 << " are allowed to avoid cyclic reasoning."); 9516 return indicatePessimisticFixpoint(); 9517 } 9518 return ChangeStatus::CHANGED; 9519 } 9520 9521 /// See AbstractAttribute::trackStatistics() 9522 void trackStatistics() const override { 9523 STATS_DECLTRACK_FLOATING_ATTR(value_range) 9524 } 9525 9526 /// Tracker to bail after too many widening steps of the constant range. 9527 int NumChanges = 0; 9528 9529 /// Upper bound for the number of allowed changes (=widening steps) for the 9530 /// constant range before we give up. 9531 static constexpr int MaxNumChanges = 5; 9532 }; 9533 9534 struct AAValueConstantRangeFunction : AAValueConstantRangeImpl { 9535 AAValueConstantRangeFunction(const IRPosition &IRP, Attributor &A) 9536 : AAValueConstantRangeImpl(IRP, A) {} 9537 9538 /// See AbstractAttribute::initialize(...). 9539 ChangeStatus updateImpl(Attributor &A) override { 9540 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will " 9541 "not be called"); 9542 } 9543 9544 /// See AbstractAttribute::trackStatistics() 9545 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) } 9546 }; 9547 9548 struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction { 9549 AAValueConstantRangeCallSite(const IRPosition &IRP, Attributor &A) 9550 : AAValueConstantRangeFunction(IRP, A) {} 9551 9552 /// See AbstractAttribute::trackStatistics() 9553 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) } 9554 }; 9555 9556 struct AAValueConstantRangeCallSiteReturned 9557 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl, 9558 AAValueConstantRangeImpl::StateType, 9559 /* IntroduceCallBaseContext */ true> { 9560 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP, Attributor &A) 9561 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl, 9562 AAValueConstantRangeImpl::StateType, 9563 /* IntroduceCallBaseContext */ true>(IRP, A) {} 9564 9565 /// See AbstractAttribute::initialize(...). 9566 void initialize(Attributor &A) override { 9567 // If it is a load instruction with range metadata, use the metadata. 9568 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue())) 9569 if (auto *RangeMD = CI->getMetadata(LLVMContext::MD_range)) 9570 intersectKnown(getConstantRangeFromMetadata(*RangeMD)); 9571 9572 AAValueConstantRangeImpl::initialize(A); 9573 } 9574 9575 /// See AbstractAttribute::trackStatistics() 9576 void trackStatistics() const override { 9577 STATS_DECLTRACK_CSRET_ATTR(value_range) 9578 } 9579 }; 9580 struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating { 9581 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP, Attributor &A) 9582 : AAValueConstantRangeFloating(IRP, A) {} 9583 9584 /// See AbstractAttribute::manifest() 9585 ChangeStatus manifest(Attributor &A) override { 9586 return ChangeStatus::UNCHANGED; 9587 } 9588 9589 /// See AbstractAttribute::trackStatistics() 9590 void trackStatistics() const override { 9591 STATS_DECLTRACK_CSARG_ATTR(value_range) 9592 } 9593 }; 9594 } // namespace 9595 9596 /// ------------------ Potential Values Attribute ------------------------- 9597 9598 namespace { 9599 struct AAPotentialConstantValuesImpl : AAPotentialConstantValues { 9600 using StateType = PotentialConstantIntValuesState; 9601 9602 AAPotentialConstantValuesImpl(const IRPosition &IRP, Attributor &A) 9603 : AAPotentialConstantValues(IRP, A) {} 9604 9605 /// See AbstractAttribute::initialize(..). 9606 void initialize(Attributor &A) override { 9607 if (A.hasSimplificationCallback(getIRPosition())) 9608 indicatePessimisticFixpoint(); 9609 else 9610 AAPotentialConstantValues::initialize(A); 9611 } 9612 9613 bool fillSetWithConstantValues(Attributor &A, const IRPosition &IRP, SetTy &S, 9614 bool &ContainsUndef, bool ForSelf) { 9615 SmallVector<AA::ValueAndContext> Values; 9616 bool UsedAssumedInformation = false; 9617 if (!A.getAssumedSimplifiedValues(IRP, *this, Values, AA::Interprocedural, 9618 UsedAssumedInformation)) { 9619 // Avoid recursion when the caller is computing constant values for this 9620 // IRP itself. 9621 if (ForSelf) 9622 return false; 9623 if (!IRP.getAssociatedType()->isIntegerTy()) 9624 return false; 9625 auto *PotentialValuesAA = A.getAAFor<AAPotentialConstantValues>( 9626 *this, IRP, DepClassTy::REQUIRED); 9627 if (!PotentialValuesAA || !PotentialValuesAA->getState().isValidState()) 9628 return false; 9629 ContainsUndef = PotentialValuesAA->getState().undefIsContained(); 9630 S = PotentialValuesAA->getState().getAssumedSet(); 9631 return true; 9632 } 9633 9634 // Copy all the constant values, except UndefValue. ContainsUndef is true 9635 // iff Values contains only UndefValue instances. If there are other known 9636 // constants, then UndefValue is dropped. 9637 ContainsUndef = false; 9638 for (auto &It : Values) { 9639 if (isa<UndefValue>(It.getValue())) { 9640 ContainsUndef = true; 9641 continue; 9642 } 9643 auto *CI = dyn_cast<ConstantInt>(It.getValue()); 9644 if (!CI) 9645 return false; 9646 S.insert(CI->getValue()); 9647 } 9648 ContainsUndef &= S.empty(); 9649 9650 return true; 9651 } 9652 9653 /// See AbstractAttribute::getAsStr(). 9654 const std::string getAsStr(Attributor *A) const override { 9655 std::string Str; 9656 llvm::raw_string_ostream OS(Str); 9657 OS << getState(); 9658 return Str; 9659 } 9660 9661 /// See AbstractAttribute::updateImpl(...). 9662 ChangeStatus updateImpl(Attributor &A) override { 9663 return indicatePessimisticFixpoint(); 9664 } 9665 }; 9666 9667 struct AAPotentialConstantValuesArgument final 9668 : AAArgumentFromCallSiteArguments<AAPotentialConstantValues, 9669 AAPotentialConstantValuesImpl, 9670 PotentialConstantIntValuesState> { 9671 using Base = AAArgumentFromCallSiteArguments<AAPotentialConstantValues, 9672 AAPotentialConstantValuesImpl, 9673 PotentialConstantIntValuesState>; 9674 AAPotentialConstantValuesArgument(const IRPosition &IRP, Attributor &A) 9675 : Base(IRP, A) {} 9676 9677 /// See AbstractAttribute::trackStatistics() 9678 void trackStatistics() const override { 9679 STATS_DECLTRACK_ARG_ATTR(potential_values) 9680 } 9681 }; 9682 9683 struct AAPotentialConstantValuesReturned 9684 : AAReturnedFromReturnedValues<AAPotentialConstantValues, 9685 AAPotentialConstantValuesImpl> { 9686 using Base = AAReturnedFromReturnedValues<AAPotentialConstantValues, 9687 AAPotentialConstantValuesImpl>; 9688 AAPotentialConstantValuesReturned(const IRPosition &IRP, Attributor &A) 9689 : Base(IRP, A) {} 9690 9691 void initialize(Attributor &A) override { 9692 if (!A.isFunctionIPOAmendable(*getAssociatedFunction())) 9693 indicatePessimisticFixpoint(); 9694 Base::initialize(A); 9695 } 9696 9697 /// See AbstractAttribute::trackStatistics() 9698 void trackStatistics() const override { 9699 STATS_DECLTRACK_FNRET_ATTR(potential_values) 9700 } 9701 }; 9702 9703 struct AAPotentialConstantValuesFloating : AAPotentialConstantValuesImpl { 9704 AAPotentialConstantValuesFloating(const IRPosition &IRP, Attributor &A) 9705 : AAPotentialConstantValuesImpl(IRP, A) {} 9706 9707 /// See AbstractAttribute::initialize(..). 9708 void initialize(Attributor &A) override { 9709 AAPotentialConstantValuesImpl::initialize(A); 9710 if (isAtFixpoint()) 9711 return; 9712 9713 Value &V = getAssociatedValue(); 9714 9715 if (auto *C = dyn_cast<ConstantInt>(&V)) { 9716 unionAssumed(C->getValue()); 9717 indicateOptimisticFixpoint(); 9718 return; 9719 } 9720 9721 if (isa<UndefValue>(&V)) { 9722 unionAssumedWithUndef(); 9723 indicateOptimisticFixpoint(); 9724 return; 9725 } 9726 9727 if (isa<BinaryOperator>(&V) || isa<ICmpInst>(&V) || isa<CastInst>(&V)) 9728 return; 9729 9730 if (isa<SelectInst>(V) || isa<PHINode>(V) || isa<LoadInst>(V)) 9731 return; 9732 9733 indicatePessimisticFixpoint(); 9734 9735 LLVM_DEBUG(dbgs() << "[AAPotentialConstantValues] We give up: " 9736 << getAssociatedValue() << "\n"); 9737 } 9738 9739 static bool calculateICmpInst(const ICmpInst *ICI, const APInt &LHS, 9740 const APInt &RHS) { 9741 return ICmpInst::compare(LHS, RHS, ICI->getPredicate()); 9742 } 9743 9744 static APInt calculateCastInst(const CastInst *CI, const APInt &Src, 9745 uint32_t ResultBitWidth) { 9746 Instruction::CastOps CastOp = CI->getOpcode(); 9747 switch (CastOp) { 9748 default: 9749 llvm_unreachable("unsupported or not integer cast"); 9750 case Instruction::Trunc: 9751 return Src.trunc(ResultBitWidth); 9752 case Instruction::SExt: 9753 return Src.sext(ResultBitWidth); 9754 case Instruction::ZExt: 9755 return Src.zext(ResultBitWidth); 9756 case Instruction::BitCast: 9757 return Src; 9758 } 9759 } 9760 9761 static APInt calculateBinaryOperator(const BinaryOperator *BinOp, 9762 const APInt &LHS, const APInt &RHS, 9763 bool &SkipOperation, bool &Unsupported) { 9764 Instruction::BinaryOps BinOpcode = BinOp->getOpcode(); 9765 // Unsupported is set to true when the binary operator is not supported. 9766 // SkipOperation is set to true when UB occur with the given operand pair 9767 // (LHS, RHS). 9768 // TODO: we should look at nsw and nuw keywords to handle operations 9769 // that create poison or undef value. 9770 switch (BinOpcode) { 9771 default: 9772 Unsupported = true; 9773 return LHS; 9774 case Instruction::Add: 9775 return LHS + RHS; 9776 case Instruction::Sub: 9777 return LHS - RHS; 9778 case Instruction::Mul: 9779 return LHS * RHS; 9780 case Instruction::UDiv: 9781 if (RHS.isZero()) { 9782 SkipOperation = true; 9783 return LHS; 9784 } 9785 return LHS.udiv(RHS); 9786 case Instruction::SDiv: 9787 if (RHS.isZero()) { 9788 SkipOperation = true; 9789 return LHS; 9790 } 9791 return LHS.sdiv(RHS); 9792 case Instruction::URem: 9793 if (RHS.isZero()) { 9794 SkipOperation = true; 9795 return LHS; 9796 } 9797 return LHS.urem(RHS); 9798 case Instruction::SRem: 9799 if (RHS.isZero()) { 9800 SkipOperation = true; 9801 return LHS; 9802 } 9803 return LHS.srem(RHS); 9804 case Instruction::Shl: 9805 return LHS.shl(RHS); 9806 case Instruction::LShr: 9807 return LHS.lshr(RHS); 9808 case Instruction::AShr: 9809 return LHS.ashr(RHS); 9810 case Instruction::And: 9811 return LHS & RHS; 9812 case Instruction::Or: 9813 return LHS | RHS; 9814 case Instruction::Xor: 9815 return LHS ^ RHS; 9816 } 9817 } 9818 9819 bool calculateBinaryOperatorAndTakeUnion(const BinaryOperator *BinOp, 9820 const APInt &LHS, const APInt &RHS) { 9821 bool SkipOperation = false; 9822 bool Unsupported = false; 9823 APInt Result = 9824 calculateBinaryOperator(BinOp, LHS, RHS, SkipOperation, Unsupported); 9825 if (Unsupported) 9826 return false; 9827 // If SkipOperation is true, we can ignore this operand pair (L, R). 9828 if (!SkipOperation) 9829 unionAssumed(Result); 9830 return isValidState(); 9831 } 9832 9833 ChangeStatus updateWithICmpInst(Attributor &A, ICmpInst *ICI) { 9834 auto AssumedBefore = getAssumed(); 9835 Value *LHS = ICI->getOperand(0); 9836 Value *RHS = ICI->getOperand(1); 9837 9838 bool LHSContainsUndef = false, RHSContainsUndef = false; 9839 SetTy LHSAAPVS, RHSAAPVS; 9840 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS, 9841 LHSContainsUndef, /* ForSelf */ false) || 9842 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS, 9843 RHSContainsUndef, /* ForSelf */ false)) 9844 return indicatePessimisticFixpoint(); 9845 9846 // TODO: make use of undef flag to limit potential values aggressively. 9847 bool MaybeTrue = false, MaybeFalse = false; 9848 const APInt Zero(RHS->getType()->getIntegerBitWidth(), 0); 9849 if (LHSContainsUndef && RHSContainsUndef) { 9850 // The result of any comparison between undefs can be soundly replaced 9851 // with undef. 9852 unionAssumedWithUndef(); 9853 } else if (LHSContainsUndef) { 9854 for (const APInt &R : RHSAAPVS) { 9855 bool CmpResult = calculateICmpInst(ICI, Zero, R); 9856 MaybeTrue |= CmpResult; 9857 MaybeFalse |= !CmpResult; 9858 if (MaybeTrue & MaybeFalse) 9859 return indicatePessimisticFixpoint(); 9860 } 9861 } else if (RHSContainsUndef) { 9862 for (const APInt &L : LHSAAPVS) { 9863 bool CmpResult = calculateICmpInst(ICI, L, Zero); 9864 MaybeTrue |= CmpResult; 9865 MaybeFalse |= !CmpResult; 9866 if (MaybeTrue & MaybeFalse) 9867 return indicatePessimisticFixpoint(); 9868 } 9869 } else { 9870 for (const APInt &L : LHSAAPVS) { 9871 for (const APInt &R : RHSAAPVS) { 9872 bool CmpResult = calculateICmpInst(ICI, L, R); 9873 MaybeTrue |= CmpResult; 9874 MaybeFalse |= !CmpResult; 9875 if (MaybeTrue & MaybeFalse) 9876 return indicatePessimisticFixpoint(); 9877 } 9878 } 9879 } 9880 if (MaybeTrue) 9881 unionAssumed(APInt(/* numBits */ 1, /* val */ 1)); 9882 if (MaybeFalse) 9883 unionAssumed(APInt(/* numBits */ 1, /* val */ 0)); 9884 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 9885 : ChangeStatus::CHANGED; 9886 } 9887 9888 ChangeStatus updateWithSelectInst(Attributor &A, SelectInst *SI) { 9889 auto AssumedBefore = getAssumed(); 9890 Value *LHS = SI->getTrueValue(); 9891 Value *RHS = SI->getFalseValue(); 9892 9893 bool UsedAssumedInformation = false; 9894 std::optional<Constant *> C = A.getAssumedConstant( 9895 *SI->getCondition(), *this, UsedAssumedInformation); 9896 9897 // Check if we only need one operand. 9898 bool OnlyLeft = false, OnlyRight = false; 9899 if (C && *C && (*C)->isOneValue()) 9900 OnlyLeft = true; 9901 else if (C && *C && (*C)->isZeroValue()) 9902 OnlyRight = true; 9903 9904 bool LHSContainsUndef = false, RHSContainsUndef = false; 9905 SetTy LHSAAPVS, RHSAAPVS; 9906 if (!OnlyRight && 9907 !fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS, 9908 LHSContainsUndef, /* ForSelf */ false)) 9909 return indicatePessimisticFixpoint(); 9910 9911 if (!OnlyLeft && 9912 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS, 9913 RHSContainsUndef, /* ForSelf */ false)) 9914 return indicatePessimisticFixpoint(); 9915 9916 if (OnlyLeft || OnlyRight) { 9917 // select (true/false), lhs, rhs 9918 auto *OpAA = OnlyLeft ? &LHSAAPVS : &RHSAAPVS; 9919 auto Undef = OnlyLeft ? LHSContainsUndef : RHSContainsUndef; 9920 9921 if (Undef) 9922 unionAssumedWithUndef(); 9923 else { 9924 for (const auto &It : *OpAA) 9925 unionAssumed(It); 9926 } 9927 9928 } else if (LHSContainsUndef && RHSContainsUndef) { 9929 // select i1 *, undef , undef => undef 9930 unionAssumedWithUndef(); 9931 } else { 9932 for (const auto &It : LHSAAPVS) 9933 unionAssumed(It); 9934 for (const auto &It : RHSAAPVS) 9935 unionAssumed(It); 9936 } 9937 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 9938 : ChangeStatus::CHANGED; 9939 } 9940 9941 ChangeStatus updateWithCastInst(Attributor &A, CastInst *CI) { 9942 auto AssumedBefore = getAssumed(); 9943 if (!CI->isIntegerCast()) 9944 return indicatePessimisticFixpoint(); 9945 assert(CI->getNumOperands() == 1 && "Expected cast to be unary!"); 9946 uint32_t ResultBitWidth = CI->getDestTy()->getIntegerBitWidth(); 9947 Value *Src = CI->getOperand(0); 9948 9949 bool SrcContainsUndef = false; 9950 SetTy SrcPVS; 9951 if (!fillSetWithConstantValues(A, IRPosition::value(*Src), SrcPVS, 9952 SrcContainsUndef, /* ForSelf */ false)) 9953 return indicatePessimisticFixpoint(); 9954 9955 if (SrcContainsUndef) 9956 unionAssumedWithUndef(); 9957 else { 9958 for (const APInt &S : SrcPVS) { 9959 APInt T = calculateCastInst(CI, S, ResultBitWidth); 9960 unionAssumed(T); 9961 } 9962 } 9963 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 9964 : ChangeStatus::CHANGED; 9965 } 9966 9967 ChangeStatus updateWithBinaryOperator(Attributor &A, BinaryOperator *BinOp) { 9968 auto AssumedBefore = getAssumed(); 9969 Value *LHS = BinOp->getOperand(0); 9970 Value *RHS = BinOp->getOperand(1); 9971 9972 bool LHSContainsUndef = false, RHSContainsUndef = false; 9973 SetTy LHSAAPVS, RHSAAPVS; 9974 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS, 9975 LHSContainsUndef, /* ForSelf */ false) || 9976 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS, 9977 RHSContainsUndef, /* ForSelf */ false)) 9978 return indicatePessimisticFixpoint(); 9979 9980 const APInt Zero = APInt(LHS->getType()->getIntegerBitWidth(), 0); 9981 9982 // TODO: make use of undef flag to limit potential values aggressively. 9983 if (LHSContainsUndef && RHSContainsUndef) { 9984 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, Zero)) 9985 return indicatePessimisticFixpoint(); 9986 } else if (LHSContainsUndef) { 9987 for (const APInt &R : RHSAAPVS) { 9988 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, R)) 9989 return indicatePessimisticFixpoint(); 9990 } 9991 } else if (RHSContainsUndef) { 9992 for (const APInt &L : LHSAAPVS) { 9993 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, Zero)) 9994 return indicatePessimisticFixpoint(); 9995 } 9996 } else { 9997 for (const APInt &L : LHSAAPVS) { 9998 for (const APInt &R : RHSAAPVS) { 9999 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, R)) 10000 return indicatePessimisticFixpoint(); 10001 } 10002 } 10003 } 10004 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 10005 : ChangeStatus::CHANGED; 10006 } 10007 10008 ChangeStatus updateWithInstruction(Attributor &A, Instruction *Inst) { 10009 auto AssumedBefore = getAssumed(); 10010 SetTy Incoming; 10011 bool ContainsUndef; 10012 if (!fillSetWithConstantValues(A, IRPosition::value(*Inst), Incoming, 10013 ContainsUndef, /* ForSelf */ true)) 10014 return indicatePessimisticFixpoint(); 10015 if (ContainsUndef) { 10016 unionAssumedWithUndef(); 10017 } else { 10018 for (const auto &It : Incoming) 10019 unionAssumed(It); 10020 } 10021 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 10022 : ChangeStatus::CHANGED; 10023 } 10024 10025 /// See AbstractAttribute::updateImpl(...). 10026 ChangeStatus updateImpl(Attributor &A) override { 10027 Value &V = getAssociatedValue(); 10028 Instruction *I = dyn_cast<Instruction>(&V); 10029 10030 if (auto *ICI = dyn_cast<ICmpInst>(I)) 10031 return updateWithICmpInst(A, ICI); 10032 10033 if (auto *SI = dyn_cast<SelectInst>(I)) 10034 return updateWithSelectInst(A, SI); 10035 10036 if (auto *CI = dyn_cast<CastInst>(I)) 10037 return updateWithCastInst(A, CI); 10038 10039 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) 10040 return updateWithBinaryOperator(A, BinOp); 10041 10042 if (isa<PHINode>(I) || isa<LoadInst>(I)) 10043 return updateWithInstruction(A, I); 10044 10045 return indicatePessimisticFixpoint(); 10046 } 10047 10048 /// See AbstractAttribute::trackStatistics() 10049 void trackStatistics() const override { 10050 STATS_DECLTRACK_FLOATING_ATTR(potential_values) 10051 } 10052 }; 10053 10054 struct AAPotentialConstantValuesFunction : AAPotentialConstantValuesImpl { 10055 AAPotentialConstantValuesFunction(const IRPosition &IRP, Attributor &A) 10056 : AAPotentialConstantValuesImpl(IRP, A) {} 10057 10058 /// See AbstractAttribute::initialize(...). 10059 ChangeStatus updateImpl(Attributor &A) override { 10060 llvm_unreachable( 10061 "AAPotentialConstantValues(Function|CallSite)::updateImpl will " 10062 "not be called"); 10063 } 10064 10065 /// See AbstractAttribute::trackStatistics() 10066 void trackStatistics() const override { 10067 STATS_DECLTRACK_FN_ATTR(potential_values) 10068 } 10069 }; 10070 10071 struct AAPotentialConstantValuesCallSite : AAPotentialConstantValuesFunction { 10072 AAPotentialConstantValuesCallSite(const IRPosition &IRP, Attributor &A) 10073 : AAPotentialConstantValuesFunction(IRP, A) {} 10074 10075 /// See AbstractAttribute::trackStatistics() 10076 void trackStatistics() const override { 10077 STATS_DECLTRACK_CS_ATTR(potential_values) 10078 } 10079 }; 10080 10081 struct AAPotentialConstantValuesCallSiteReturned 10082 : AACalleeToCallSite<AAPotentialConstantValues, 10083 AAPotentialConstantValuesImpl> { 10084 AAPotentialConstantValuesCallSiteReturned(const IRPosition &IRP, 10085 Attributor &A) 10086 : AACalleeToCallSite<AAPotentialConstantValues, 10087 AAPotentialConstantValuesImpl>(IRP, A) {} 10088 10089 /// See AbstractAttribute::trackStatistics() 10090 void trackStatistics() const override { 10091 STATS_DECLTRACK_CSRET_ATTR(potential_values) 10092 } 10093 }; 10094 10095 struct AAPotentialConstantValuesCallSiteArgument 10096 : AAPotentialConstantValuesFloating { 10097 AAPotentialConstantValuesCallSiteArgument(const IRPosition &IRP, 10098 Attributor &A) 10099 : AAPotentialConstantValuesFloating(IRP, A) {} 10100 10101 /// See AbstractAttribute::initialize(..). 10102 void initialize(Attributor &A) override { 10103 AAPotentialConstantValuesImpl::initialize(A); 10104 if (isAtFixpoint()) 10105 return; 10106 10107 Value &V = getAssociatedValue(); 10108 10109 if (auto *C = dyn_cast<ConstantInt>(&V)) { 10110 unionAssumed(C->getValue()); 10111 indicateOptimisticFixpoint(); 10112 return; 10113 } 10114 10115 if (isa<UndefValue>(&V)) { 10116 unionAssumedWithUndef(); 10117 indicateOptimisticFixpoint(); 10118 return; 10119 } 10120 } 10121 10122 /// See AbstractAttribute::updateImpl(...). 10123 ChangeStatus updateImpl(Attributor &A) override { 10124 Value &V = getAssociatedValue(); 10125 auto AssumedBefore = getAssumed(); 10126 auto *AA = A.getAAFor<AAPotentialConstantValues>( 10127 *this, IRPosition::value(V), DepClassTy::REQUIRED); 10128 if (!AA) 10129 return indicatePessimisticFixpoint(); 10130 const auto &S = AA->getAssumed(); 10131 unionAssumed(S); 10132 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 10133 : ChangeStatus::CHANGED; 10134 } 10135 10136 /// See AbstractAttribute::trackStatistics() 10137 void trackStatistics() const override { 10138 STATS_DECLTRACK_CSARG_ATTR(potential_values) 10139 } 10140 }; 10141 } // namespace 10142 10143 /// ------------------------ NoUndef Attribute --------------------------------- 10144 bool AANoUndef::isImpliedByIR(Attributor &A, const IRPosition &IRP, 10145 Attribute::AttrKind ImpliedAttributeKind, 10146 bool IgnoreSubsumingPositions) { 10147 assert(ImpliedAttributeKind == Attribute::NoUndef && 10148 "Unexpected attribute kind"); 10149 if (A.hasAttr(IRP, {Attribute::NoUndef}, IgnoreSubsumingPositions, 10150 Attribute::NoUndef)) 10151 return true; 10152 10153 Value &Val = IRP.getAssociatedValue(); 10154 if (IRP.getPositionKind() != IRPosition::IRP_RETURNED && 10155 isGuaranteedNotToBeUndefOrPoison(&Val)) { 10156 LLVMContext &Ctx = Val.getContext(); 10157 A.manifestAttrs(IRP, Attribute::get(Ctx, Attribute::NoUndef)); 10158 return true; 10159 } 10160 10161 return false; 10162 } 10163 10164 namespace { 10165 struct AANoUndefImpl : AANoUndef { 10166 AANoUndefImpl(const IRPosition &IRP, Attributor &A) : AANoUndef(IRP, A) {} 10167 10168 /// See AbstractAttribute::initialize(...). 10169 void initialize(Attributor &A) override { 10170 Value &V = getAssociatedValue(); 10171 if (isa<UndefValue>(V)) 10172 indicatePessimisticFixpoint(); 10173 assert(!isImpliedByIR(A, getIRPosition(), Attribute::NoUndef)); 10174 } 10175 10176 /// See followUsesInMBEC 10177 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I, 10178 AANoUndef::StateType &State) { 10179 const Value *UseV = U->get(); 10180 const DominatorTree *DT = nullptr; 10181 AssumptionCache *AC = nullptr; 10182 InformationCache &InfoCache = A.getInfoCache(); 10183 if (Function *F = getAnchorScope()) { 10184 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F); 10185 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F); 10186 } 10187 State.setKnown(isGuaranteedNotToBeUndefOrPoison(UseV, AC, I, DT)); 10188 bool TrackUse = false; 10189 // Track use for instructions which must produce undef or poison bits when 10190 // at least one operand contains such bits. 10191 if (isa<CastInst>(*I) || isa<GetElementPtrInst>(*I)) 10192 TrackUse = true; 10193 return TrackUse; 10194 } 10195 10196 /// See AbstractAttribute::getAsStr(). 10197 const std::string getAsStr(Attributor *A) const override { 10198 return getAssumed() ? "noundef" : "may-undef-or-poison"; 10199 } 10200 10201 ChangeStatus manifest(Attributor &A) override { 10202 // We don't manifest noundef attribute for dead positions because the 10203 // associated values with dead positions would be replaced with undef 10204 // values. 10205 bool UsedAssumedInformation = false; 10206 if (A.isAssumedDead(getIRPosition(), nullptr, nullptr, 10207 UsedAssumedInformation)) 10208 return ChangeStatus::UNCHANGED; 10209 // A position whose simplified value does not have any value is 10210 // considered to be dead. We don't manifest noundef in such positions for 10211 // the same reason above. 10212 if (!A.getAssumedSimplified(getIRPosition(), *this, UsedAssumedInformation, 10213 AA::Interprocedural) 10214 .has_value()) 10215 return ChangeStatus::UNCHANGED; 10216 return AANoUndef::manifest(A); 10217 } 10218 }; 10219 10220 struct AANoUndefFloating : public AANoUndefImpl { 10221 AANoUndefFloating(const IRPosition &IRP, Attributor &A) 10222 : AANoUndefImpl(IRP, A) {} 10223 10224 /// See AbstractAttribute::initialize(...). 10225 void initialize(Attributor &A) override { 10226 AANoUndefImpl::initialize(A); 10227 if (!getState().isAtFixpoint() && getAnchorScope() && 10228 !getAnchorScope()->isDeclaration()) 10229 if (Instruction *CtxI = getCtxI()) 10230 followUsesInMBEC(*this, A, getState(), *CtxI); 10231 } 10232 10233 /// See AbstractAttribute::updateImpl(...). 10234 ChangeStatus updateImpl(Attributor &A) override { 10235 auto VisitValueCB = [&](const IRPosition &IRP) -> bool { 10236 bool IsKnownNoUndef; 10237 return AA::hasAssumedIRAttr<Attribute::NoUndef>( 10238 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoUndef); 10239 }; 10240 10241 bool Stripped; 10242 bool UsedAssumedInformation = false; 10243 Value *AssociatedValue = &getAssociatedValue(); 10244 SmallVector<AA::ValueAndContext> Values; 10245 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values, 10246 AA::AnyScope, UsedAssumedInformation)) 10247 Stripped = false; 10248 else 10249 Stripped = 10250 Values.size() != 1 || Values.front().getValue() != AssociatedValue; 10251 10252 if (!Stripped) { 10253 // If we haven't stripped anything we might still be able to use a 10254 // different AA, but only if the IRP changes. Effectively when we 10255 // interpret this not as a call site value but as a floating/argument 10256 // value. 10257 const IRPosition AVIRP = IRPosition::value(*AssociatedValue); 10258 if (AVIRP == getIRPosition() || !VisitValueCB(AVIRP)) 10259 return indicatePessimisticFixpoint(); 10260 return ChangeStatus::UNCHANGED; 10261 } 10262 10263 for (const auto &VAC : Values) 10264 if (!VisitValueCB(IRPosition::value(*VAC.getValue()))) 10265 return indicatePessimisticFixpoint(); 10266 10267 return ChangeStatus::UNCHANGED; 10268 } 10269 10270 /// See AbstractAttribute::trackStatistics() 10271 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) } 10272 }; 10273 10274 struct AANoUndefReturned final 10275 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl> { 10276 AANoUndefReturned(const IRPosition &IRP, Attributor &A) 10277 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl>(IRP, A) {} 10278 10279 /// See AbstractAttribute::trackStatistics() 10280 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) } 10281 }; 10282 10283 struct AANoUndefArgument final 10284 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl> { 10285 AANoUndefArgument(const IRPosition &IRP, Attributor &A) 10286 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl>(IRP, A) {} 10287 10288 /// See AbstractAttribute::trackStatistics() 10289 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noundef) } 10290 }; 10291 10292 struct AANoUndefCallSiteArgument final : AANoUndefFloating { 10293 AANoUndefCallSiteArgument(const IRPosition &IRP, Attributor &A) 10294 : AANoUndefFloating(IRP, A) {} 10295 10296 /// See AbstractAttribute::trackStatistics() 10297 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noundef) } 10298 }; 10299 10300 struct AANoUndefCallSiteReturned final 10301 : AACalleeToCallSite<AANoUndef, AANoUndefImpl> { 10302 AANoUndefCallSiteReturned(const IRPosition &IRP, Attributor &A) 10303 : AACalleeToCallSite<AANoUndef, AANoUndefImpl>(IRP, A) {} 10304 10305 /// See AbstractAttribute::trackStatistics() 10306 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) } 10307 }; 10308 10309 /// ------------------------ NoFPClass Attribute ------------------------------- 10310 10311 struct AANoFPClassImpl : AANoFPClass { 10312 AANoFPClassImpl(const IRPosition &IRP, Attributor &A) : AANoFPClass(IRP, A) {} 10313 10314 void initialize(Attributor &A) override { 10315 const IRPosition &IRP = getIRPosition(); 10316 10317 Value &V = IRP.getAssociatedValue(); 10318 if (isa<UndefValue>(V)) { 10319 indicateOptimisticFixpoint(); 10320 return; 10321 } 10322 10323 SmallVector<Attribute> Attrs; 10324 A.getAttrs(getIRPosition(), {Attribute::NoFPClass}, Attrs, false); 10325 for (const auto &Attr : Attrs) { 10326 addKnownBits(Attr.getNoFPClass()); 10327 } 10328 10329 const DataLayout &DL = A.getDataLayout(); 10330 if (getPositionKind() != IRPosition::IRP_RETURNED) { 10331 KnownFPClass KnownFPClass = computeKnownFPClass(&V, DL); 10332 addKnownBits(~KnownFPClass.KnownFPClasses); 10333 } 10334 10335 if (Instruction *CtxI = getCtxI()) 10336 followUsesInMBEC(*this, A, getState(), *CtxI); 10337 } 10338 10339 /// See followUsesInMBEC 10340 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I, 10341 AANoFPClass::StateType &State) { 10342 // TODO: Determine what instructions can be looked through. 10343 auto *CB = dyn_cast<CallBase>(I); 10344 if (!CB) 10345 return false; 10346 10347 if (!CB->isArgOperand(U)) 10348 return false; 10349 10350 unsigned ArgNo = CB->getArgOperandNo(U); 10351 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo); 10352 if (auto *NoFPAA = A.getAAFor<AANoFPClass>(*this, IRP, DepClassTy::NONE)) 10353 State.addKnownBits(NoFPAA->getState().getKnown()); 10354 return false; 10355 } 10356 10357 const std::string getAsStr(Attributor *A) const override { 10358 std::string Result = "nofpclass"; 10359 raw_string_ostream OS(Result); 10360 OS << getKnownNoFPClass() << '/' << getAssumedNoFPClass(); 10361 return Result; 10362 } 10363 10364 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, 10365 SmallVectorImpl<Attribute> &Attrs) const override { 10366 Attrs.emplace_back(Attribute::getWithNoFPClass(Ctx, getAssumedNoFPClass())); 10367 } 10368 }; 10369 10370 struct AANoFPClassFloating : public AANoFPClassImpl { 10371 AANoFPClassFloating(const IRPosition &IRP, Attributor &A) 10372 : AANoFPClassImpl(IRP, A) {} 10373 10374 /// See AbstractAttribute::updateImpl(...). 10375 ChangeStatus updateImpl(Attributor &A) override { 10376 SmallVector<AA::ValueAndContext> Values; 10377 bool UsedAssumedInformation = false; 10378 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values, 10379 AA::AnyScope, UsedAssumedInformation)) { 10380 Values.push_back({getAssociatedValue(), getCtxI()}); 10381 } 10382 10383 StateType T; 10384 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool { 10385 const auto *AA = A.getAAFor<AANoFPClass>(*this, IRPosition::value(V), 10386 DepClassTy::REQUIRED); 10387 if (!AA || this == AA) { 10388 T.indicatePessimisticFixpoint(); 10389 } else { 10390 const AANoFPClass::StateType &S = 10391 static_cast<const AANoFPClass::StateType &>(AA->getState()); 10392 T ^= S; 10393 } 10394 return T.isValidState(); 10395 }; 10396 10397 for (const auto &VAC : Values) 10398 if (!VisitValueCB(*VAC.getValue(), VAC.getCtxI())) 10399 return indicatePessimisticFixpoint(); 10400 10401 return clampStateAndIndicateChange(getState(), T); 10402 } 10403 10404 /// See AbstractAttribute::trackStatistics() 10405 void trackStatistics() const override { 10406 STATS_DECLTRACK_FNRET_ATTR(nofpclass) 10407 } 10408 }; 10409 10410 struct AANoFPClassReturned final 10411 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl, 10412 AANoFPClassImpl::StateType, false, 10413 Attribute::None, false> { 10414 AANoFPClassReturned(const IRPosition &IRP, Attributor &A) 10415 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl, 10416 AANoFPClassImpl::StateType, false, 10417 Attribute::None, false>(IRP, A) {} 10418 10419 /// See AbstractAttribute::trackStatistics() 10420 void trackStatistics() const override { 10421 STATS_DECLTRACK_FNRET_ATTR(nofpclass) 10422 } 10423 }; 10424 10425 struct AANoFPClassArgument final 10426 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl> { 10427 AANoFPClassArgument(const IRPosition &IRP, Attributor &A) 10428 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl>(IRP, A) {} 10429 10430 /// See AbstractAttribute::trackStatistics() 10431 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofpclass) } 10432 }; 10433 10434 struct AANoFPClassCallSiteArgument final : AANoFPClassFloating { 10435 AANoFPClassCallSiteArgument(const IRPosition &IRP, Attributor &A) 10436 : AANoFPClassFloating(IRP, A) {} 10437 10438 /// See AbstractAttribute::trackStatistics() 10439 void trackStatistics() const override { 10440 STATS_DECLTRACK_CSARG_ATTR(nofpclass) 10441 } 10442 }; 10443 10444 struct AANoFPClassCallSiteReturned final 10445 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl> { 10446 AANoFPClassCallSiteReturned(const IRPosition &IRP, Attributor &A) 10447 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl>(IRP, A) {} 10448 10449 /// See AbstractAttribute::trackStatistics() 10450 void trackStatistics() const override { 10451 STATS_DECLTRACK_CSRET_ATTR(nofpclass) 10452 } 10453 }; 10454 10455 struct AACallEdgesImpl : public AACallEdges { 10456 AACallEdgesImpl(const IRPosition &IRP, Attributor &A) : AACallEdges(IRP, A) {} 10457 10458 const SetVector<Function *> &getOptimisticEdges() const override { 10459 return CalledFunctions; 10460 } 10461 10462 bool hasUnknownCallee() const override { return HasUnknownCallee; } 10463 10464 bool hasNonAsmUnknownCallee() const override { 10465 return HasUnknownCalleeNonAsm; 10466 } 10467 10468 const std::string getAsStr(Attributor *A) const override { 10469 return "CallEdges[" + std::to_string(HasUnknownCallee) + "," + 10470 std::to_string(CalledFunctions.size()) + "]"; 10471 } 10472 10473 void trackStatistics() const override {} 10474 10475 protected: 10476 void addCalledFunction(Function *Fn, ChangeStatus &Change) { 10477 if (CalledFunctions.insert(Fn)) { 10478 Change = ChangeStatus::CHANGED; 10479 LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn->getName() 10480 << "\n"); 10481 } 10482 } 10483 10484 void setHasUnknownCallee(bool NonAsm, ChangeStatus &Change) { 10485 if (!HasUnknownCallee) 10486 Change = ChangeStatus::CHANGED; 10487 if (NonAsm && !HasUnknownCalleeNonAsm) 10488 Change = ChangeStatus::CHANGED; 10489 HasUnknownCalleeNonAsm |= NonAsm; 10490 HasUnknownCallee = true; 10491 } 10492 10493 private: 10494 /// Optimistic set of functions that might be called by this position. 10495 SetVector<Function *> CalledFunctions; 10496 10497 /// Is there any call with a unknown callee. 10498 bool HasUnknownCallee = false; 10499 10500 /// Is there any call with a unknown callee, excluding any inline asm. 10501 bool HasUnknownCalleeNonAsm = false; 10502 }; 10503 10504 struct AACallEdgesCallSite : public AACallEdgesImpl { 10505 AACallEdgesCallSite(const IRPosition &IRP, Attributor &A) 10506 : AACallEdgesImpl(IRP, A) {} 10507 /// See AbstractAttribute::updateImpl(...). 10508 ChangeStatus updateImpl(Attributor &A) override { 10509 ChangeStatus Change = ChangeStatus::UNCHANGED; 10510 10511 auto VisitValue = [&](Value &V, const Instruction *CtxI) -> bool { 10512 if (Function *Fn = dyn_cast<Function>(&V)) { 10513 addCalledFunction(Fn, Change); 10514 } else { 10515 LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n"); 10516 setHasUnknownCallee(true, Change); 10517 } 10518 10519 // Explore all values. 10520 return true; 10521 }; 10522 10523 SmallVector<AA::ValueAndContext> Values; 10524 // Process any value that we might call. 10525 auto ProcessCalledOperand = [&](Value *V, Instruction *CtxI) { 10526 if (isa<Constant>(V)) { 10527 VisitValue(*V, CtxI); 10528 return; 10529 } 10530 10531 bool UsedAssumedInformation = false; 10532 Values.clear(); 10533 if (!A.getAssumedSimplifiedValues(IRPosition::value(*V), *this, Values, 10534 AA::AnyScope, UsedAssumedInformation)) { 10535 Values.push_back({*V, CtxI}); 10536 } 10537 for (auto &VAC : Values) 10538 VisitValue(*VAC.getValue(), VAC.getCtxI()); 10539 }; 10540 10541 CallBase *CB = cast<CallBase>(getCtxI()); 10542 10543 if (auto *IA = dyn_cast<InlineAsm>(CB->getCalledOperand())) { 10544 if (IA->hasSideEffects() && 10545 !hasAssumption(*CB->getCaller(), "ompx_no_call_asm") && 10546 !hasAssumption(*CB, "ompx_no_call_asm")) { 10547 setHasUnknownCallee(false, Change); 10548 } 10549 return Change; 10550 } 10551 10552 if (CB->isIndirectCall()) 10553 if (auto *IndirectCallAA = A.getAAFor<AAIndirectCallInfo>( 10554 *this, getIRPosition(), DepClassTy::OPTIONAL)) 10555 if (IndirectCallAA->foreachCallee( 10556 [&](Function *Fn) { return VisitValue(*Fn, CB); })) 10557 return Change; 10558 10559 // The most simple case. 10560 ProcessCalledOperand(CB->getCalledOperand(), CB); 10561 10562 // Process callback functions. 10563 SmallVector<const Use *, 4u> CallbackUses; 10564 AbstractCallSite::getCallbackUses(*CB, CallbackUses); 10565 for (const Use *U : CallbackUses) 10566 ProcessCalledOperand(U->get(), CB); 10567 10568 return Change; 10569 } 10570 }; 10571 10572 struct AACallEdgesFunction : public AACallEdgesImpl { 10573 AACallEdgesFunction(const IRPosition &IRP, Attributor &A) 10574 : AACallEdgesImpl(IRP, A) {} 10575 10576 /// See AbstractAttribute::updateImpl(...). 10577 ChangeStatus updateImpl(Attributor &A) override { 10578 ChangeStatus Change = ChangeStatus::UNCHANGED; 10579 10580 auto ProcessCallInst = [&](Instruction &Inst) { 10581 CallBase &CB = cast<CallBase>(Inst); 10582 10583 auto *CBEdges = A.getAAFor<AACallEdges>( 10584 *this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED); 10585 if (!CBEdges) 10586 return false; 10587 if (CBEdges->hasNonAsmUnknownCallee()) 10588 setHasUnknownCallee(true, Change); 10589 if (CBEdges->hasUnknownCallee()) 10590 setHasUnknownCallee(false, Change); 10591 10592 for (Function *F : CBEdges->getOptimisticEdges()) 10593 addCalledFunction(F, Change); 10594 10595 return true; 10596 }; 10597 10598 // Visit all callable instructions. 10599 bool UsedAssumedInformation = false; 10600 if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this, 10601 UsedAssumedInformation, 10602 /* CheckBBLivenessOnly */ true)) { 10603 // If we haven't looked at all call like instructions, assume that there 10604 // are unknown callees. 10605 setHasUnknownCallee(true, Change); 10606 } 10607 10608 return Change; 10609 } 10610 }; 10611 10612 /// -------------------AAInterFnReachability Attribute-------------------------- 10613 10614 struct AAInterFnReachabilityFunction 10615 : public CachedReachabilityAA<AAInterFnReachability, Function> { 10616 using Base = CachedReachabilityAA<AAInterFnReachability, Function>; 10617 AAInterFnReachabilityFunction(const IRPosition &IRP, Attributor &A) 10618 : Base(IRP, A) {} 10619 10620 bool instructionCanReach( 10621 Attributor &A, const Instruction &From, const Function &To, 10622 const AA::InstExclusionSetTy *ExclusionSet) const override { 10623 assert(From.getFunction() == getAnchorScope() && "Queried the wrong AA!"); 10624 auto *NonConstThis = const_cast<AAInterFnReachabilityFunction *>(this); 10625 10626 RQITy StackRQI(A, From, To, ExclusionSet, false); 10627 typename RQITy::Reachable Result; 10628 if (!NonConstThis->checkQueryCache(A, StackRQI, Result)) 10629 return NonConstThis->isReachableImpl(A, StackRQI, 10630 /*IsTemporaryRQI=*/true); 10631 return Result == RQITy::Reachable::Yes; 10632 } 10633 10634 bool isReachableImpl(Attributor &A, RQITy &RQI, 10635 bool IsTemporaryRQI) override { 10636 const Instruction *EntryI = 10637 &RQI.From->getFunction()->getEntryBlock().front(); 10638 if (EntryI != RQI.From && 10639 !instructionCanReach(A, *EntryI, *RQI.To, nullptr)) 10640 return rememberResult(A, RQITy::Reachable::No, RQI, false, 10641 IsTemporaryRQI); 10642 10643 auto CheckReachableCallBase = [&](CallBase *CB) { 10644 auto *CBEdges = A.getAAFor<AACallEdges>( 10645 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL); 10646 if (!CBEdges || !CBEdges->getState().isValidState()) 10647 return false; 10648 // TODO Check To backwards in this case. 10649 if (CBEdges->hasUnknownCallee()) 10650 return false; 10651 10652 for (Function *Fn : CBEdges->getOptimisticEdges()) { 10653 if (Fn == RQI.To) 10654 return false; 10655 10656 if (Fn->isDeclaration()) { 10657 if (Fn->hasFnAttribute(Attribute::NoCallback)) 10658 continue; 10659 // TODO Check To backwards in this case. 10660 return false; 10661 } 10662 10663 if (Fn == getAnchorScope()) { 10664 if (EntryI == RQI.From) 10665 continue; 10666 return false; 10667 } 10668 10669 const AAInterFnReachability *InterFnReachability = 10670 A.getAAFor<AAInterFnReachability>(*this, IRPosition::function(*Fn), 10671 DepClassTy::OPTIONAL); 10672 10673 const Instruction &FnFirstInst = Fn->getEntryBlock().front(); 10674 if (!InterFnReachability || 10675 InterFnReachability->instructionCanReach(A, FnFirstInst, *RQI.To, 10676 RQI.ExclusionSet)) 10677 return false; 10678 } 10679 return true; 10680 }; 10681 10682 const auto *IntraFnReachability = A.getAAFor<AAIntraFnReachability>( 10683 *this, IRPosition::function(*RQI.From->getFunction()), 10684 DepClassTy::OPTIONAL); 10685 10686 // Determine call like instructions that we can reach from the inst. 10687 auto CheckCallBase = [&](Instruction &CBInst) { 10688 // There are usually less nodes in the call graph, check inter function 10689 // reachability first. 10690 if (CheckReachableCallBase(cast<CallBase>(&CBInst))) 10691 return true; 10692 return IntraFnReachability && !IntraFnReachability->isAssumedReachable( 10693 A, *RQI.From, CBInst, RQI.ExclusionSet); 10694 }; 10695 10696 bool UsedExclusionSet = /* conservative */ true; 10697 bool UsedAssumedInformation = false; 10698 if (!A.checkForAllCallLikeInstructions(CheckCallBase, *this, 10699 UsedAssumedInformation, 10700 /* CheckBBLivenessOnly */ true)) 10701 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet, 10702 IsTemporaryRQI); 10703 10704 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet, 10705 IsTemporaryRQI); 10706 } 10707 10708 void trackStatistics() const override {} 10709 }; 10710 } // namespace 10711 10712 template <typename AAType> 10713 static std::optional<Constant *> 10714 askForAssumedConstant(Attributor &A, const AbstractAttribute &QueryingAA, 10715 const IRPosition &IRP, Type &Ty) { 10716 if (!Ty.isIntegerTy()) 10717 return nullptr; 10718 10719 // This will also pass the call base context. 10720 const auto *AA = A.getAAFor<AAType>(QueryingAA, IRP, DepClassTy::NONE); 10721 if (!AA) 10722 return nullptr; 10723 10724 std::optional<Constant *> COpt = AA->getAssumedConstant(A); 10725 10726 if (!COpt.has_value()) { 10727 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL); 10728 return std::nullopt; 10729 } 10730 if (auto *C = *COpt) { 10731 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL); 10732 return C; 10733 } 10734 return nullptr; 10735 } 10736 10737 Value *AAPotentialValues::getSingleValue( 10738 Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP, 10739 SmallVectorImpl<AA::ValueAndContext> &Values) { 10740 Type &Ty = *IRP.getAssociatedType(); 10741 std::optional<Value *> V; 10742 for (auto &It : Values) { 10743 V = AA::combineOptionalValuesInAAValueLatice(V, It.getValue(), &Ty); 10744 if (V.has_value() && !*V) 10745 break; 10746 } 10747 if (!V.has_value()) 10748 return UndefValue::get(&Ty); 10749 return *V; 10750 } 10751 10752 namespace { 10753 struct AAPotentialValuesImpl : AAPotentialValues { 10754 using StateType = PotentialLLVMValuesState; 10755 10756 AAPotentialValuesImpl(const IRPosition &IRP, Attributor &A) 10757 : AAPotentialValues(IRP, A) {} 10758 10759 /// See AbstractAttribute::initialize(..). 10760 void initialize(Attributor &A) override { 10761 if (A.hasSimplificationCallback(getIRPosition())) { 10762 indicatePessimisticFixpoint(); 10763 return; 10764 } 10765 Value *Stripped = getAssociatedValue().stripPointerCasts(); 10766 if (isa<Constant>(Stripped) && !isa<ConstantExpr>(Stripped)) { 10767 addValue(A, getState(), *Stripped, getCtxI(), AA::AnyScope, 10768 getAnchorScope()); 10769 indicateOptimisticFixpoint(); 10770 return; 10771 } 10772 AAPotentialValues::initialize(A); 10773 } 10774 10775 /// See AbstractAttribute::getAsStr(). 10776 const std::string getAsStr(Attributor *A) const override { 10777 std::string Str; 10778 llvm::raw_string_ostream OS(Str); 10779 OS << getState(); 10780 return Str; 10781 } 10782 10783 template <typename AAType> 10784 static std::optional<Value *> askOtherAA(Attributor &A, 10785 const AbstractAttribute &AA, 10786 const IRPosition &IRP, Type &Ty) { 10787 if (isa<Constant>(IRP.getAssociatedValue())) 10788 return &IRP.getAssociatedValue(); 10789 std::optional<Constant *> C = askForAssumedConstant<AAType>(A, AA, IRP, Ty); 10790 if (!C) 10791 return std::nullopt; 10792 if (*C) 10793 if (auto *CC = AA::getWithType(**C, Ty)) 10794 return CC; 10795 return nullptr; 10796 } 10797 10798 virtual void addValue(Attributor &A, StateType &State, Value &V, 10799 const Instruction *CtxI, AA::ValueScope S, 10800 Function *AnchorScope) const { 10801 10802 IRPosition ValIRP = IRPosition::value(V); 10803 if (auto *CB = dyn_cast_or_null<CallBase>(CtxI)) { 10804 for (const auto &U : CB->args()) { 10805 if (U.get() != &V) 10806 continue; 10807 ValIRP = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U)); 10808 break; 10809 } 10810 } 10811 10812 Value *VPtr = &V; 10813 if (ValIRP.getAssociatedType()->isIntegerTy()) { 10814 Type &Ty = *getAssociatedType(); 10815 std::optional<Value *> SimpleV = 10816 askOtherAA<AAValueConstantRange>(A, *this, ValIRP, Ty); 10817 if (SimpleV.has_value() && !*SimpleV) { 10818 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>( 10819 *this, ValIRP, DepClassTy::OPTIONAL); 10820 if (PotentialConstantsAA && PotentialConstantsAA->isValidState()) { 10821 for (const auto &It : PotentialConstantsAA->getAssumedSet()) 10822 State.unionAssumed({{*ConstantInt::get(&Ty, It), nullptr}, S}); 10823 if (PotentialConstantsAA->undefIsContained()) 10824 State.unionAssumed({{*UndefValue::get(&Ty), nullptr}, S}); 10825 return; 10826 } 10827 } 10828 if (!SimpleV.has_value()) 10829 return; 10830 10831 if (*SimpleV) 10832 VPtr = *SimpleV; 10833 } 10834 10835 if (isa<ConstantInt>(VPtr)) 10836 CtxI = nullptr; 10837 if (!AA::isValidInScope(*VPtr, AnchorScope)) 10838 S = AA::ValueScope(S | AA::Interprocedural); 10839 10840 State.unionAssumed({{*VPtr, CtxI}, S}); 10841 } 10842 10843 /// Helper struct to tie a value+context pair together with the scope for 10844 /// which this is the simplified version. 10845 struct ItemInfo { 10846 AA::ValueAndContext I; 10847 AA::ValueScope S; 10848 10849 bool operator==(const ItemInfo &II) const { 10850 return II.I == I && II.S == S; 10851 }; 10852 bool operator<(const ItemInfo &II) const { 10853 if (I == II.I) 10854 return S < II.S; 10855 return I < II.I; 10856 }; 10857 }; 10858 10859 bool recurseForValue(Attributor &A, const IRPosition &IRP, AA::ValueScope S) { 10860 SmallMapVector<AA::ValueAndContext, int, 8> ValueScopeMap; 10861 for (auto CS : {AA::Intraprocedural, AA::Interprocedural}) { 10862 if (!(CS & S)) 10863 continue; 10864 10865 bool UsedAssumedInformation = false; 10866 SmallVector<AA::ValueAndContext> Values; 10867 if (!A.getAssumedSimplifiedValues(IRP, this, Values, CS, 10868 UsedAssumedInformation)) 10869 return false; 10870 10871 for (auto &It : Values) 10872 ValueScopeMap[It] += CS; 10873 } 10874 for (auto &It : ValueScopeMap) 10875 addValue(A, getState(), *It.first.getValue(), It.first.getCtxI(), 10876 AA::ValueScope(It.second), getAnchorScope()); 10877 10878 return true; 10879 } 10880 10881 void giveUpOnIntraprocedural(Attributor &A) { 10882 auto NewS = StateType::getBestState(getState()); 10883 for (const auto &It : getAssumedSet()) { 10884 if (It.second == AA::Intraprocedural) 10885 continue; 10886 addValue(A, NewS, *It.first.getValue(), It.first.getCtxI(), 10887 AA::Interprocedural, getAnchorScope()); 10888 } 10889 assert(!undefIsContained() && "Undef should be an explicit value!"); 10890 addValue(A, NewS, getAssociatedValue(), getCtxI(), AA::Intraprocedural, 10891 getAnchorScope()); 10892 getState() = NewS; 10893 } 10894 10895 /// See AbstractState::indicatePessimisticFixpoint(...). 10896 ChangeStatus indicatePessimisticFixpoint() override { 10897 getState() = StateType::getBestState(getState()); 10898 getState().unionAssumed({{getAssociatedValue(), getCtxI()}, AA::AnyScope}); 10899 AAPotentialValues::indicateOptimisticFixpoint(); 10900 return ChangeStatus::CHANGED; 10901 } 10902 10903 /// See AbstractAttribute::updateImpl(...). 10904 ChangeStatus updateImpl(Attributor &A) override { 10905 return indicatePessimisticFixpoint(); 10906 } 10907 10908 /// See AbstractAttribute::manifest(...). 10909 ChangeStatus manifest(Attributor &A) override { 10910 SmallVector<AA::ValueAndContext> Values; 10911 for (AA::ValueScope S : {AA::Interprocedural, AA::Intraprocedural}) { 10912 Values.clear(); 10913 if (!getAssumedSimplifiedValues(A, Values, S)) 10914 continue; 10915 Value &OldV = getAssociatedValue(); 10916 if (isa<UndefValue>(OldV)) 10917 continue; 10918 Value *NewV = getSingleValue(A, *this, getIRPosition(), Values); 10919 if (!NewV || NewV == &OldV) 10920 continue; 10921 if (getCtxI() && 10922 !AA::isValidAtPosition({*NewV, *getCtxI()}, A.getInfoCache())) 10923 continue; 10924 if (A.changeAfterManifest(getIRPosition(), *NewV)) 10925 return ChangeStatus::CHANGED; 10926 } 10927 return ChangeStatus::UNCHANGED; 10928 } 10929 10930 bool getAssumedSimplifiedValues( 10931 Attributor &A, SmallVectorImpl<AA::ValueAndContext> &Values, 10932 AA::ValueScope S, bool RecurseForSelectAndPHI = false) const override { 10933 if (!isValidState()) 10934 return false; 10935 bool UsedAssumedInformation = false; 10936 for (const auto &It : getAssumedSet()) 10937 if (It.second & S) { 10938 if (RecurseForSelectAndPHI && (isa<PHINode>(It.first.getValue()) || 10939 isa<SelectInst>(It.first.getValue()))) { 10940 if (A.getAssumedSimplifiedValues( 10941 IRPosition::inst(*cast<Instruction>(It.first.getValue())), 10942 this, Values, S, UsedAssumedInformation)) 10943 continue; 10944 } 10945 Values.push_back(It.first); 10946 } 10947 assert(!undefIsContained() && "Undef should be an explicit value!"); 10948 return true; 10949 } 10950 }; 10951 10952 struct AAPotentialValuesFloating : AAPotentialValuesImpl { 10953 AAPotentialValuesFloating(const IRPosition &IRP, Attributor &A) 10954 : AAPotentialValuesImpl(IRP, A) {} 10955 10956 /// See AbstractAttribute::updateImpl(...). 10957 ChangeStatus updateImpl(Attributor &A) override { 10958 auto AssumedBefore = getAssumed(); 10959 10960 genericValueTraversal(A, &getAssociatedValue()); 10961 10962 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED 10963 : ChangeStatus::CHANGED; 10964 } 10965 10966 /// Helper struct to remember which AAIsDead instances we actually used. 10967 struct LivenessInfo { 10968 const AAIsDead *LivenessAA = nullptr; 10969 bool AnyDead = false; 10970 }; 10971 10972 /// Check if \p Cmp is a comparison we can simplify. 10973 /// 10974 /// We handle multiple cases, one in which at least one operand is an 10975 /// (assumed) nullptr. If so, try to simplify it using AANonNull on the other 10976 /// operand. Return true if successful, in that case Worklist will be updated. 10977 bool handleCmp(Attributor &A, Value &Cmp, Value *LHS, Value *RHS, 10978 CmpInst::Predicate Pred, ItemInfo II, 10979 SmallVectorImpl<ItemInfo> &Worklist) { 10980 10981 // Simplify the operands first. 10982 bool UsedAssumedInformation = false; 10983 SmallVector<AA::ValueAndContext> LHSValues, RHSValues; 10984 auto GetSimplifiedValues = [&](Value &V, 10985 SmallVector<AA::ValueAndContext> &Values) { 10986 if (!A.getAssumedSimplifiedValues( 10987 IRPosition::value(V, getCallBaseContext()), this, Values, 10988 AA::Intraprocedural, UsedAssumedInformation)) { 10989 Values.clear(); 10990 Values.push_back(AA::ValueAndContext{V, II.I.getCtxI()}); 10991 } 10992 return Values.empty(); 10993 }; 10994 if (GetSimplifiedValues(*LHS, LHSValues)) 10995 return true; 10996 if (GetSimplifiedValues(*RHS, RHSValues)) 10997 return true; 10998 10999 LLVMContext &Ctx = LHS->getContext(); 11000 11001 InformationCache &InfoCache = A.getInfoCache(); 11002 Instruction *CmpI = dyn_cast<Instruction>(&Cmp); 11003 Function *F = CmpI ? CmpI->getFunction() : nullptr; 11004 const auto *DT = 11005 F ? InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F) 11006 : nullptr; 11007 const auto *TLI = 11008 F ? A.getInfoCache().getTargetLibraryInfoForFunction(*F) : nullptr; 11009 auto *AC = 11010 F ? InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F) 11011 : nullptr; 11012 11013 const DataLayout &DL = A.getDataLayout(); 11014 SimplifyQuery Q(DL, TLI, DT, AC, CmpI); 11015 11016 auto CheckPair = [&](Value &LHSV, Value &RHSV) { 11017 if (isa<UndefValue>(LHSV) || isa<UndefValue>(RHSV)) { 11018 addValue(A, getState(), *UndefValue::get(Cmp.getType()), 11019 /* CtxI */ nullptr, II.S, getAnchorScope()); 11020 return true; 11021 } 11022 11023 // Handle the trivial case first in which we don't even need to think 11024 // about null or non-null. 11025 if (&LHSV == &RHSV && 11026 (CmpInst::isTrueWhenEqual(Pred) || CmpInst::isFalseWhenEqual(Pred))) { 11027 Constant *NewV = ConstantInt::get(Type::getInt1Ty(Ctx), 11028 CmpInst::isTrueWhenEqual(Pred)); 11029 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S, 11030 getAnchorScope()); 11031 return true; 11032 } 11033 11034 auto *TypedLHS = AA::getWithType(LHSV, *LHS->getType()); 11035 auto *TypedRHS = AA::getWithType(RHSV, *RHS->getType()); 11036 if (TypedLHS && TypedRHS) { 11037 Value *NewV = simplifyCmpInst(Pred, TypedLHS, TypedRHS, Q); 11038 if (NewV && NewV != &Cmp) { 11039 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S, 11040 getAnchorScope()); 11041 return true; 11042 } 11043 } 11044 11045 // From now on we only handle equalities (==, !=). 11046 if (!CmpInst::isEquality(Pred)) 11047 return false; 11048 11049 bool LHSIsNull = isa<ConstantPointerNull>(LHSV); 11050 bool RHSIsNull = isa<ConstantPointerNull>(RHSV); 11051 if (!LHSIsNull && !RHSIsNull) 11052 return false; 11053 11054 // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the 11055 // non-nullptr operand and if we assume it's non-null we can conclude the 11056 // result of the comparison. 11057 assert((LHSIsNull || RHSIsNull) && 11058 "Expected nullptr versus non-nullptr comparison at this point"); 11059 11060 // The index is the operand that we assume is not null. 11061 unsigned PtrIdx = LHSIsNull; 11062 bool IsKnownNonNull; 11063 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>( 11064 A, this, IRPosition::value(*(PtrIdx ? &RHSV : &LHSV)), 11065 DepClassTy::REQUIRED, IsKnownNonNull); 11066 if (!IsAssumedNonNull) 11067 return false; 11068 11069 // The new value depends on the predicate, true for != and false for ==. 11070 Constant *NewV = 11071 ConstantInt::get(Type::getInt1Ty(Ctx), Pred == CmpInst::ICMP_NE); 11072 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S, 11073 getAnchorScope()); 11074 return true; 11075 }; 11076 11077 for (auto &LHSValue : LHSValues) 11078 for (auto &RHSValue : RHSValues) 11079 if (!CheckPair(*LHSValue.getValue(), *RHSValue.getValue())) 11080 return false; 11081 return true; 11082 } 11083 11084 bool handleSelectInst(Attributor &A, SelectInst &SI, ItemInfo II, 11085 SmallVectorImpl<ItemInfo> &Worklist) { 11086 const Instruction *CtxI = II.I.getCtxI(); 11087 bool UsedAssumedInformation = false; 11088 11089 std::optional<Constant *> C = 11090 A.getAssumedConstant(*SI.getCondition(), *this, UsedAssumedInformation); 11091 bool NoValueYet = !C.has_value(); 11092 if (NoValueYet || isa_and_nonnull<UndefValue>(*C)) 11093 return true; 11094 if (auto *CI = dyn_cast_or_null<ConstantInt>(*C)) { 11095 if (CI->isZero()) 11096 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S}); 11097 else 11098 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S}); 11099 } else if (&SI == &getAssociatedValue()) { 11100 // We could not simplify the condition, assume both values. 11101 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S}); 11102 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S}); 11103 } else { 11104 std::optional<Value *> SimpleV = A.getAssumedSimplified( 11105 IRPosition::inst(SI), *this, UsedAssumedInformation, II.S); 11106 if (!SimpleV.has_value()) 11107 return true; 11108 if (*SimpleV) { 11109 addValue(A, getState(), **SimpleV, CtxI, II.S, getAnchorScope()); 11110 return true; 11111 } 11112 return false; 11113 } 11114 return true; 11115 } 11116 11117 bool handleLoadInst(Attributor &A, LoadInst &LI, ItemInfo II, 11118 SmallVectorImpl<ItemInfo> &Worklist) { 11119 SmallSetVector<Value *, 4> PotentialCopies; 11120 SmallSetVector<Instruction *, 4> PotentialValueOrigins; 11121 bool UsedAssumedInformation = false; 11122 if (!AA::getPotentiallyLoadedValues(A, LI, PotentialCopies, 11123 PotentialValueOrigins, *this, 11124 UsedAssumedInformation, 11125 /* OnlyExact */ true)) { 11126 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Failed to get potentially " 11127 "loaded values for load instruction " 11128 << LI << "\n"); 11129 return false; 11130 } 11131 11132 // Do not simplify loads that are only used in llvm.assume if we cannot also 11133 // remove all stores that may feed into the load. The reason is that the 11134 // assume is probably worth something as long as the stores are around. 11135 InformationCache &InfoCache = A.getInfoCache(); 11136 if (InfoCache.isOnlyUsedByAssume(LI)) { 11137 if (!llvm::all_of(PotentialValueOrigins, [&](Instruction *I) { 11138 if (!I || isa<AssumeInst>(I)) 11139 return true; 11140 if (auto *SI = dyn_cast<StoreInst>(I)) 11141 return A.isAssumedDead(SI->getOperandUse(0), this, 11142 /* LivenessAA */ nullptr, 11143 UsedAssumedInformation, 11144 /* CheckBBLivenessOnly */ false); 11145 return A.isAssumedDead(*I, this, /* LivenessAA */ nullptr, 11146 UsedAssumedInformation, 11147 /* CheckBBLivenessOnly */ false); 11148 })) { 11149 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Load is onl used by assumes " 11150 "and we cannot delete all the stores: " 11151 << LI << "\n"); 11152 return false; 11153 } 11154 } 11155 11156 // Values have to be dynamically unique or we loose the fact that a 11157 // single llvm::Value might represent two runtime values (e.g., 11158 // stack locations in different recursive calls). 11159 const Instruction *CtxI = II.I.getCtxI(); 11160 bool ScopeIsLocal = (II.S & AA::Intraprocedural); 11161 bool AllLocal = ScopeIsLocal; 11162 bool DynamicallyUnique = llvm::all_of(PotentialCopies, [&](Value *PC) { 11163 AllLocal &= AA::isValidInScope(*PC, getAnchorScope()); 11164 return AA::isDynamicallyUnique(A, *this, *PC); 11165 }); 11166 if (!DynamicallyUnique) { 11167 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Not all potentially loaded " 11168 "values are dynamically unique: " 11169 << LI << "\n"); 11170 return false; 11171 } 11172 11173 for (auto *PotentialCopy : PotentialCopies) { 11174 if (AllLocal) { 11175 Worklist.push_back({{*PotentialCopy, CtxI}, II.S}); 11176 } else { 11177 Worklist.push_back({{*PotentialCopy, CtxI}, AA::Interprocedural}); 11178 } 11179 } 11180 if (!AllLocal && ScopeIsLocal) 11181 addValue(A, getState(), LI, CtxI, AA::Intraprocedural, getAnchorScope()); 11182 return true; 11183 } 11184 11185 bool handlePHINode( 11186 Attributor &A, PHINode &PHI, ItemInfo II, 11187 SmallVectorImpl<ItemInfo> &Worklist, 11188 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) { 11189 auto GetLivenessInfo = [&](const Function &F) -> LivenessInfo & { 11190 LivenessInfo &LI = LivenessAAs[&F]; 11191 if (!LI.LivenessAA) 11192 LI.LivenessAA = A.getAAFor<AAIsDead>(*this, IRPosition::function(F), 11193 DepClassTy::NONE); 11194 return LI; 11195 }; 11196 11197 if (&PHI == &getAssociatedValue()) { 11198 LivenessInfo &LI = GetLivenessInfo(*PHI.getFunction()); 11199 const auto *CI = 11200 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>( 11201 *PHI.getFunction()); 11202 11203 Cycle *C = nullptr; 11204 bool CyclePHI = mayBeInCycle(CI, &PHI, /* HeaderOnly */ true, &C); 11205 for (unsigned u = 0, e = PHI.getNumIncomingValues(); u < e; u++) { 11206 BasicBlock *IncomingBB = PHI.getIncomingBlock(u); 11207 if (LI.LivenessAA && 11208 LI.LivenessAA->isEdgeDead(IncomingBB, PHI.getParent())) { 11209 LI.AnyDead = true; 11210 continue; 11211 } 11212 Value *V = PHI.getIncomingValue(u); 11213 if (V == &PHI) 11214 continue; 11215 11216 // If the incoming value is not the PHI but an instruction in the same 11217 // cycle we might have multiple versions of it flying around. 11218 if (CyclePHI && isa<Instruction>(V) && 11219 (!C || C->contains(cast<Instruction>(V)->getParent()))) 11220 return false; 11221 11222 Worklist.push_back({{*V, IncomingBB->getTerminator()}, II.S}); 11223 } 11224 return true; 11225 } 11226 11227 bool UsedAssumedInformation = false; 11228 std::optional<Value *> SimpleV = A.getAssumedSimplified( 11229 IRPosition::inst(PHI), *this, UsedAssumedInformation, II.S); 11230 if (!SimpleV.has_value()) 11231 return true; 11232 if (!(*SimpleV)) 11233 return false; 11234 addValue(A, getState(), **SimpleV, &PHI, II.S, getAnchorScope()); 11235 return true; 11236 } 11237 11238 /// Use the generic, non-optimistic InstSimplfy functionality if we managed to 11239 /// simplify any operand of the instruction \p I. Return true if successful, 11240 /// in that case Worklist will be updated. 11241 bool handleGenericInst(Attributor &A, Instruction &I, ItemInfo II, 11242 SmallVectorImpl<ItemInfo> &Worklist) { 11243 bool SomeSimplified = false; 11244 bool UsedAssumedInformation = false; 11245 11246 SmallVector<Value *, 8> NewOps(I.getNumOperands()); 11247 int Idx = 0; 11248 for (Value *Op : I.operands()) { 11249 const auto &SimplifiedOp = A.getAssumedSimplified( 11250 IRPosition::value(*Op, getCallBaseContext()), *this, 11251 UsedAssumedInformation, AA::Intraprocedural); 11252 // If we are not sure about any operand we are not sure about the entire 11253 // instruction, we'll wait. 11254 if (!SimplifiedOp.has_value()) 11255 return true; 11256 11257 if (*SimplifiedOp) 11258 NewOps[Idx] = *SimplifiedOp; 11259 else 11260 NewOps[Idx] = Op; 11261 11262 SomeSimplified |= (NewOps[Idx] != Op); 11263 ++Idx; 11264 } 11265 11266 // We won't bother with the InstSimplify interface if we didn't simplify any 11267 // operand ourselves. 11268 if (!SomeSimplified) 11269 return false; 11270 11271 InformationCache &InfoCache = A.getInfoCache(); 11272 Function *F = I.getFunction(); 11273 const auto *DT = 11274 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F); 11275 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F); 11276 auto *AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F); 11277 11278 const DataLayout &DL = I.getDataLayout(); 11279 SimplifyQuery Q(DL, TLI, DT, AC, &I); 11280 Value *NewV = simplifyInstructionWithOperands(&I, NewOps, Q); 11281 if (!NewV || NewV == &I) 11282 return false; 11283 11284 LLVM_DEBUG(dbgs() << "Generic inst " << I << " assumed simplified to " 11285 << *NewV << "\n"); 11286 Worklist.push_back({{*NewV, II.I.getCtxI()}, II.S}); 11287 return true; 11288 } 11289 11290 bool simplifyInstruction( 11291 Attributor &A, Instruction &I, ItemInfo II, 11292 SmallVectorImpl<ItemInfo> &Worklist, 11293 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) { 11294 if (auto *CI = dyn_cast<CmpInst>(&I)) 11295 return handleCmp(A, *CI, CI->getOperand(0), CI->getOperand(1), 11296 CI->getPredicate(), II, Worklist); 11297 11298 switch (I.getOpcode()) { 11299 case Instruction::Select: 11300 return handleSelectInst(A, cast<SelectInst>(I), II, Worklist); 11301 case Instruction::PHI: 11302 return handlePHINode(A, cast<PHINode>(I), II, Worklist, LivenessAAs); 11303 case Instruction::Load: 11304 return handleLoadInst(A, cast<LoadInst>(I), II, Worklist); 11305 default: 11306 return handleGenericInst(A, I, II, Worklist); 11307 }; 11308 return false; 11309 } 11310 11311 void genericValueTraversal(Attributor &A, Value *InitialV) { 11312 SmallMapVector<const Function *, LivenessInfo, 4> LivenessAAs; 11313 11314 SmallSet<ItemInfo, 16> Visited; 11315 SmallVector<ItemInfo, 16> Worklist; 11316 Worklist.push_back({{*InitialV, getCtxI()}, AA::AnyScope}); 11317 11318 int Iteration = 0; 11319 do { 11320 ItemInfo II = Worklist.pop_back_val(); 11321 Value *V = II.I.getValue(); 11322 assert(V); 11323 const Instruction *CtxI = II.I.getCtxI(); 11324 AA::ValueScope S = II.S; 11325 11326 // Check if we should process the current value. To prevent endless 11327 // recursion keep a record of the values we followed! 11328 if (!Visited.insert(II).second) 11329 continue; 11330 11331 // Make sure we limit the compile time for complex expressions. 11332 if (Iteration++ >= MaxPotentialValuesIterations) { 11333 LLVM_DEBUG(dbgs() << "Generic value traversal reached iteration limit: " 11334 << Iteration << "!\n"); 11335 addValue(A, getState(), *V, CtxI, S, getAnchorScope()); 11336 continue; 11337 } 11338 11339 // Explicitly look through calls with a "returned" attribute if we do 11340 // not have a pointer as stripPointerCasts only works on them. 11341 Value *NewV = nullptr; 11342 if (V->getType()->isPointerTy()) { 11343 NewV = AA::getWithType(*V->stripPointerCasts(), *V->getType()); 11344 } else { 11345 if (auto *CB = dyn_cast<CallBase>(V)) 11346 if (auto *Callee = 11347 dyn_cast_if_present<Function>(CB->getCalledOperand())) { 11348 for (Argument &Arg : Callee->args()) 11349 if (Arg.hasReturnedAttr()) { 11350 NewV = CB->getArgOperand(Arg.getArgNo()); 11351 break; 11352 } 11353 } 11354 } 11355 if (NewV && NewV != V) { 11356 Worklist.push_back({{*NewV, CtxI}, S}); 11357 continue; 11358 } 11359 11360 if (auto *I = dyn_cast<Instruction>(V)) { 11361 if (simplifyInstruction(A, *I, II, Worklist, LivenessAAs)) 11362 continue; 11363 } 11364 11365 if (V != InitialV || isa<Argument>(V)) 11366 if (recurseForValue(A, IRPosition::value(*V), II.S)) 11367 continue; 11368 11369 // If we haven't stripped anything we give up. 11370 if (V == InitialV && CtxI == getCtxI()) { 11371 indicatePessimisticFixpoint(); 11372 return; 11373 } 11374 11375 addValue(A, getState(), *V, CtxI, S, getAnchorScope()); 11376 } while (!Worklist.empty()); 11377 11378 // If we actually used liveness information so we have to record a 11379 // dependence. 11380 for (auto &It : LivenessAAs) 11381 if (It.second.AnyDead) 11382 A.recordDependence(*It.second.LivenessAA, *this, DepClassTy::OPTIONAL); 11383 } 11384 11385 /// See AbstractAttribute::trackStatistics() 11386 void trackStatistics() const override { 11387 STATS_DECLTRACK_FLOATING_ATTR(potential_values) 11388 } 11389 }; 11390 11391 struct AAPotentialValuesArgument final : AAPotentialValuesImpl { 11392 using Base = AAPotentialValuesImpl; 11393 AAPotentialValuesArgument(const IRPosition &IRP, Attributor &A) 11394 : Base(IRP, A) {} 11395 11396 /// See AbstractAttribute::initialize(..). 11397 void initialize(Attributor &A) override { 11398 auto &Arg = cast<Argument>(getAssociatedValue()); 11399 if (Arg.hasPointeeInMemoryValueAttr()) 11400 indicatePessimisticFixpoint(); 11401 } 11402 11403 /// See AbstractAttribute::updateImpl(...). 11404 ChangeStatus updateImpl(Attributor &A) override { 11405 auto AssumedBefore = getAssumed(); 11406 11407 unsigned ArgNo = getCalleeArgNo(); 11408 11409 bool UsedAssumedInformation = false; 11410 SmallVector<AA::ValueAndContext> Values; 11411 auto CallSitePred = [&](AbstractCallSite ACS) { 11412 const auto CSArgIRP = IRPosition::callsite_argument(ACS, ArgNo); 11413 if (CSArgIRP.getPositionKind() == IRP_INVALID) 11414 return false; 11415 11416 if (!A.getAssumedSimplifiedValues(CSArgIRP, this, Values, 11417 AA::Interprocedural, 11418 UsedAssumedInformation)) 11419 return false; 11420 11421 return isValidState(); 11422 }; 11423 11424 if (!A.checkForAllCallSites(CallSitePred, *this, 11425 /* RequireAllCallSites */ true, 11426 UsedAssumedInformation)) 11427 return indicatePessimisticFixpoint(); 11428 11429 Function *Fn = getAssociatedFunction(); 11430 bool AnyNonLocal = false; 11431 for (auto &It : Values) { 11432 if (isa<Constant>(It.getValue())) { 11433 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope, 11434 getAnchorScope()); 11435 continue; 11436 } 11437 if (!AA::isDynamicallyUnique(A, *this, *It.getValue())) 11438 return indicatePessimisticFixpoint(); 11439 11440 if (auto *Arg = dyn_cast<Argument>(It.getValue())) 11441 if (Arg->getParent() == Fn) { 11442 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope, 11443 getAnchorScope()); 11444 continue; 11445 } 11446 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::Interprocedural, 11447 getAnchorScope()); 11448 AnyNonLocal = true; 11449 } 11450 assert(!undefIsContained() && "Undef should be an explicit value!"); 11451 if (AnyNonLocal) 11452 giveUpOnIntraprocedural(A); 11453 11454 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED 11455 : ChangeStatus::CHANGED; 11456 } 11457 11458 /// See AbstractAttribute::trackStatistics() 11459 void trackStatistics() const override { 11460 STATS_DECLTRACK_ARG_ATTR(potential_values) 11461 } 11462 }; 11463 11464 struct AAPotentialValuesReturned : public AAPotentialValuesFloating { 11465 using Base = AAPotentialValuesFloating; 11466 AAPotentialValuesReturned(const IRPosition &IRP, Attributor &A) 11467 : Base(IRP, A) {} 11468 11469 /// See AbstractAttribute::initialize(..). 11470 void initialize(Attributor &A) override { 11471 Function *F = getAssociatedFunction(); 11472 if (!F || F->isDeclaration() || F->getReturnType()->isVoidTy()) { 11473 indicatePessimisticFixpoint(); 11474 return; 11475 } 11476 11477 for (Argument &Arg : F->args()) 11478 if (Arg.hasReturnedAttr()) { 11479 addValue(A, getState(), Arg, nullptr, AA::AnyScope, F); 11480 ReturnedArg = &Arg; 11481 break; 11482 } 11483 if (!A.isFunctionIPOAmendable(*F) || 11484 A.hasSimplificationCallback(getIRPosition())) { 11485 if (!ReturnedArg) 11486 indicatePessimisticFixpoint(); 11487 else 11488 indicateOptimisticFixpoint(); 11489 } 11490 } 11491 11492 /// See AbstractAttribute::updateImpl(...). 11493 ChangeStatus updateImpl(Attributor &A) override { 11494 auto AssumedBefore = getAssumed(); 11495 bool UsedAssumedInformation = false; 11496 11497 SmallVector<AA::ValueAndContext> Values; 11498 Function *AnchorScope = getAnchorScope(); 11499 auto HandleReturnedValue = [&](Value &V, Instruction *CtxI, 11500 bool AddValues) { 11501 for (AA::ValueScope S : {AA::Interprocedural, AA::Intraprocedural}) { 11502 Values.clear(); 11503 if (!A.getAssumedSimplifiedValues(IRPosition::value(V), this, Values, S, 11504 UsedAssumedInformation, 11505 /* RecurseForSelectAndPHI */ true)) 11506 return false; 11507 if (!AddValues) 11508 continue; 11509 for (const AA::ValueAndContext &VAC : Values) 11510 addValue(A, getState(), *VAC.getValue(), 11511 VAC.getCtxI() ? VAC.getCtxI() : CtxI, S, AnchorScope); 11512 } 11513 return true; 11514 }; 11515 11516 if (ReturnedArg) { 11517 HandleReturnedValue(*ReturnedArg, nullptr, true); 11518 } else { 11519 auto RetInstPred = [&](Instruction &RetI) { 11520 bool AddValues = true; 11521 if (isa<PHINode>(RetI.getOperand(0)) || 11522 isa<SelectInst>(RetI.getOperand(0))) { 11523 addValue(A, getState(), *RetI.getOperand(0), &RetI, AA::AnyScope, 11524 AnchorScope); 11525 AddValues = false; 11526 } 11527 return HandleReturnedValue(*RetI.getOperand(0), &RetI, AddValues); 11528 }; 11529 11530 if (!A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret}, 11531 UsedAssumedInformation, 11532 /* CheckBBLivenessOnly */ true)) 11533 return indicatePessimisticFixpoint(); 11534 } 11535 11536 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED 11537 : ChangeStatus::CHANGED; 11538 } 11539 11540 void addValue(Attributor &A, StateType &State, Value &V, 11541 const Instruction *CtxI, AA::ValueScope S, 11542 Function *AnchorScope) const override { 11543 Function *F = getAssociatedFunction(); 11544 if (auto *CB = dyn_cast<CallBase>(&V)) 11545 if (CB->getCalledOperand() == F) 11546 return; 11547 Base::addValue(A, State, V, CtxI, S, AnchorScope); 11548 } 11549 11550 ChangeStatus manifest(Attributor &A) override { 11551 if (ReturnedArg) 11552 return ChangeStatus::UNCHANGED; 11553 SmallVector<AA::ValueAndContext> Values; 11554 if (!getAssumedSimplifiedValues(A, Values, AA::ValueScope::Intraprocedural, 11555 /* RecurseForSelectAndPHI */ true)) 11556 return ChangeStatus::UNCHANGED; 11557 Value *NewVal = getSingleValue(A, *this, getIRPosition(), Values); 11558 if (!NewVal) 11559 return ChangeStatus::UNCHANGED; 11560 11561 ChangeStatus Changed = ChangeStatus::UNCHANGED; 11562 if (auto *Arg = dyn_cast<Argument>(NewVal)) { 11563 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn, 11564 "Number of function with unique return"); 11565 Changed |= A.manifestAttrs( 11566 IRPosition::argument(*Arg), 11567 {Attribute::get(Arg->getContext(), Attribute::Returned)}); 11568 STATS_DECLTRACK_ARG_ATTR(returned); 11569 } 11570 11571 auto RetInstPred = [&](Instruction &RetI) { 11572 Value *RetOp = RetI.getOperand(0); 11573 if (isa<UndefValue>(RetOp) || RetOp == NewVal) 11574 return true; 11575 if (AA::isValidAtPosition({*NewVal, RetI}, A.getInfoCache())) 11576 if (A.changeUseAfterManifest(RetI.getOperandUse(0), *NewVal)) 11577 Changed = ChangeStatus::CHANGED; 11578 return true; 11579 }; 11580 bool UsedAssumedInformation = false; 11581 (void)A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret}, 11582 UsedAssumedInformation, 11583 /* CheckBBLivenessOnly */ true); 11584 return Changed; 11585 } 11586 11587 ChangeStatus indicatePessimisticFixpoint() override { 11588 return AAPotentialValues::indicatePessimisticFixpoint(); 11589 } 11590 11591 /// See AbstractAttribute::trackStatistics() 11592 void trackStatistics() const override{ 11593 STATS_DECLTRACK_FNRET_ATTR(potential_values)} 11594 11595 /// The argumented with an existing `returned` attribute. 11596 Argument *ReturnedArg = nullptr; 11597 }; 11598 11599 struct AAPotentialValuesFunction : AAPotentialValuesImpl { 11600 AAPotentialValuesFunction(const IRPosition &IRP, Attributor &A) 11601 : AAPotentialValuesImpl(IRP, A) {} 11602 11603 /// See AbstractAttribute::updateImpl(...). 11604 ChangeStatus updateImpl(Attributor &A) override { 11605 llvm_unreachable("AAPotentialValues(Function|CallSite)::updateImpl will " 11606 "not be called"); 11607 } 11608 11609 /// See AbstractAttribute::trackStatistics() 11610 void trackStatistics() const override { 11611 STATS_DECLTRACK_FN_ATTR(potential_values) 11612 } 11613 }; 11614 11615 struct AAPotentialValuesCallSite : AAPotentialValuesFunction { 11616 AAPotentialValuesCallSite(const IRPosition &IRP, Attributor &A) 11617 : AAPotentialValuesFunction(IRP, A) {} 11618 11619 /// See AbstractAttribute::trackStatistics() 11620 void trackStatistics() const override { 11621 STATS_DECLTRACK_CS_ATTR(potential_values) 11622 } 11623 }; 11624 11625 struct AAPotentialValuesCallSiteReturned : AAPotentialValuesImpl { 11626 AAPotentialValuesCallSiteReturned(const IRPosition &IRP, Attributor &A) 11627 : AAPotentialValuesImpl(IRP, A) {} 11628 11629 /// See AbstractAttribute::updateImpl(...). 11630 ChangeStatus updateImpl(Attributor &A) override { 11631 auto AssumedBefore = getAssumed(); 11632 11633 Function *Callee = getAssociatedFunction(); 11634 if (!Callee) 11635 return indicatePessimisticFixpoint(); 11636 11637 bool UsedAssumedInformation = false; 11638 auto *CB = cast<CallBase>(getCtxI()); 11639 if (CB->isMustTailCall() && 11640 !A.isAssumedDead(IRPosition::inst(*CB), this, nullptr, 11641 UsedAssumedInformation)) 11642 return indicatePessimisticFixpoint(); 11643 11644 SmallVector<AA::ValueAndContext> Values; 11645 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this, 11646 Values, AA::Intraprocedural, 11647 UsedAssumedInformation)) 11648 return indicatePessimisticFixpoint(); 11649 11650 Function *Caller = CB->getCaller(); 11651 11652 bool AnyNonLocal = false; 11653 for (auto &It : Values) { 11654 Value *V = It.getValue(); 11655 std::optional<Value *> CallerV = A.translateArgumentToCallSiteContent( 11656 V, *CB, *this, UsedAssumedInformation); 11657 if (!CallerV.has_value()) { 11658 // Nothing to do as long as no value was determined. 11659 continue; 11660 } 11661 V = *CallerV ? *CallerV : V; 11662 if (AA::isDynamicallyUnique(A, *this, *V) && 11663 AA::isValidInScope(*V, Caller)) { 11664 if (*CallerV) { 11665 SmallVector<AA::ValueAndContext> ArgValues; 11666 IRPosition IRP = IRPosition::value(*V); 11667 if (auto *Arg = dyn_cast<Argument>(V)) 11668 if (Arg->getParent() == CB->getCalledOperand()) 11669 IRP = IRPosition::callsite_argument(*CB, Arg->getArgNo()); 11670 if (recurseForValue(A, IRP, AA::AnyScope)) 11671 continue; 11672 } 11673 addValue(A, getState(), *V, CB, AA::AnyScope, getAnchorScope()); 11674 } else { 11675 AnyNonLocal = true; 11676 break; 11677 } 11678 } 11679 if (AnyNonLocal) { 11680 Values.clear(); 11681 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this, 11682 Values, AA::Interprocedural, 11683 UsedAssumedInformation)) 11684 return indicatePessimisticFixpoint(); 11685 AnyNonLocal = false; 11686 getState() = PotentialLLVMValuesState::getBestState(); 11687 for (auto &It : Values) { 11688 Value *V = It.getValue(); 11689 if (!AA::isDynamicallyUnique(A, *this, *V)) 11690 return indicatePessimisticFixpoint(); 11691 if (AA::isValidInScope(*V, Caller)) { 11692 addValue(A, getState(), *V, CB, AA::AnyScope, getAnchorScope()); 11693 } else { 11694 AnyNonLocal = true; 11695 addValue(A, getState(), *V, CB, AA::Interprocedural, 11696 getAnchorScope()); 11697 } 11698 } 11699 if (AnyNonLocal) 11700 giveUpOnIntraprocedural(A); 11701 } 11702 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED 11703 : ChangeStatus::CHANGED; 11704 } 11705 11706 ChangeStatus indicatePessimisticFixpoint() override { 11707 return AAPotentialValues::indicatePessimisticFixpoint(); 11708 } 11709 11710 /// See AbstractAttribute::trackStatistics() 11711 void trackStatistics() const override { 11712 STATS_DECLTRACK_CSRET_ATTR(potential_values) 11713 } 11714 }; 11715 11716 struct AAPotentialValuesCallSiteArgument : AAPotentialValuesFloating { 11717 AAPotentialValuesCallSiteArgument(const IRPosition &IRP, Attributor &A) 11718 : AAPotentialValuesFloating(IRP, A) {} 11719 11720 /// See AbstractAttribute::trackStatistics() 11721 void trackStatistics() const override { 11722 STATS_DECLTRACK_CSARG_ATTR(potential_values) 11723 } 11724 }; 11725 } // namespace 11726 11727 /// ---------------------- Assumption Propagation ------------------------------ 11728 namespace { 11729 struct AAAssumptionInfoImpl : public AAAssumptionInfo { 11730 AAAssumptionInfoImpl(const IRPosition &IRP, Attributor &A, 11731 const DenseSet<StringRef> &Known) 11732 : AAAssumptionInfo(IRP, A, Known) {} 11733 11734 /// See AbstractAttribute::manifest(...). 11735 ChangeStatus manifest(Attributor &A) override { 11736 // Don't manifest a universal set if it somehow made it here. 11737 if (getKnown().isUniversal()) 11738 return ChangeStatus::UNCHANGED; 11739 11740 const IRPosition &IRP = getIRPosition(); 11741 SmallVector<StringRef, 0> Set(getAssumed().getSet().begin(), 11742 getAssumed().getSet().end()); 11743 llvm::sort(Set); 11744 return A.manifestAttrs(IRP, 11745 Attribute::get(IRP.getAnchorValue().getContext(), 11746 AssumptionAttrKey, 11747 llvm::join(Set, ",")), 11748 /*ForceReplace=*/true); 11749 } 11750 11751 bool hasAssumption(const StringRef Assumption) const override { 11752 return isValidState() && setContains(Assumption); 11753 } 11754 11755 /// See AbstractAttribute::getAsStr() 11756 const std::string getAsStr(Attributor *A) const override { 11757 const SetContents &Known = getKnown(); 11758 const SetContents &Assumed = getAssumed(); 11759 11760 SmallVector<StringRef, 0> Set(Known.getSet().begin(), Known.getSet().end()); 11761 llvm::sort(Set); 11762 const std::string KnownStr = llvm::join(Set, ","); 11763 11764 std::string AssumedStr = "Universal"; 11765 if (!Assumed.isUniversal()) { 11766 Set.assign(Assumed.getSet().begin(), Assumed.getSet().end()); 11767 AssumedStr = llvm::join(Set, ","); 11768 } 11769 return "Known [" + KnownStr + "]," + " Assumed [" + AssumedStr + "]"; 11770 } 11771 }; 11772 11773 /// Propagates assumption information from parent functions to all of their 11774 /// successors. An assumption can be propagated if the containing function 11775 /// dominates the called function. 11776 /// 11777 /// We start with a "known" set of assumptions already valid for the associated 11778 /// function and an "assumed" set that initially contains all possible 11779 /// assumptions. The assumed set is inter-procedurally updated by narrowing its 11780 /// contents as concrete values are known. The concrete values are seeded by the 11781 /// first nodes that are either entries into the call graph, or contains no 11782 /// assumptions. Each node is updated as the intersection of the assumed state 11783 /// with all of its predecessors. 11784 struct AAAssumptionInfoFunction final : AAAssumptionInfoImpl { 11785 AAAssumptionInfoFunction(const IRPosition &IRP, Attributor &A) 11786 : AAAssumptionInfoImpl(IRP, A, 11787 getAssumptions(*IRP.getAssociatedFunction())) {} 11788 11789 /// See AbstractAttribute::updateImpl(...). 11790 ChangeStatus updateImpl(Attributor &A) override { 11791 bool Changed = false; 11792 11793 auto CallSitePred = [&](AbstractCallSite ACS) { 11794 const auto *AssumptionAA = A.getAAFor<AAAssumptionInfo>( 11795 *this, IRPosition::callsite_function(*ACS.getInstruction()), 11796 DepClassTy::REQUIRED); 11797 if (!AssumptionAA) 11798 return false; 11799 // Get the set of assumptions shared by all of this function's callers. 11800 Changed |= getIntersection(AssumptionAA->getAssumed()); 11801 return !getAssumed().empty() || !getKnown().empty(); 11802 }; 11803 11804 bool UsedAssumedInformation = false; 11805 // Get the intersection of all assumptions held by this node's predecessors. 11806 // If we don't know all the call sites then this is either an entry into the 11807 // call graph or an empty node. This node is known to only contain its own 11808 // assumptions and can be propagated to its successors. 11809 if (!A.checkForAllCallSites(CallSitePred, *this, true, 11810 UsedAssumedInformation)) 11811 return indicatePessimisticFixpoint(); 11812 11813 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 11814 } 11815 11816 void trackStatistics() const override {} 11817 }; 11818 11819 /// Assumption Info defined for call sites. 11820 struct AAAssumptionInfoCallSite final : AAAssumptionInfoImpl { 11821 11822 AAAssumptionInfoCallSite(const IRPosition &IRP, Attributor &A) 11823 : AAAssumptionInfoImpl(IRP, A, getInitialAssumptions(IRP)) {} 11824 11825 /// See AbstractAttribute::initialize(...). 11826 void initialize(Attributor &A) override { 11827 const IRPosition &FnPos = IRPosition::function(*getAnchorScope()); 11828 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED); 11829 } 11830 11831 /// See AbstractAttribute::updateImpl(...). 11832 ChangeStatus updateImpl(Attributor &A) override { 11833 const IRPosition &FnPos = IRPosition::function(*getAnchorScope()); 11834 auto *AssumptionAA = 11835 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED); 11836 if (!AssumptionAA) 11837 return indicatePessimisticFixpoint(); 11838 bool Changed = getIntersection(AssumptionAA->getAssumed()); 11839 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 11840 } 11841 11842 /// See AbstractAttribute::trackStatistics() 11843 void trackStatistics() const override {} 11844 11845 private: 11846 /// Helper to initialized the known set as all the assumptions this call and 11847 /// the callee contain. 11848 DenseSet<StringRef> getInitialAssumptions(const IRPosition &IRP) { 11849 const CallBase &CB = cast<CallBase>(IRP.getAssociatedValue()); 11850 auto Assumptions = getAssumptions(CB); 11851 if (const Function *F = CB.getCaller()) 11852 set_union(Assumptions, getAssumptions(*F)); 11853 if (Function *F = IRP.getAssociatedFunction()) 11854 set_union(Assumptions, getAssumptions(*F)); 11855 return Assumptions; 11856 } 11857 }; 11858 } // namespace 11859 11860 AACallGraphNode *AACallEdgeIterator::operator*() const { 11861 return static_cast<AACallGraphNode *>(const_cast<AACallEdges *>( 11862 A.getOrCreateAAFor<AACallEdges>(IRPosition::function(**I)))); 11863 } 11864 11865 void AttributorCallGraph::print() { llvm::WriteGraph(outs(), this); } 11866 11867 /// ------------------------ UnderlyingObjects --------------------------------- 11868 11869 namespace { 11870 struct AAUnderlyingObjectsImpl 11871 : StateWrapper<BooleanState, AAUnderlyingObjects> { 11872 using BaseTy = StateWrapper<BooleanState, AAUnderlyingObjects>; 11873 AAUnderlyingObjectsImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {} 11874 11875 /// See AbstractAttribute::getAsStr(). 11876 const std::string getAsStr(Attributor *A) const override { 11877 return std::string("UnderlyingObjects ") + 11878 (isValidState() 11879 ? (std::string("inter #") + 11880 std::to_string(InterAssumedUnderlyingObjects.size()) + 11881 " objs" + std::string(", intra #") + 11882 std::to_string(IntraAssumedUnderlyingObjects.size()) + 11883 " objs") 11884 : "<invalid>"); 11885 } 11886 11887 /// See AbstractAttribute::trackStatistics() 11888 void trackStatistics() const override {} 11889 11890 /// See AbstractAttribute::updateImpl(...). 11891 ChangeStatus updateImpl(Attributor &A) override { 11892 auto &Ptr = getAssociatedValue(); 11893 11894 auto DoUpdate = [&](SmallSetVector<Value *, 8> &UnderlyingObjects, 11895 AA::ValueScope Scope) { 11896 bool UsedAssumedInformation = false; 11897 SmallPtrSet<Value *, 8> SeenObjects; 11898 SmallVector<AA::ValueAndContext> Values; 11899 11900 if (!A.getAssumedSimplifiedValues(IRPosition::value(Ptr), *this, Values, 11901 Scope, UsedAssumedInformation)) 11902 return UnderlyingObjects.insert(&Ptr); 11903 11904 bool Changed = false; 11905 11906 for (unsigned I = 0; I < Values.size(); ++I) { 11907 auto &VAC = Values[I]; 11908 auto *Obj = VAC.getValue(); 11909 Value *UO = getUnderlyingObject(Obj); 11910 if (UO && UO != VAC.getValue() && SeenObjects.insert(UO).second) { 11911 const auto *OtherAA = A.getAAFor<AAUnderlyingObjects>( 11912 *this, IRPosition::value(*UO), DepClassTy::OPTIONAL); 11913 auto Pred = [&Values](Value &V) { 11914 Values.emplace_back(V, nullptr); 11915 return true; 11916 }; 11917 11918 if (!OtherAA || !OtherAA->forallUnderlyingObjects(Pred, Scope)) 11919 llvm_unreachable( 11920 "The forall call should not return false at this position"); 11921 11922 continue; 11923 } 11924 11925 if (isa<SelectInst>(Obj)) { 11926 Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope); 11927 continue; 11928 } 11929 if (auto *PHI = dyn_cast<PHINode>(Obj)) { 11930 // Explicitly look through PHIs as we do not care about dynamically 11931 // uniqueness. 11932 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) { 11933 Changed |= handleIndirect(A, *PHI->getIncomingValue(u), 11934 UnderlyingObjects, Scope); 11935 } 11936 continue; 11937 } 11938 11939 Changed |= UnderlyingObjects.insert(Obj); 11940 } 11941 11942 return Changed; 11943 }; 11944 11945 bool Changed = false; 11946 Changed |= DoUpdate(IntraAssumedUnderlyingObjects, AA::Intraprocedural); 11947 Changed |= DoUpdate(InterAssumedUnderlyingObjects, AA::Interprocedural); 11948 11949 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 11950 } 11951 11952 bool forallUnderlyingObjects( 11953 function_ref<bool(Value &)> Pred, 11954 AA::ValueScope Scope = AA::Interprocedural) const override { 11955 if (!isValidState()) 11956 return Pred(getAssociatedValue()); 11957 11958 auto &AssumedUnderlyingObjects = Scope == AA::Intraprocedural 11959 ? IntraAssumedUnderlyingObjects 11960 : InterAssumedUnderlyingObjects; 11961 for (Value *Obj : AssumedUnderlyingObjects) 11962 if (!Pred(*Obj)) 11963 return false; 11964 11965 return true; 11966 } 11967 11968 private: 11969 /// Handle the case where the value is not the actual underlying value, such 11970 /// as a phi node or a select instruction. 11971 bool handleIndirect(Attributor &A, Value &V, 11972 SmallSetVector<Value *, 8> &UnderlyingObjects, 11973 AA::ValueScope Scope) { 11974 bool Changed = false; 11975 const auto *AA = A.getAAFor<AAUnderlyingObjects>( 11976 *this, IRPosition::value(V), DepClassTy::OPTIONAL); 11977 auto Pred = [&](Value &V) { 11978 Changed |= UnderlyingObjects.insert(&V); 11979 return true; 11980 }; 11981 if (!AA || !AA->forallUnderlyingObjects(Pred, Scope)) 11982 llvm_unreachable( 11983 "The forall call should not return false at this position"); 11984 return Changed; 11985 } 11986 11987 /// All the underlying objects collected so far via intra procedural scope. 11988 SmallSetVector<Value *, 8> IntraAssumedUnderlyingObjects; 11989 /// All the underlying objects collected so far via inter procedural scope. 11990 SmallSetVector<Value *, 8> InterAssumedUnderlyingObjects; 11991 }; 11992 11993 struct AAUnderlyingObjectsFloating final : AAUnderlyingObjectsImpl { 11994 AAUnderlyingObjectsFloating(const IRPosition &IRP, Attributor &A) 11995 : AAUnderlyingObjectsImpl(IRP, A) {} 11996 }; 11997 11998 struct AAUnderlyingObjectsArgument final : AAUnderlyingObjectsImpl { 11999 AAUnderlyingObjectsArgument(const IRPosition &IRP, Attributor &A) 12000 : AAUnderlyingObjectsImpl(IRP, A) {} 12001 }; 12002 12003 struct AAUnderlyingObjectsCallSite final : AAUnderlyingObjectsImpl { 12004 AAUnderlyingObjectsCallSite(const IRPosition &IRP, Attributor &A) 12005 : AAUnderlyingObjectsImpl(IRP, A) {} 12006 }; 12007 12008 struct AAUnderlyingObjectsCallSiteArgument final : AAUnderlyingObjectsImpl { 12009 AAUnderlyingObjectsCallSiteArgument(const IRPosition &IRP, Attributor &A) 12010 : AAUnderlyingObjectsImpl(IRP, A) {} 12011 }; 12012 12013 struct AAUnderlyingObjectsReturned final : AAUnderlyingObjectsImpl { 12014 AAUnderlyingObjectsReturned(const IRPosition &IRP, Attributor &A) 12015 : AAUnderlyingObjectsImpl(IRP, A) {} 12016 }; 12017 12018 struct AAUnderlyingObjectsCallSiteReturned final : AAUnderlyingObjectsImpl { 12019 AAUnderlyingObjectsCallSiteReturned(const IRPosition &IRP, Attributor &A) 12020 : AAUnderlyingObjectsImpl(IRP, A) {} 12021 }; 12022 12023 struct AAUnderlyingObjectsFunction final : AAUnderlyingObjectsImpl { 12024 AAUnderlyingObjectsFunction(const IRPosition &IRP, Attributor &A) 12025 : AAUnderlyingObjectsImpl(IRP, A) {} 12026 }; 12027 } // namespace 12028 12029 /// ------------------------ Global Value Info ------------------------------- 12030 namespace { 12031 struct AAGlobalValueInfoFloating : public AAGlobalValueInfo { 12032 AAGlobalValueInfoFloating(const IRPosition &IRP, Attributor &A) 12033 : AAGlobalValueInfo(IRP, A) {} 12034 12035 /// See AbstractAttribute::initialize(...). 12036 void initialize(Attributor &A) override {} 12037 12038 bool checkUse(Attributor &A, const Use &U, bool &Follow, 12039 SmallVectorImpl<const Value *> &Worklist) { 12040 Instruction *UInst = dyn_cast<Instruction>(U.getUser()); 12041 if (!UInst) { 12042 Follow = true; 12043 return true; 12044 } 12045 12046 LLVM_DEBUG(dbgs() << "[AAGlobalValueInfo] Check use: " << *U.get() << " in " 12047 << *UInst << "\n"); 12048 12049 if (auto *Cmp = dyn_cast<ICmpInst>(U.getUser())) { 12050 int Idx = &Cmp->getOperandUse(0) == &U; 12051 if (isa<Constant>(Cmp->getOperand(Idx))) 12052 return true; 12053 return U == &getAnchorValue(); 12054 } 12055 12056 // Explicitly catch return instructions. 12057 if (isa<ReturnInst>(UInst)) { 12058 auto CallSitePred = [&](AbstractCallSite ACS) { 12059 Worklist.push_back(ACS.getInstruction()); 12060 return true; 12061 }; 12062 bool UsedAssumedInformation = false; 12063 // TODO: We should traverse the uses or add a "non-call-site" CB. 12064 if (!A.checkForAllCallSites(CallSitePred, *UInst->getFunction(), 12065 /*RequireAllCallSites=*/true, this, 12066 UsedAssumedInformation)) 12067 return false; 12068 return true; 12069 } 12070 12071 // For now we only use special logic for call sites. However, the tracker 12072 // itself knows about a lot of other non-capturing cases already. 12073 auto *CB = dyn_cast<CallBase>(UInst); 12074 if (!CB) 12075 return false; 12076 // Direct calls are OK uses. 12077 if (CB->isCallee(&U)) 12078 return true; 12079 // Non-argument uses are scary. 12080 if (!CB->isArgOperand(&U)) 12081 return false; 12082 // TODO: Iterate callees. 12083 auto *Fn = dyn_cast<Function>(CB->getCalledOperand()); 12084 if (!Fn || !A.isFunctionIPOAmendable(*Fn)) 12085 return false; 12086 12087 unsigned ArgNo = CB->getArgOperandNo(&U); 12088 Worklist.push_back(Fn->getArg(ArgNo)); 12089 return true; 12090 } 12091 12092 ChangeStatus updateImpl(Attributor &A) override { 12093 unsigned NumUsesBefore = Uses.size(); 12094 12095 SmallPtrSet<const Value *, 8> Visited; 12096 SmallVector<const Value *> Worklist; 12097 Worklist.push_back(&getAnchorValue()); 12098 12099 auto UsePred = [&](const Use &U, bool &Follow) -> bool { 12100 Uses.insert(&U); 12101 switch (DetermineUseCaptureKind(U, nullptr)) { 12102 case UseCaptureKind::NO_CAPTURE: 12103 return checkUse(A, U, Follow, Worklist); 12104 case UseCaptureKind::MAY_CAPTURE: 12105 return checkUse(A, U, Follow, Worklist); 12106 case UseCaptureKind::PASSTHROUGH: 12107 Follow = true; 12108 return true; 12109 } 12110 return true; 12111 }; 12112 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) { 12113 Uses.insert(&OldU); 12114 return true; 12115 }; 12116 12117 while (!Worklist.empty()) { 12118 const Value *V = Worklist.pop_back_val(); 12119 if (!Visited.insert(V).second) 12120 continue; 12121 if (!A.checkForAllUses(UsePred, *this, *V, 12122 /* CheckBBLivenessOnly */ true, 12123 DepClassTy::OPTIONAL, 12124 /* IgnoreDroppableUses */ true, EquivalentUseCB)) { 12125 return indicatePessimisticFixpoint(); 12126 } 12127 } 12128 12129 return Uses.size() == NumUsesBefore ? ChangeStatus::UNCHANGED 12130 : ChangeStatus::CHANGED; 12131 } 12132 12133 bool isPotentialUse(const Use &U) const override { 12134 return !isValidState() || Uses.contains(&U); 12135 } 12136 12137 /// See AbstractAttribute::manifest(...). 12138 ChangeStatus manifest(Attributor &A) override { 12139 return ChangeStatus::UNCHANGED; 12140 } 12141 12142 /// See AbstractAttribute::getAsStr(). 12143 const std::string getAsStr(Attributor *A) const override { 12144 return "[" + std::to_string(Uses.size()) + " uses]"; 12145 } 12146 12147 void trackStatistics() const override { 12148 STATS_DECLTRACK_FLOATING_ATTR(GlobalValuesTracked); 12149 } 12150 12151 private: 12152 /// Set of (transitive) uses of this GlobalValue. 12153 SmallPtrSet<const Use *, 8> Uses; 12154 }; 12155 } // namespace 12156 12157 /// ------------------------ Indirect Call Info ------------------------------- 12158 namespace { 12159 struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo { 12160 AAIndirectCallInfoCallSite(const IRPosition &IRP, Attributor &A) 12161 : AAIndirectCallInfo(IRP, A) {} 12162 12163 /// See AbstractAttribute::initialize(...). 12164 void initialize(Attributor &A) override { 12165 auto *MD = getCtxI()->getMetadata(LLVMContext::MD_callees); 12166 if (!MD && !A.isClosedWorldModule()) 12167 return; 12168 12169 if (MD) { 12170 for (const auto &Op : MD->operands()) 12171 if (Function *Callee = mdconst::dyn_extract_or_null<Function>(Op)) 12172 PotentialCallees.insert(Callee); 12173 } else if (A.isClosedWorldModule()) { 12174 ArrayRef<Function *> IndirectlyCallableFunctions = 12175 A.getInfoCache().getIndirectlyCallableFunctions(A); 12176 PotentialCallees.insert(IndirectlyCallableFunctions.begin(), 12177 IndirectlyCallableFunctions.end()); 12178 } 12179 12180 if (PotentialCallees.empty()) 12181 indicateOptimisticFixpoint(); 12182 } 12183 12184 ChangeStatus updateImpl(Attributor &A) override { 12185 CallBase *CB = cast<CallBase>(getCtxI()); 12186 const Use &CalleeUse = CB->getCalledOperandUse(); 12187 Value *FP = CB->getCalledOperand(); 12188 12189 SmallSetVector<Function *, 4> AssumedCalleesNow; 12190 bool AllCalleesKnownNow = AllCalleesKnown; 12191 12192 auto CheckPotentialCalleeUse = [&](Function &PotentialCallee, 12193 bool &UsedAssumedInformation) { 12194 const auto *GIAA = A.getAAFor<AAGlobalValueInfo>( 12195 *this, IRPosition::value(PotentialCallee), DepClassTy::OPTIONAL); 12196 if (!GIAA || GIAA->isPotentialUse(CalleeUse)) 12197 return true; 12198 UsedAssumedInformation = !GIAA->isAtFixpoint(); 12199 return false; 12200 }; 12201 12202 auto AddPotentialCallees = [&]() { 12203 for (auto *PotentialCallee : PotentialCallees) { 12204 bool UsedAssumedInformation = false; 12205 if (CheckPotentialCalleeUse(*PotentialCallee, UsedAssumedInformation)) 12206 AssumedCalleesNow.insert(PotentialCallee); 12207 } 12208 }; 12209 12210 // Use simplification to find potential callees, if !callees was present, 12211 // fallback to that set if necessary. 12212 bool UsedAssumedInformation = false; 12213 SmallVector<AA::ValueAndContext> Values; 12214 if (!A.getAssumedSimplifiedValues(IRPosition::value(*FP), this, Values, 12215 AA::ValueScope::AnyScope, 12216 UsedAssumedInformation)) { 12217 if (PotentialCallees.empty()) 12218 return indicatePessimisticFixpoint(); 12219 AddPotentialCallees(); 12220 } 12221 12222 // Try to find a reason for \p Fn not to be a potential callee. If none was 12223 // found, add it to the assumed callees set. 12224 auto CheckPotentialCallee = [&](Function &Fn) { 12225 if (!PotentialCallees.empty() && !PotentialCallees.count(&Fn)) 12226 return false; 12227 12228 auto &CachedResult = FilterResults[&Fn]; 12229 if (CachedResult.has_value()) 12230 return CachedResult.value(); 12231 12232 bool UsedAssumedInformation = false; 12233 if (!CheckPotentialCalleeUse(Fn, UsedAssumedInformation)) { 12234 if (!UsedAssumedInformation) 12235 CachedResult = false; 12236 return false; 12237 } 12238 12239 int NumFnArgs = Fn.arg_size(); 12240 int NumCBArgs = CB->arg_size(); 12241 12242 // Check if any excess argument (which we fill up with poison) is known to 12243 // be UB on undef. 12244 for (int I = NumCBArgs; I < NumFnArgs; ++I) { 12245 bool IsKnown = false; 12246 if (AA::hasAssumedIRAttr<Attribute::NoUndef>( 12247 A, this, IRPosition::argument(*Fn.getArg(I)), 12248 DepClassTy::OPTIONAL, IsKnown)) { 12249 if (IsKnown) 12250 CachedResult = false; 12251 return false; 12252 } 12253 } 12254 12255 CachedResult = true; 12256 return true; 12257 }; 12258 12259 // Check simplification result, prune known UB callees, also restrict it to 12260 // the !callees set, if present. 12261 for (auto &VAC : Values) { 12262 if (isa<UndefValue>(VAC.getValue())) 12263 continue; 12264 if (isa<ConstantPointerNull>(VAC.getValue()) && 12265 VAC.getValue()->getType()->getPointerAddressSpace() == 0) 12266 continue; 12267 // TODO: Check for known UB, e.g., poison + noundef. 12268 if (auto *VACFn = dyn_cast<Function>(VAC.getValue())) { 12269 if (CheckPotentialCallee(*VACFn)) 12270 AssumedCalleesNow.insert(VACFn); 12271 continue; 12272 } 12273 if (!PotentialCallees.empty()) { 12274 AddPotentialCallees(); 12275 break; 12276 } 12277 AllCalleesKnownNow = false; 12278 } 12279 12280 if (AssumedCalleesNow == AssumedCallees && 12281 AllCalleesKnown == AllCalleesKnownNow) 12282 return ChangeStatus::UNCHANGED; 12283 12284 std::swap(AssumedCallees, AssumedCalleesNow); 12285 AllCalleesKnown = AllCalleesKnownNow; 12286 return ChangeStatus::CHANGED; 12287 } 12288 12289 /// See AbstractAttribute::manifest(...). 12290 ChangeStatus manifest(Attributor &A) override { 12291 // If we can't specialize at all, give up now. 12292 if (!AllCalleesKnown && AssumedCallees.empty()) 12293 return ChangeStatus::UNCHANGED; 12294 12295 CallBase *CB = cast<CallBase>(getCtxI()); 12296 bool UsedAssumedInformation = false; 12297 if (A.isAssumedDead(*CB, this, /*LivenessAA=*/nullptr, 12298 UsedAssumedInformation)) 12299 return ChangeStatus::UNCHANGED; 12300 12301 ChangeStatus Changed = ChangeStatus::UNCHANGED; 12302 Value *FP = CB->getCalledOperand(); 12303 if (FP->getType()->getPointerAddressSpace()) 12304 FP = new AddrSpaceCastInst(FP, PointerType::get(FP->getType(), 0), 12305 FP->getName() + ".as0", CB->getIterator()); 12306 12307 bool CBIsVoid = CB->getType()->isVoidTy(); 12308 BasicBlock::iterator IP = CB->getIterator(); 12309 FunctionType *CSFT = CB->getFunctionType(); 12310 SmallVector<Value *> CSArgs(CB->arg_begin(), CB->arg_end()); 12311 12312 // If we know all callees and there are none, the call site is (effectively) 12313 // dead (or UB). 12314 if (AssumedCallees.empty()) { 12315 assert(AllCalleesKnown && 12316 "Expected all callees to be known if there are none."); 12317 A.changeToUnreachableAfterManifest(CB); 12318 return ChangeStatus::CHANGED; 12319 } 12320 12321 // Special handling for the single callee case. 12322 if (AllCalleesKnown && AssumedCallees.size() == 1) { 12323 auto *NewCallee = AssumedCallees.front(); 12324 if (isLegalToPromote(*CB, NewCallee)) { 12325 promoteCall(*CB, NewCallee, nullptr); 12326 return ChangeStatus::CHANGED; 12327 } 12328 Instruction *NewCall = 12329 CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs, 12330 CB->getName(), CB->getIterator()); 12331 if (!CBIsVoid) 12332 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *NewCall); 12333 A.deleteAfterManifest(*CB); 12334 return ChangeStatus::CHANGED; 12335 } 12336 12337 // For each potential value we create a conditional 12338 // 12339 // ``` 12340 // if (ptr == value) value(args); 12341 // else ... 12342 // ``` 12343 // 12344 bool SpecializedForAnyCallees = false; 12345 bool SpecializedForAllCallees = AllCalleesKnown; 12346 ICmpInst *LastCmp = nullptr; 12347 SmallVector<Function *, 8> SkippedAssumedCallees; 12348 SmallVector<std::pair<CallInst *, Instruction *>> NewCalls; 12349 for (Function *NewCallee : AssumedCallees) { 12350 if (!A.shouldSpecializeCallSiteForCallee(*this, *CB, *NewCallee)) { 12351 SkippedAssumedCallees.push_back(NewCallee); 12352 SpecializedForAllCallees = false; 12353 continue; 12354 } 12355 SpecializedForAnyCallees = true; 12356 12357 LastCmp = new ICmpInst(IP, llvm::CmpInst::ICMP_EQ, FP, NewCallee); 12358 Instruction *ThenTI = 12359 SplitBlockAndInsertIfThen(LastCmp, IP, /* Unreachable */ false); 12360 BasicBlock *CBBB = CB->getParent(); 12361 A.registerManifestAddedBasicBlock(*ThenTI->getParent()); 12362 A.registerManifestAddedBasicBlock(*IP->getParent()); 12363 auto *SplitTI = cast<BranchInst>(LastCmp->getNextNode()); 12364 BasicBlock *ElseBB; 12365 if (&*IP == CB) { 12366 ElseBB = BasicBlock::Create(ThenTI->getContext(), "", 12367 ThenTI->getFunction(), CBBB); 12368 A.registerManifestAddedBasicBlock(*ElseBB); 12369 IP = BranchInst::Create(CBBB, ElseBB)->getIterator(); 12370 SplitTI->replaceUsesOfWith(CBBB, ElseBB); 12371 } else { 12372 ElseBB = IP->getParent(); 12373 ThenTI->replaceUsesOfWith(ElseBB, CBBB); 12374 } 12375 CastInst *RetBC = nullptr; 12376 CallInst *NewCall = nullptr; 12377 if (isLegalToPromote(*CB, NewCallee)) { 12378 auto *CBClone = cast<CallBase>(CB->clone()); 12379 CBClone->insertBefore(ThenTI); 12380 NewCall = &cast<CallInst>(promoteCall(*CBClone, NewCallee, &RetBC)); 12381 } else { 12382 NewCall = CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs, 12383 CB->getName(), ThenTI->getIterator()); 12384 } 12385 NewCalls.push_back({NewCall, RetBC}); 12386 } 12387 12388 auto AttachCalleeMetadata = [&](CallBase &IndirectCB) { 12389 if (!AllCalleesKnown) 12390 return ChangeStatus::UNCHANGED; 12391 MDBuilder MDB(IndirectCB.getContext()); 12392 MDNode *Callees = MDB.createCallees(SkippedAssumedCallees); 12393 IndirectCB.setMetadata(LLVMContext::MD_callees, Callees); 12394 return ChangeStatus::CHANGED; 12395 }; 12396 12397 if (!SpecializedForAnyCallees) 12398 return AttachCalleeMetadata(*CB); 12399 12400 // Check if we need the fallback indirect call still. 12401 if (SpecializedForAllCallees) { 12402 LastCmp->replaceAllUsesWith(ConstantInt::getTrue(LastCmp->getContext())); 12403 LastCmp->eraseFromParent(); 12404 new UnreachableInst(IP->getContext(), IP); 12405 IP->eraseFromParent(); 12406 } else { 12407 auto *CBClone = cast<CallInst>(CB->clone()); 12408 CBClone->setName(CB->getName()); 12409 CBClone->insertBefore(*IP->getParent(), IP); 12410 NewCalls.push_back({CBClone, nullptr}); 12411 AttachCalleeMetadata(*CBClone); 12412 } 12413 12414 // Check if we need a PHI to merge the results. 12415 if (!CBIsVoid) { 12416 auto *PHI = PHINode::Create(CB->getType(), NewCalls.size(), 12417 CB->getName() + ".phi", 12418 CB->getParent()->getFirstInsertionPt()); 12419 for (auto &It : NewCalls) { 12420 CallBase *NewCall = It.first; 12421 Instruction *CallRet = It.second ? It.second : It.first; 12422 if (CallRet->getType() == CB->getType()) 12423 PHI->addIncoming(CallRet, CallRet->getParent()); 12424 else if (NewCall->getType()->isVoidTy()) 12425 PHI->addIncoming(PoisonValue::get(CB->getType()), 12426 NewCall->getParent()); 12427 else 12428 llvm_unreachable("Call return should match or be void!"); 12429 } 12430 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *PHI); 12431 } 12432 12433 A.deleteAfterManifest(*CB); 12434 Changed = ChangeStatus::CHANGED; 12435 12436 return Changed; 12437 } 12438 12439 /// See AbstractAttribute::getAsStr(). 12440 const std::string getAsStr(Attributor *A) const override { 12441 return std::string(AllCalleesKnown ? "eliminate" : "specialize") + 12442 " indirect call site with " + std::to_string(AssumedCallees.size()) + 12443 " functions"; 12444 } 12445 12446 void trackStatistics() const override { 12447 if (AllCalleesKnown) { 12448 STATS_DECLTRACK( 12449 Eliminated, CallSites, 12450 "Number of indirect call sites eliminated via specialization") 12451 } else { 12452 STATS_DECLTRACK(Specialized, CallSites, 12453 "Number of indirect call sites specialized") 12454 } 12455 } 12456 12457 bool foreachCallee(function_ref<bool(Function *)> CB) const override { 12458 return isValidState() && AllCalleesKnown && all_of(AssumedCallees, CB); 12459 } 12460 12461 private: 12462 /// Map to remember filter results. 12463 DenseMap<Function *, std::optional<bool>> FilterResults; 12464 12465 /// If the !callee metadata was present, this set will contain all potential 12466 /// callees (superset). 12467 SmallSetVector<Function *, 4> PotentialCallees; 12468 12469 /// This set contains all currently assumed calllees, which might grow over 12470 /// time. 12471 SmallSetVector<Function *, 4> AssumedCallees; 12472 12473 /// Flag to indicate if all possible callees are in the AssumedCallees set or 12474 /// if there could be others. 12475 bool AllCalleesKnown = true; 12476 }; 12477 } // namespace 12478 12479 /// ------------------------ Address Space ------------------------------------ 12480 namespace { 12481 struct AAAddressSpaceImpl : public AAAddressSpace { 12482 AAAddressSpaceImpl(const IRPosition &IRP, Attributor &A) 12483 : AAAddressSpace(IRP, A) {} 12484 12485 int32_t getAddressSpace() const override { 12486 assert(isValidState() && "the AA is invalid"); 12487 return AssumedAddressSpace; 12488 } 12489 12490 /// See AbstractAttribute::initialize(...). 12491 void initialize(Attributor &A) override { 12492 assert(getAssociatedType()->isPtrOrPtrVectorTy() && 12493 "Associated value is not a pointer"); 12494 } 12495 12496 ChangeStatus updateImpl(Attributor &A) override { 12497 int32_t OldAddressSpace = AssumedAddressSpace; 12498 auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this, 12499 DepClassTy::REQUIRED); 12500 auto Pred = [&](Value &Obj) { 12501 if (isa<UndefValue>(&Obj)) 12502 return true; 12503 return takeAddressSpace(Obj.getType()->getPointerAddressSpace()); 12504 }; 12505 12506 if (!AUO->forallUnderlyingObjects(Pred)) 12507 return indicatePessimisticFixpoint(); 12508 12509 return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED 12510 : ChangeStatus::CHANGED; 12511 } 12512 12513 /// See AbstractAttribute::manifest(...). 12514 ChangeStatus manifest(Attributor &A) override { 12515 Value *AssociatedValue = &getAssociatedValue(); 12516 Value *OriginalValue = peelAddrspacecast(AssociatedValue); 12517 if (getAddressSpace() == NoAddressSpace || 12518 static_cast<uint32_t>(getAddressSpace()) == 12519 getAssociatedType()->getPointerAddressSpace()) 12520 return ChangeStatus::UNCHANGED; 12521 12522 Type *NewPtrTy = PointerType::get(getAssociatedType()->getContext(), 12523 static_cast<uint32_t>(getAddressSpace())); 12524 bool UseOriginalValue = 12525 OriginalValue->getType()->getPointerAddressSpace() == 12526 static_cast<uint32_t>(getAddressSpace()); 12527 12528 bool Changed = false; 12529 12530 auto MakeChange = [&](Instruction *I, Use &U) { 12531 Changed = true; 12532 if (UseOriginalValue) { 12533 A.changeUseAfterManifest(U, *OriginalValue); 12534 return; 12535 } 12536 Instruction *CastInst = new AddrSpaceCastInst(OriginalValue, NewPtrTy); 12537 CastInst->insertBefore(cast<Instruction>(I)); 12538 A.changeUseAfterManifest(U, *CastInst); 12539 }; 12540 12541 auto Pred = [&](const Use &U, bool &) { 12542 if (U.get() != AssociatedValue) 12543 return true; 12544 auto *Inst = dyn_cast<Instruction>(U.getUser()); 12545 if (!Inst) 12546 return true; 12547 // This is a WA to make sure we only change uses from the corresponding 12548 // CGSCC if the AA is run on CGSCC instead of the entire module. 12549 if (!A.isRunOn(Inst->getFunction())) 12550 return true; 12551 if (isa<LoadInst>(Inst)) 12552 MakeChange(Inst, const_cast<Use &>(U)); 12553 if (isa<StoreInst>(Inst)) { 12554 // We only make changes if the use is the pointer operand. 12555 if (U.getOperandNo() == 1) 12556 MakeChange(Inst, const_cast<Use &>(U)); 12557 } 12558 return true; 12559 }; 12560 12561 // It doesn't matter if we can't check all uses as we can simply 12562 // conservatively ignore those that can not be visited. 12563 (void)A.checkForAllUses(Pred, *this, getAssociatedValue(), 12564 /* CheckBBLivenessOnly */ true); 12565 12566 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 12567 } 12568 12569 /// See AbstractAttribute::getAsStr(). 12570 const std::string getAsStr(Attributor *A) const override { 12571 if (!isValidState()) 12572 return "addrspace(<invalid>)"; 12573 return "addrspace(" + 12574 (AssumedAddressSpace == NoAddressSpace 12575 ? "none" 12576 : std::to_string(AssumedAddressSpace)) + 12577 ")"; 12578 } 12579 12580 private: 12581 int32_t AssumedAddressSpace = NoAddressSpace; 12582 12583 bool takeAddressSpace(int32_t AS) { 12584 if (AssumedAddressSpace == NoAddressSpace) { 12585 AssumedAddressSpace = AS; 12586 return true; 12587 } 12588 return AssumedAddressSpace == AS; 12589 } 12590 12591 static Value *peelAddrspacecast(Value *V) { 12592 if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) 12593 return peelAddrspacecast(I->getPointerOperand()); 12594 if (auto *C = dyn_cast<ConstantExpr>(V)) 12595 if (C->getOpcode() == Instruction::AddrSpaceCast) 12596 return peelAddrspacecast(C->getOperand(0)); 12597 return V; 12598 } 12599 }; 12600 12601 struct AAAddressSpaceFloating final : AAAddressSpaceImpl { 12602 AAAddressSpaceFloating(const IRPosition &IRP, Attributor &A) 12603 : AAAddressSpaceImpl(IRP, A) {} 12604 12605 void trackStatistics() const override { 12606 STATS_DECLTRACK_FLOATING_ATTR(addrspace); 12607 } 12608 }; 12609 12610 struct AAAddressSpaceReturned final : AAAddressSpaceImpl { 12611 AAAddressSpaceReturned(const IRPosition &IRP, Attributor &A) 12612 : AAAddressSpaceImpl(IRP, A) {} 12613 12614 /// See AbstractAttribute::initialize(...). 12615 void initialize(Attributor &A) override { 12616 // TODO: we don't rewrite function argument for now because it will need to 12617 // rewrite the function signature and all call sites. 12618 (void)indicatePessimisticFixpoint(); 12619 } 12620 12621 void trackStatistics() const override { 12622 STATS_DECLTRACK_FNRET_ATTR(addrspace); 12623 } 12624 }; 12625 12626 struct AAAddressSpaceCallSiteReturned final : AAAddressSpaceImpl { 12627 AAAddressSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A) 12628 : AAAddressSpaceImpl(IRP, A) {} 12629 12630 void trackStatistics() const override { 12631 STATS_DECLTRACK_CSRET_ATTR(addrspace); 12632 } 12633 }; 12634 12635 struct AAAddressSpaceArgument final : AAAddressSpaceImpl { 12636 AAAddressSpaceArgument(const IRPosition &IRP, Attributor &A) 12637 : AAAddressSpaceImpl(IRP, A) {} 12638 12639 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(addrspace); } 12640 }; 12641 12642 struct AAAddressSpaceCallSiteArgument final : AAAddressSpaceImpl { 12643 AAAddressSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A) 12644 : AAAddressSpaceImpl(IRP, A) {} 12645 12646 /// See AbstractAttribute::initialize(...). 12647 void initialize(Attributor &A) override { 12648 // TODO: we don't rewrite call site argument for now because it will need to 12649 // rewrite the function signature of the callee. 12650 (void)indicatePessimisticFixpoint(); 12651 } 12652 12653 void trackStatistics() const override { 12654 STATS_DECLTRACK_CSARG_ATTR(addrspace); 12655 } 12656 }; 12657 } // namespace 12658 12659 /// ----------- Allocation Info ---------- 12660 namespace { 12661 struct AAAllocationInfoImpl : public AAAllocationInfo { 12662 AAAllocationInfoImpl(const IRPosition &IRP, Attributor &A) 12663 : AAAllocationInfo(IRP, A) {} 12664 12665 std::optional<TypeSize> getAllocatedSize() const override { 12666 assert(isValidState() && "the AA is invalid"); 12667 return AssumedAllocatedSize; 12668 } 12669 12670 std::optional<TypeSize> findInitialAllocationSize(Instruction *I, 12671 const DataLayout &DL) { 12672 12673 // TODO: implement case for malloc like instructions 12674 switch (I->getOpcode()) { 12675 case Instruction::Alloca: { 12676 AllocaInst *AI = cast<AllocaInst>(I); 12677 return AI->getAllocationSize(DL); 12678 } 12679 default: 12680 return std::nullopt; 12681 } 12682 } 12683 12684 ChangeStatus updateImpl(Attributor &A) override { 12685 12686 const IRPosition &IRP = getIRPosition(); 12687 Instruction *I = IRP.getCtxI(); 12688 12689 // TODO: update check for malloc like calls 12690 if (!isa<AllocaInst>(I)) 12691 return indicatePessimisticFixpoint(); 12692 12693 bool IsKnownNoCapture; 12694 if (!AA::hasAssumedIRAttr<Attribute::NoCapture>( 12695 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture)) 12696 return indicatePessimisticFixpoint(); 12697 12698 const AAPointerInfo *PI = 12699 A.getOrCreateAAFor<AAPointerInfo>(IRP, *this, DepClassTy::REQUIRED); 12700 12701 if (!PI) 12702 return indicatePessimisticFixpoint(); 12703 12704 if (!PI->getState().isValidState()) 12705 return indicatePessimisticFixpoint(); 12706 12707 const DataLayout &DL = A.getDataLayout(); 12708 const auto AllocationSize = findInitialAllocationSize(I, DL); 12709 12710 // If allocation size is nullopt, we give up. 12711 if (!AllocationSize) 12712 return indicatePessimisticFixpoint(); 12713 12714 // For zero sized allocations, we give up. 12715 // Since we can't reduce further 12716 if (*AllocationSize == 0) 12717 return indicatePessimisticFixpoint(); 12718 12719 int64_t BinSize = PI->numOffsetBins(); 12720 12721 // TODO: implement for multiple bins 12722 if (BinSize > 1) 12723 return indicatePessimisticFixpoint(); 12724 12725 if (BinSize == 0) { 12726 auto NewAllocationSize = std::optional<TypeSize>(TypeSize(0, false)); 12727 if (!changeAllocationSize(NewAllocationSize)) 12728 return ChangeStatus::UNCHANGED; 12729 return ChangeStatus::CHANGED; 12730 } 12731 12732 // TODO: refactor this to be part of multiple bin case 12733 const auto &It = PI->begin(); 12734 12735 // TODO: handle if Offset is not zero 12736 if (It->first.Offset != 0) 12737 return indicatePessimisticFixpoint(); 12738 12739 uint64_t SizeOfBin = It->first.Offset + It->first.Size; 12740 12741 if (SizeOfBin >= *AllocationSize) 12742 return indicatePessimisticFixpoint(); 12743 12744 auto NewAllocationSize = 12745 std::optional<TypeSize>(TypeSize(SizeOfBin * 8, false)); 12746 12747 if (!changeAllocationSize(NewAllocationSize)) 12748 return ChangeStatus::UNCHANGED; 12749 12750 return ChangeStatus::CHANGED; 12751 } 12752 12753 /// See AbstractAttribute::manifest(...). 12754 ChangeStatus manifest(Attributor &A) override { 12755 12756 assert(isValidState() && 12757 "Manifest should only be called if the state is valid."); 12758 12759 Instruction *I = getIRPosition().getCtxI(); 12760 12761 auto FixedAllocatedSizeInBits = getAllocatedSize()->getFixedValue(); 12762 12763 unsigned long NumBytesToAllocate = (FixedAllocatedSizeInBits + 7) / 8; 12764 12765 switch (I->getOpcode()) { 12766 // TODO: add case for malloc like calls 12767 case Instruction::Alloca: { 12768 12769 AllocaInst *AI = cast<AllocaInst>(I); 12770 12771 Type *CharType = Type::getInt8Ty(I->getContext()); 12772 12773 auto *NumBytesToValue = 12774 ConstantInt::get(I->getContext(), APInt(32, NumBytesToAllocate)); 12775 12776 BasicBlock::iterator insertPt = AI->getIterator(); 12777 insertPt = std::next(insertPt); 12778 AllocaInst *NewAllocaInst = 12779 new AllocaInst(CharType, AI->getAddressSpace(), NumBytesToValue, 12780 AI->getAlign(), AI->getName(), insertPt); 12781 12782 if (A.changeAfterManifest(IRPosition::inst(*AI), *NewAllocaInst)) 12783 return ChangeStatus::CHANGED; 12784 12785 break; 12786 } 12787 default: 12788 break; 12789 } 12790 12791 return ChangeStatus::UNCHANGED; 12792 } 12793 12794 /// See AbstractAttribute::getAsStr(). 12795 const std::string getAsStr(Attributor *A) const override { 12796 if (!isValidState()) 12797 return "allocationinfo(<invalid>)"; 12798 return "allocationinfo(" + 12799 (AssumedAllocatedSize == HasNoAllocationSize 12800 ? "none" 12801 : std::to_string(AssumedAllocatedSize->getFixedValue())) + 12802 ")"; 12803 } 12804 12805 private: 12806 std::optional<TypeSize> AssumedAllocatedSize = HasNoAllocationSize; 12807 12808 // Maintain the computed allocation size of the object. 12809 // Returns (bool) weather the size of the allocation was modified or not. 12810 bool changeAllocationSize(std::optional<TypeSize> Size) { 12811 if (AssumedAllocatedSize == HasNoAllocationSize || 12812 AssumedAllocatedSize != Size) { 12813 AssumedAllocatedSize = Size; 12814 return true; 12815 } 12816 return false; 12817 } 12818 }; 12819 12820 struct AAAllocationInfoFloating : AAAllocationInfoImpl { 12821 AAAllocationInfoFloating(const IRPosition &IRP, Attributor &A) 12822 : AAAllocationInfoImpl(IRP, A) {} 12823 12824 void trackStatistics() const override { 12825 STATS_DECLTRACK_FLOATING_ATTR(allocationinfo); 12826 } 12827 }; 12828 12829 struct AAAllocationInfoReturned : AAAllocationInfoImpl { 12830 AAAllocationInfoReturned(const IRPosition &IRP, Attributor &A) 12831 : AAAllocationInfoImpl(IRP, A) {} 12832 12833 /// See AbstractAttribute::initialize(...). 12834 void initialize(Attributor &A) override { 12835 // TODO: we don't rewrite function argument for now because it will need to 12836 // rewrite the function signature and all call sites 12837 (void)indicatePessimisticFixpoint(); 12838 } 12839 12840 void trackStatistics() const override { 12841 STATS_DECLTRACK_FNRET_ATTR(allocationinfo); 12842 } 12843 }; 12844 12845 struct AAAllocationInfoCallSiteReturned : AAAllocationInfoImpl { 12846 AAAllocationInfoCallSiteReturned(const IRPosition &IRP, Attributor &A) 12847 : AAAllocationInfoImpl(IRP, A) {} 12848 12849 void trackStatistics() const override { 12850 STATS_DECLTRACK_CSRET_ATTR(allocationinfo); 12851 } 12852 }; 12853 12854 struct AAAllocationInfoArgument : AAAllocationInfoImpl { 12855 AAAllocationInfoArgument(const IRPosition &IRP, Attributor &A) 12856 : AAAllocationInfoImpl(IRP, A) {} 12857 12858 void trackStatistics() const override { 12859 STATS_DECLTRACK_ARG_ATTR(allocationinfo); 12860 } 12861 }; 12862 12863 struct AAAllocationInfoCallSiteArgument : AAAllocationInfoImpl { 12864 AAAllocationInfoCallSiteArgument(const IRPosition &IRP, Attributor &A) 12865 : AAAllocationInfoImpl(IRP, A) {} 12866 12867 /// See AbstractAttribute::initialize(...). 12868 void initialize(Attributor &A) override { 12869 12870 (void)indicatePessimisticFixpoint(); 12871 } 12872 12873 void trackStatistics() const override { 12874 STATS_DECLTRACK_CSARG_ATTR(allocationinfo); 12875 } 12876 }; 12877 } // namespace 12878 12879 const char AANoUnwind::ID = 0; 12880 const char AANoSync::ID = 0; 12881 const char AANoFree::ID = 0; 12882 const char AANonNull::ID = 0; 12883 const char AAMustProgress::ID = 0; 12884 const char AANoRecurse::ID = 0; 12885 const char AANonConvergent::ID = 0; 12886 const char AAWillReturn::ID = 0; 12887 const char AAUndefinedBehavior::ID = 0; 12888 const char AANoAlias::ID = 0; 12889 const char AAIntraFnReachability::ID = 0; 12890 const char AANoReturn::ID = 0; 12891 const char AAIsDead::ID = 0; 12892 const char AADereferenceable::ID = 0; 12893 const char AAAlign::ID = 0; 12894 const char AAInstanceInfo::ID = 0; 12895 const char AANoCapture::ID = 0; 12896 const char AAValueSimplify::ID = 0; 12897 const char AAHeapToStack::ID = 0; 12898 const char AAPrivatizablePtr::ID = 0; 12899 const char AAMemoryBehavior::ID = 0; 12900 const char AAMemoryLocation::ID = 0; 12901 const char AAValueConstantRange::ID = 0; 12902 const char AAPotentialConstantValues::ID = 0; 12903 const char AAPotentialValues::ID = 0; 12904 const char AANoUndef::ID = 0; 12905 const char AANoFPClass::ID = 0; 12906 const char AACallEdges::ID = 0; 12907 const char AAInterFnReachability::ID = 0; 12908 const char AAPointerInfo::ID = 0; 12909 const char AAAssumptionInfo::ID = 0; 12910 const char AAUnderlyingObjects::ID = 0; 12911 const char AAAddressSpace::ID = 0; 12912 const char AAAllocationInfo::ID = 0; 12913 const char AAIndirectCallInfo::ID = 0; 12914 const char AAGlobalValueInfo::ID = 0; 12915 const char AADenormalFPMath::ID = 0; 12916 12917 // Macro magic to create the static generator function for attributes that 12918 // follow the naming scheme. 12919 12920 #define SWITCH_PK_INV(CLASS, PK, POS_NAME) \ 12921 case IRPosition::PK: \ 12922 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!"); 12923 12924 #define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \ 12925 case IRPosition::PK: \ 12926 AA = new (A.Allocator) CLASS##SUFFIX(IRP, A); \ 12927 ++NumAAs; \ 12928 break; 12929 12930 #define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \ 12931 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 12932 CLASS *AA = nullptr; \ 12933 switch (IRP.getPositionKind()) { \ 12934 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \ 12935 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \ 12936 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \ 12937 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \ 12938 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \ 12939 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \ 12940 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \ 12941 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \ 12942 } \ 12943 return *AA; \ 12944 } 12945 12946 #define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \ 12947 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 12948 CLASS *AA = nullptr; \ 12949 switch (IRP.getPositionKind()) { \ 12950 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \ 12951 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \ 12952 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \ 12953 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \ 12954 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \ 12955 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \ 12956 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \ 12957 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \ 12958 } \ 12959 return *AA; \ 12960 } 12961 12962 #define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS) \ 12963 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 12964 CLASS *AA = nullptr; \ 12965 switch (IRP.getPositionKind()) { \ 12966 SWITCH_PK_CREATE(CLASS, IRP, POS, SUFFIX) \ 12967 default: \ 12968 llvm_unreachable("Cannot create " #CLASS " for position otherthan " #POS \ 12969 " position!"); \ 12970 } \ 12971 return *AA; \ 12972 } 12973 12974 #define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \ 12975 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 12976 CLASS *AA = nullptr; \ 12977 switch (IRP.getPositionKind()) { \ 12978 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \ 12979 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \ 12980 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \ 12981 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \ 12982 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \ 12983 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \ 12984 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \ 12985 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \ 12986 } \ 12987 return *AA; \ 12988 } 12989 12990 #define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \ 12991 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 12992 CLASS *AA = nullptr; \ 12993 switch (IRP.getPositionKind()) { \ 12994 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \ 12995 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \ 12996 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \ 12997 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \ 12998 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \ 12999 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \ 13000 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \ 13001 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \ 13002 } \ 13003 return *AA; \ 13004 } 13005 13006 #define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \ 13007 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 13008 CLASS *AA = nullptr; \ 13009 switch (IRP.getPositionKind()) { \ 13010 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \ 13011 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \ 13012 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \ 13013 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \ 13014 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \ 13015 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \ 13016 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \ 13017 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \ 13018 } \ 13019 return *AA; \ 13020 } 13021 13022 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUnwind) 13023 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoSync) 13024 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoRecurse) 13025 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAWillReturn) 13026 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoReturn) 13027 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryLocation) 13028 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AACallEdges) 13029 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAssumptionInfo) 13030 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMustProgress) 13031 13032 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonNull) 13033 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoAlias) 13034 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPrivatizablePtr) 13035 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADereferenceable) 13036 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAlign) 13037 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAInstanceInfo) 13038 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoCapture) 13039 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueConstantRange) 13040 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPotentialConstantValues) 13041 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPotentialValues) 13042 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUndef) 13043 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFPClass) 13044 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPointerInfo) 13045 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAddressSpace) 13046 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAllocationInfo) 13047 13048 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify) 13049 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIsDead) 13050 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree) 13051 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAUnderlyingObjects) 13052 13053 CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(IRP_CALL_SITE, CallSite, 13054 AAIndirectCallInfo) 13055 CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(IRP_FLOAT, Floating, 13056 AAGlobalValueInfo) 13057 13058 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAHeapToStack) 13059 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAUndefinedBehavior) 13060 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonConvergent) 13061 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIntraFnReachability) 13062 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAInterFnReachability) 13063 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADenormalFPMath) 13064 13065 CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryBehavior) 13066 13067 #undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION 13068 #undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION 13069 #undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION 13070 #undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION 13071 #undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION 13072 #undef CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION 13073 #undef SWITCH_PK_CREATE 13074 #undef SWITCH_PK_INV 13075