1 //===- AttributorAttributes.cpp - Attributes for Attributor deduction -----===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // See the Attributor.h file comment and the class descriptions in that file for 10 // more information. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Transforms/IPO/Attributor.h" 15 16 #include "llvm/ADT/APInt.h" 17 #include "llvm/ADT/ArrayRef.h" 18 #include "llvm/ADT/DenseMapInfo.h" 19 #include "llvm/ADT/MapVector.h" 20 #include "llvm/ADT/SCCIterator.h" 21 #include "llvm/ADT/STLExtras.h" 22 #include "llvm/ADT/SetOperations.h" 23 #include "llvm/ADT/SetVector.h" 24 #include "llvm/ADT/SmallPtrSet.h" 25 #include "llvm/ADT/SmallVector.h" 26 #include "llvm/ADT/Statistic.h" 27 #include "llvm/ADT/StringExtras.h" 28 #include "llvm/Analysis/AliasAnalysis.h" 29 #include "llvm/Analysis/AssumeBundleQueries.h" 30 #include "llvm/Analysis/AssumptionCache.h" 31 #include "llvm/Analysis/CaptureTracking.h" 32 #include "llvm/Analysis/CycleAnalysis.h" 33 #include "llvm/Analysis/InstructionSimplify.h" 34 #include "llvm/Analysis/LazyValueInfo.h" 35 #include "llvm/Analysis/MemoryBuiltins.h" 36 #include "llvm/Analysis/ScalarEvolution.h" 37 #include "llvm/Analysis/TargetTransformInfo.h" 38 #include "llvm/Analysis/ValueTracking.h" 39 #include "llvm/IR/Argument.h" 40 #include "llvm/IR/Assumptions.h" 41 #include "llvm/IR/Attributes.h" 42 #include "llvm/IR/BasicBlock.h" 43 #include "llvm/IR/Constant.h" 44 #include "llvm/IR/Constants.h" 45 #include "llvm/IR/DataLayout.h" 46 #include "llvm/IR/DerivedTypes.h" 47 #include "llvm/IR/GlobalValue.h" 48 #include "llvm/IR/IRBuilder.h" 49 #include "llvm/IR/InlineAsm.h" 50 #include "llvm/IR/InstrTypes.h" 51 #include "llvm/IR/Instruction.h" 52 #include "llvm/IR/Instructions.h" 53 #include "llvm/IR/IntrinsicInst.h" 54 #include "llvm/IR/IntrinsicsAMDGPU.h" 55 #include "llvm/IR/IntrinsicsNVPTX.h" 56 #include "llvm/IR/LLVMContext.h" 57 #include "llvm/IR/MDBuilder.h" 58 #include "llvm/IR/NoFolder.h" 59 #include "llvm/IR/Value.h" 60 #include "llvm/IR/ValueHandle.h" 61 #include "llvm/Support/Alignment.h" 62 #include "llvm/Support/Casting.h" 63 #include "llvm/Support/CommandLine.h" 64 #include "llvm/Support/ErrorHandling.h" 65 #include "llvm/Support/GraphWriter.h" 66 #include "llvm/Support/MathExtras.h" 67 #include "llvm/Support/TypeSize.h" 68 #include "llvm/Support/raw_ostream.h" 69 #include "llvm/Transforms/Utils/BasicBlockUtils.h" 70 #include "llvm/Transforms/Utils/CallPromotionUtils.h" 71 #include "llvm/Transforms/Utils/Local.h" 72 #include "llvm/Transforms/Utils/ValueMapper.h" 73 #include <cassert> 74 #include <numeric> 75 #include <optional> 76 #include <string> 77 78 using namespace llvm; 79 80 #define DEBUG_TYPE "attributor" 81 82 static cl::opt<bool> ManifestInternal( 83 "attributor-manifest-internal", cl::Hidden, 84 cl::desc("Manifest Attributor internal string attributes."), 85 cl::init(false)); 86 87 static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128), 88 cl::Hidden); 89 90 template <> 91 unsigned llvm::PotentialConstantIntValuesState::MaxPotentialValues = 0; 92 93 template <> unsigned llvm::PotentialLLVMValuesState::MaxPotentialValues = -1; 94 95 static cl::opt<unsigned, true> MaxPotentialValues( 96 "attributor-max-potential-values", cl::Hidden, 97 cl::desc("Maximum number of potential values to be " 98 "tracked for each position."), 99 cl::location(llvm::PotentialConstantIntValuesState::MaxPotentialValues), 100 cl::init(7)); 101 102 static cl::opt<int> MaxPotentialValuesIterations( 103 "attributor-max-potential-values-iterations", cl::Hidden, 104 cl::desc( 105 "Maximum number of iterations we keep dismantling potential values."), 106 cl::init(64)); 107 108 STATISTIC(NumAAs, "Number of abstract attributes created"); 109 STATISTIC(NumIndirectCallsPromoted, "Number of indirect calls promoted"); 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 ReturnedOffsets = R.ReturnedOffsets; 830 return *this; 831 } 832 833 State &operator=(State &&R) { 834 if (this == &R) 835 return *this; 836 std::swap(BS, R.BS); 837 std::swap(AccessList, R.AccessList); 838 std::swap(OffsetBins, R.OffsetBins); 839 std::swap(RemoteIMap, R.RemoteIMap); 840 std::swap(ReturnedOffsets, R.ReturnedOffsets); 841 return *this; 842 } 843 844 /// Add a new Access to the state at offset \p Offset and with size \p Size. 845 /// The access is associated with \p I, writes \p Content (if anything), and 846 /// is of kind \p Kind. If an Access already exists for the same \p I and same 847 /// \p RemoteI, the two are combined, potentially losing information about 848 /// offset and size. The resulting access must now be moved from its original 849 /// OffsetBin to the bin for its new offset. 850 /// 851 /// \Returns CHANGED, if the state changed, UNCHANGED otherwise. 852 ChangeStatus addAccess(Attributor &A, const AAPointerInfo::RangeList &Ranges, 853 Instruction &I, std::optional<Value *> Content, 854 AAPointerInfo::AccessKind Kind, Type *Ty, 855 Instruction *RemoteI = nullptr); 856 857 AAPointerInfo::const_bin_iterator begin() const { return OffsetBins.begin(); } 858 AAPointerInfo::const_bin_iterator end() const { return OffsetBins.end(); } 859 int64_t numOffsetBins() const { return OffsetBins.size(); } 860 861 const AAPointerInfo::Access &getAccess(unsigned Index) const { 862 return AccessList[Index]; 863 } 864 865 protected: 866 // Every memory instruction results in an Access object. We maintain a list of 867 // all Access objects that we own, along with the following maps: 868 // 869 // - OffsetBins: RangeTy -> { Access } 870 // - RemoteIMap: RemoteI x LocalI -> Access 871 // 872 // A RemoteI is any instruction that accesses memory. RemoteI is different 873 // from LocalI if and only if LocalI is a call; then RemoteI is some 874 // instruction in the callgraph starting from LocalI. Multiple paths in the 875 // callgraph from LocalI to RemoteI may produce multiple accesses, but these 876 // are all combined into a single Access object. This may result in loss of 877 // information in RangeTy in the Access object. 878 SmallVector<AAPointerInfo::Access> AccessList; 879 AAPointerInfo::OffsetBinsTy OffsetBins; 880 DenseMap<const Instruction *, SmallVector<unsigned>> RemoteIMap; 881 882 /// Flag to determine if the underlying pointer is reaching a return statement 883 /// in the associated function or not. Returns in other functions cause 884 /// invalidation. 885 AAPointerInfo::OffsetInfo ReturnedOffsets; 886 887 /// See AAPointerInfo::forallInterferingAccesses. 888 template <typename F> 889 bool forallInterferingAccesses(AA::RangeTy Range, F CB) const { 890 if (!isValidState() || !ReturnedOffsets.isUnassigned()) 891 return false; 892 893 for (const auto &It : OffsetBins) { 894 AA::RangeTy ItRange = It.getFirst(); 895 if (!Range.mayOverlap(ItRange)) 896 continue; 897 bool IsExact = Range == ItRange && !Range.offsetOrSizeAreUnknown(); 898 for (auto Index : It.getSecond()) { 899 auto &Access = AccessList[Index]; 900 if (!CB(Access, IsExact)) 901 return false; 902 } 903 } 904 return true; 905 } 906 907 /// See AAPointerInfo::forallInterferingAccesses. 908 template <typename F> 909 bool forallInterferingAccesses(Instruction &I, F CB, 910 AA::RangeTy &Range) const { 911 if (!isValidState() || !ReturnedOffsets.isUnassigned()) 912 return false; 913 914 auto LocalList = RemoteIMap.find(&I); 915 if (LocalList == RemoteIMap.end()) { 916 return true; 917 } 918 919 for (unsigned Index : LocalList->getSecond()) { 920 for (auto &R : AccessList[Index]) { 921 Range &= R; 922 if (Range.offsetAndSizeAreUnknown()) 923 break; 924 } 925 } 926 return forallInterferingAccesses(Range, CB); 927 } 928 929 private: 930 /// State to track fixpoint and validity. 931 BooleanState BS; 932 }; 933 934 ChangeStatus AA::PointerInfo::State::addAccess( 935 Attributor &A, const AAPointerInfo::RangeList &Ranges, Instruction &I, 936 std::optional<Value *> Content, AAPointerInfo::AccessKind Kind, Type *Ty, 937 Instruction *RemoteI) { 938 RemoteI = RemoteI ? RemoteI : &I; 939 940 // Check if we have an access for this instruction, if not, simply add it. 941 auto &LocalList = RemoteIMap[RemoteI]; 942 bool AccExists = false; 943 unsigned AccIndex = AccessList.size(); 944 for (auto Index : LocalList) { 945 auto &A = AccessList[Index]; 946 if (A.getLocalInst() == &I) { 947 AccExists = true; 948 AccIndex = Index; 949 break; 950 } 951 } 952 953 auto AddToBins = [&](const AAPointerInfo::RangeList &ToAdd) { 954 LLVM_DEBUG(if (ToAdd.size()) dbgs() 955 << "[AAPointerInfo] Inserting access in new offset bins\n";); 956 957 for (auto Key : ToAdd) { 958 LLVM_DEBUG(dbgs() << " key " << Key << "\n"); 959 OffsetBins[Key].insert(AccIndex); 960 } 961 }; 962 963 if (!AccExists) { 964 AccessList.emplace_back(&I, RemoteI, Ranges, Content, Kind, Ty); 965 assert((AccessList.size() == AccIndex + 1) && 966 "New Access should have been at AccIndex"); 967 LocalList.push_back(AccIndex); 968 AddToBins(AccessList[AccIndex].getRanges()); 969 return ChangeStatus::CHANGED; 970 } 971 972 // Combine the new Access with the existing Access, and then update the 973 // mapping in the offset bins. 974 AAPointerInfo::Access Acc(&I, RemoteI, Ranges, Content, Kind, Ty); 975 auto &Current = AccessList[AccIndex]; 976 auto Before = Current; 977 Current &= Acc; 978 if (Current == Before) 979 return ChangeStatus::UNCHANGED; 980 981 auto &ExistingRanges = Before.getRanges(); 982 auto &NewRanges = Current.getRanges(); 983 984 // Ranges that are in the old access but not the new access need to be removed 985 // from the offset bins. 986 AAPointerInfo::RangeList ToRemove; 987 AAPointerInfo::RangeList::set_difference(ExistingRanges, NewRanges, ToRemove); 988 LLVM_DEBUG(if (ToRemove.size()) dbgs() 989 << "[AAPointerInfo] Removing access from old offset bins\n";); 990 991 for (auto Key : ToRemove) { 992 LLVM_DEBUG(dbgs() << " key " << Key << "\n"); 993 assert(OffsetBins.count(Key) && "Existing Access must be in some bin."); 994 auto &Bin = OffsetBins[Key]; 995 assert(Bin.count(AccIndex) && 996 "Expected bin to actually contain the Access."); 997 Bin.erase(AccIndex); 998 } 999 1000 // Ranges that are in the new access but not the old access need to be added 1001 // to the offset bins. 1002 AAPointerInfo::RangeList ToAdd; 1003 AAPointerInfo::RangeList::set_difference(NewRanges, ExistingRanges, ToAdd); 1004 AddToBins(ToAdd); 1005 return ChangeStatus::CHANGED; 1006 } 1007 1008 namespace { 1009 1010 #ifndef NDEBUG 1011 static raw_ostream &operator<<(raw_ostream &OS, 1012 const AAPointerInfo::OffsetInfo &OI) { 1013 ListSeparator LS; 1014 OS << "["; 1015 for (auto Offset : OI) { 1016 OS << LS << Offset; 1017 } 1018 OS << "]"; 1019 return OS; 1020 } 1021 #endif // NDEBUG 1022 1023 struct AAPointerInfoImpl 1024 : public StateWrapper<AA::PointerInfo::State, AAPointerInfo> { 1025 using BaseTy = StateWrapper<AA::PointerInfo::State, AAPointerInfo>; 1026 AAPointerInfoImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {} 1027 1028 /// See AbstractAttribute::getAsStr(). 1029 const std::string getAsStr(Attributor *A) const override { 1030 return std::string("PointerInfo ") + 1031 (isValidState() ? (std::string("#") + 1032 std::to_string(OffsetBins.size()) + " bins") 1033 : "<invalid>") + 1034 (reachesReturn() 1035 ? (" (returned:" + 1036 join(map_range(ReturnedOffsets, 1037 [](int64_t O) { return std::to_string(O); }), 1038 ", ") + 1039 ")") 1040 : ""); 1041 } 1042 1043 /// See AbstractAttribute::manifest(...). 1044 ChangeStatus manifest(Attributor &A) override { 1045 return AAPointerInfo::manifest(A); 1046 } 1047 1048 virtual const_bin_iterator begin() const override { return State::begin(); } 1049 virtual const_bin_iterator end() const override { return State::end(); } 1050 virtual int64_t numOffsetBins() const override { 1051 return State::numOffsetBins(); 1052 } 1053 virtual bool reachesReturn() const override { 1054 return !ReturnedOffsets.isUnassigned(); 1055 } 1056 virtual void addReturnedOffsetsTo(OffsetInfo &OI) const override { 1057 if (ReturnedOffsets.isUnknown()) { 1058 OI.setUnknown(); 1059 return; 1060 } 1061 1062 OffsetInfo MergedOI; 1063 for (auto Offset : ReturnedOffsets) { 1064 OffsetInfo TmpOI = OI; 1065 TmpOI.addToAll(Offset); 1066 MergedOI.merge(TmpOI); 1067 } 1068 OI = std::move(MergedOI); 1069 } 1070 1071 ChangeStatus setReachesReturn(const OffsetInfo &ReachedReturnedOffsets) { 1072 if (ReturnedOffsets.isUnknown()) 1073 return ChangeStatus::UNCHANGED; 1074 if (ReachedReturnedOffsets.isUnknown()) { 1075 ReturnedOffsets.setUnknown(); 1076 return ChangeStatus::CHANGED; 1077 } 1078 if (ReturnedOffsets.merge(ReachedReturnedOffsets)) 1079 return ChangeStatus::CHANGED; 1080 return ChangeStatus::UNCHANGED; 1081 } 1082 1083 bool forallInterferingAccesses( 1084 AA::RangeTy Range, 1085 function_ref<bool(const AAPointerInfo::Access &, bool)> CB) 1086 const override { 1087 return State::forallInterferingAccesses(Range, CB); 1088 } 1089 1090 bool forallInterferingAccesses( 1091 Attributor &A, const AbstractAttribute &QueryingAA, Instruction &I, 1092 bool FindInterferingWrites, bool FindInterferingReads, 1093 function_ref<bool(const Access &, bool)> UserCB, bool &HasBeenWrittenTo, 1094 AA::RangeTy &Range, 1095 function_ref<bool(const Access &)> SkipCB) const override { 1096 HasBeenWrittenTo = false; 1097 1098 SmallPtrSet<const Access *, 8> DominatingWrites; 1099 SmallVector<std::pair<const Access *, bool>, 8> InterferingAccesses; 1100 1101 Function &Scope = *I.getFunction(); 1102 bool IsKnownNoSync; 1103 bool IsAssumedNoSync = AA::hasAssumedIRAttr<Attribute::NoSync>( 1104 A, &QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL, 1105 IsKnownNoSync); 1106 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>( 1107 IRPosition::function(Scope), &QueryingAA, DepClassTy::NONE); 1108 bool AllInSameNoSyncFn = IsAssumedNoSync; 1109 bool InstIsExecutedByInitialThreadOnly = 1110 ExecDomainAA && ExecDomainAA->isExecutedByInitialThreadOnly(I); 1111 1112 // If the function is not ending in aligned barriers, we need the stores to 1113 // be in aligned barriers. The load being in one is not sufficient since the 1114 // store might be executed by a thread that disappears after, causing the 1115 // aligned barrier guarding the load to unblock and the load to read a value 1116 // that has no CFG path to the load. 1117 bool InstIsExecutedInAlignedRegion = 1118 FindInterferingReads && ExecDomainAA && 1119 ExecDomainAA->isExecutedInAlignedRegion(A, I); 1120 1121 if (InstIsExecutedInAlignedRegion || InstIsExecutedByInitialThreadOnly) 1122 A.recordDependence(*ExecDomainAA, QueryingAA, DepClassTy::OPTIONAL); 1123 1124 InformationCache &InfoCache = A.getInfoCache(); 1125 bool IsThreadLocalObj = 1126 AA::isAssumedThreadLocalObject(A, getAssociatedValue(), *this); 1127 1128 // Helper to determine if we need to consider threading, which we cannot 1129 // right now. However, if the function is (assumed) nosync or the thread 1130 // executing all instructions is the main thread only we can ignore 1131 // threading. Also, thread-local objects do not require threading reasoning. 1132 // Finally, we can ignore threading if either access is executed in an 1133 // aligned region. 1134 auto CanIgnoreThreadingForInst = [&](const Instruction &I) -> bool { 1135 if (IsThreadLocalObj || AllInSameNoSyncFn) 1136 return true; 1137 const auto *FnExecDomainAA = 1138 I.getFunction() == &Scope 1139 ? ExecDomainAA 1140 : A.lookupAAFor<AAExecutionDomain>( 1141 IRPosition::function(*I.getFunction()), &QueryingAA, 1142 DepClassTy::NONE); 1143 if (!FnExecDomainAA) 1144 return false; 1145 if (InstIsExecutedInAlignedRegion || 1146 (FindInterferingWrites && 1147 FnExecDomainAA->isExecutedInAlignedRegion(A, I))) { 1148 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL); 1149 return true; 1150 } 1151 if (InstIsExecutedByInitialThreadOnly && 1152 FnExecDomainAA->isExecutedByInitialThreadOnly(I)) { 1153 A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL); 1154 return true; 1155 } 1156 return false; 1157 }; 1158 1159 // Helper to determine if the access is executed by the same thread as the 1160 // given instruction, for now it is sufficient to avoid any potential 1161 // threading effects as we cannot deal with them anyway. 1162 auto CanIgnoreThreading = [&](const Access &Acc) -> bool { 1163 return CanIgnoreThreadingForInst(*Acc.getRemoteInst()) || 1164 (Acc.getRemoteInst() != Acc.getLocalInst() && 1165 CanIgnoreThreadingForInst(*Acc.getLocalInst())); 1166 }; 1167 1168 // TODO: Use inter-procedural reachability and dominance. 1169 bool IsKnownNoRecurse; 1170 AA::hasAssumedIRAttr<Attribute::NoRecurse>( 1171 A, this, IRPosition::function(Scope), DepClassTy::OPTIONAL, 1172 IsKnownNoRecurse); 1173 1174 // TODO: Use reaching kernels from AAKernelInfo (or move it to 1175 // AAExecutionDomain) such that we allow scopes other than kernels as long 1176 // as the reaching kernels are disjoint. 1177 bool InstInKernel = A.getInfoCache().isKernel(Scope); 1178 bool ObjHasKernelLifetime = false; 1179 const bool UseDominanceReasoning = 1180 FindInterferingWrites && IsKnownNoRecurse; 1181 const DominatorTree *DT = 1182 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(Scope); 1183 1184 // Helper to check if a value has "kernel lifetime", that is it will not 1185 // outlive a GPU kernel. This is true for shared, constant, and local 1186 // globals on AMD and NVIDIA GPUs. 1187 auto HasKernelLifetime = [&](Value *V, Module &M) { 1188 if (!AA::isGPU(M)) 1189 return false; 1190 switch (AA::GPUAddressSpace(V->getType()->getPointerAddressSpace())) { 1191 case AA::GPUAddressSpace::Shared: 1192 case AA::GPUAddressSpace::Constant: 1193 case AA::GPUAddressSpace::Local: 1194 return true; 1195 default: 1196 return false; 1197 }; 1198 }; 1199 1200 // The IsLiveInCalleeCB will be used by the AA::isPotentiallyReachable query 1201 // to determine if we should look at reachability from the callee. For 1202 // certain pointers we know the lifetime and we do not have to step into the 1203 // callee to determine reachability as the pointer would be dead in the 1204 // callee. See the conditional initialization below. 1205 std::function<bool(const Function &)> IsLiveInCalleeCB; 1206 1207 if (auto *AI = dyn_cast<AllocaInst>(&getAssociatedValue())) { 1208 // If the alloca containing function is not recursive the alloca 1209 // must be dead in the callee. 1210 const Function *AIFn = AI->getFunction(); 1211 ObjHasKernelLifetime = A.getInfoCache().isKernel(*AIFn); 1212 bool IsKnownNoRecurse; 1213 if (AA::hasAssumedIRAttr<Attribute::NoRecurse>( 1214 A, this, IRPosition::function(*AIFn), DepClassTy::OPTIONAL, 1215 IsKnownNoRecurse)) { 1216 IsLiveInCalleeCB = [AIFn](const Function &Fn) { return AIFn != &Fn; }; 1217 } 1218 } else if (auto *GV = dyn_cast<GlobalValue>(&getAssociatedValue())) { 1219 // If the global has kernel lifetime we can stop if we reach a kernel 1220 // as it is "dead" in the (unknown) callees. 1221 ObjHasKernelLifetime = HasKernelLifetime(GV, *GV->getParent()); 1222 if (ObjHasKernelLifetime) 1223 IsLiveInCalleeCB = [&A](const Function &Fn) { 1224 return !A.getInfoCache().isKernel(Fn); 1225 }; 1226 } 1227 1228 // Set of accesses/instructions that will overwrite the result and are 1229 // therefore blockers in the reachability traversal. 1230 AA::InstExclusionSetTy ExclusionSet; 1231 1232 auto AccessCB = [&](const Access &Acc, bool Exact) { 1233 Function *AccScope = Acc.getRemoteInst()->getFunction(); 1234 bool AccInSameScope = AccScope == &Scope; 1235 1236 // If the object has kernel lifetime we can ignore accesses only reachable 1237 // by other kernels. For now we only skip accesses *in* other kernels. 1238 if (InstInKernel && ObjHasKernelLifetime && !AccInSameScope && 1239 A.getInfoCache().isKernel(*AccScope)) 1240 return true; 1241 1242 if (Exact && Acc.isMustAccess() && Acc.getRemoteInst() != &I) { 1243 if (Acc.isWrite() || (isa<LoadInst>(I) && Acc.isWriteOrAssumption())) 1244 ExclusionSet.insert(Acc.getRemoteInst()); 1245 } 1246 1247 if ((!FindInterferingWrites || !Acc.isWriteOrAssumption()) && 1248 (!FindInterferingReads || !Acc.isRead())) 1249 return true; 1250 1251 bool Dominates = FindInterferingWrites && DT && Exact && 1252 Acc.isMustAccess() && AccInSameScope && 1253 DT->dominates(Acc.getRemoteInst(), &I); 1254 if (Dominates) 1255 DominatingWrites.insert(&Acc); 1256 1257 // Track if all interesting accesses are in the same `nosync` function as 1258 // the given instruction. 1259 AllInSameNoSyncFn &= Acc.getRemoteInst()->getFunction() == &Scope; 1260 1261 InterferingAccesses.push_back({&Acc, Exact}); 1262 return true; 1263 }; 1264 if (!State::forallInterferingAccesses(I, AccessCB, Range)) 1265 return false; 1266 1267 HasBeenWrittenTo = !DominatingWrites.empty(); 1268 1269 // Dominating writes form a chain, find the least/lowest member. 1270 Instruction *LeastDominatingWriteInst = nullptr; 1271 for (const Access *Acc : DominatingWrites) { 1272 if (!LeastDominatingWriteInst) { 1273 LeastDominatingWriteInst = Acc->getRemoteInst(); 1274 } else if (DT->dominates(LeastDominatingWriteInst, 1275 Acc->getRemoteInst())) { 1276 LeastDominatingWriteInst = Acc->getRemoteInst(); 1277 } 1278 } 1279 1280 // Helper to determine if we can skip a specific write access. 1281 auto CanSkipAccess = [&](const Access &Acc, bool Exact) { 1282 if (SkipCB && SkipCB(Acc)) 1283 return true; 1284 if (!CanIgnoreThreading(Acc)) 1285 return false; 1286 1287 // Check read (RAW) dependences and write (WAR) dependences as necessary. 1288 // If we successfully excluded all effects we are interested in, the 1289 // access can be skipped. 1290 bool ReadChecked = !FindInterferingReads; 1291 bool WriteChecked = !FindInterferingWrites; 1292 1293 // If the instruction cannot reach the access, the former does not 1294 // interfere with what the access reads. 1295 if (!ReadChecked) { 1296 if (!AA::isPotentiallyReachable(A, I, *Acc.getRemoteInst(), QueryingAA, 1297 &ExclusionSet, IsLiveInCalleeCB)) 1298 ReadChecked = true; 1299 } 1300 // If the instruction cannot be reach from the access, the latter does not 1301 // interfere with what the instruction reads. 1302 if (!WriteChecked) { 1303 if (!AA::isPotentiallyReachable(A, *Acc.getRemoteInst(), I, QueryingAA, 1304 &ExclusionSet, IsLiveInCalleeCB)) 1305 WriteChecked = true; 1306 } 1307 1308 // If we still might be affected by the write of the access but there are 1309 // dominating writes in the function of the instruction 1310 // (HasBeenWrittenTo), we can try to reason that the access is overwritten 1311 // by them. This would have happend above if they are all in the same 1312 // function, so we only check the inter-procedural case. Effectively, we 1313 // want to show that there is no call after the dominting write that might 1314 // reach the access, and when it returns reach the instruction with the 1315 // updated value. To this end, we iterate all call sites, check if they 1316 // might reach the instruction without going through another access 1317 // (ExclusionSet) and at the same time might reach the access. However, 1318 // that is all part of AAInterFnReachability. 1319 if (!WriteChecked && HasBeenWrittenTo && 1320 Acc.getRemoteInst()->getFunction() != &Scope) { 1321 1322 const auto *FnReachabilityAA = A.getAAFor<AAInterFnReachability>( 1323 QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL); 1324 if (FnReachabilityAA) { 1325 // Without going backwards in the call tree, can we reach the access 1326 // from the least dominating write. Do not allow to pass the 1327 // instruction itself either. 1328 bool Inserted = ExclusionSet.insert(&I).second; 1329 1330 if (!FnReachabilityAA->instructionCanReach( 1331 A, *LeastDominatingWriteInst, 1332 *Acc.getRemoteInst()->getFunction(), &ExclusionSet)) 1333 WriteChecked = true; 1334 1335 if (Inserted) 1336 ExclusionSet.erase(&I); 1337 } 1338 } 1339 1340 if (ReadChecked && WriteChecked) 1341 return true; 1342 1343 if (!DT || !UseDominanceReasoning) 1344 return false; 1345 if (!DominatingWrites.count(&Acc)) 1346 return false; 1347 return LeastDominatingWriteInst != Acc.getRemoteInst(); 1348 }; 1349 1350 // Run the user callback on all accesses we cannot skip and return if 1351 // that succeeded for all or not. 1352 for (auto &It : InterferingAccesses) { 1353 if ((!AllInSameNoSyncFn && !IsThreadLocalObj && !ExecDomainAA) || 1354 !CanSkipAccess(*It.first, It.second)) { 1355 if (!UserCB(*It.first, It.second)) 1356 return false; 1357 } 1358 } 1359 return true; 1360 } 1361 1362 ChangeStatus translateAndAddStateFromCallee(Attributor &A, 1363 const AAPointerInfo &OtherAA, 1364 CallBase &CB) { 1365 using namespace AA::PointerInfo; 1366 if (!OtherAA.getState().isValidState() || !isValidState()) 1367 return indicatePessimisticFixpoint(); 1368 1369 ChangeStatus Changed = ChangeStatus::UNCHANGED; 1370 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA); 1371 bool IsByval = OtherAAImpl.getAssociatedArgument()->hasByValAttr(); 1372 Changed |= setReachesReturn(OtherAAImpl.ReturnedOffsets); 1373 1374 // Combine the accesses bin by bin. 1375 const auto &State = OtherAAImpl.getState(); 1376 for (const auto &It : State) { 1377 for (auto Index : It.getSecond()) { 1378 const auto &RAcc = State.getAccess(Index); 1379 if (IsByval && !RAcc.isRead()) 1380 continue; 1381 bool UsedAssumedInformation = false; 1382 AccessKind AK = RAcc.getKind(); 1383 auto Content = A.translateArgumentToCallSiteContent( 1384 RAcc.getContent(), CB, *this, UsedAssumedInformation); 1385 AK = AccessKind(AK & (IsByval ? AccessKind::AK_R : AccessKind::AK_RW)); 1386 AK = AccessKind(AK | (RAcc.isMayAccess() ? AK_MAY : AK_MUST)); 1387 1388 Changed |= addAccess(A, RAcc.getRanges(), CB, Content, AK, 1389 RAcc.getType(), RAcc.getRemoteInst()); 1390 } 1391 } 1392 return Changed; 1393 } 1394 1395 ChangeStatus translateAndAddState(Attributor &A, const AAPointerInfo &OtherAA, 1396 const OffsetInfo &Offsets, CallBase &CB, 1397 bool IsMustAcc) { 1398 using namespace AA::PointerInfo; 1399 if (!OtherAA.getState().isValidState() || !isValidState()) 1400 return indicatePessimisticFixpoint(); 1401 1402 const auto &OtherAAImpl = static_cast<const AAPointerInfoImpl &>(OtherAA); 1403 1404 // Combine the accesses bin by bin. 1405 ChangeStatus Changed = ChangeStatus::UNCHANGED; 1406 const auto &State = OtherAAImpl.getState(); 1407 for (const auto &It : State) { 1408 for (auto Index : It.getSecond()) { 1409 const auto &RAcc = State.getAccess(Index); 1410 if (!IsMustAcc && RAcc.isAssumption()) 1411 continue; 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 AccessKind AK = RAcc.getKind(); 1420 if (!IsMustAcc) 1421 AK = AccessKind((AK & ~AK_MUST) | AK_MAY); 1422 Changed |= addAccess(A, NewRanges, CB, RAcc.getContent(), AK, 1423 RAcc.getType(), RAcc.getRemoteInst()); 1424 } 1425 } 1426 } 1427 return Changed; 1428 } 1429 1430 /// Statistic tracking for all AAPointerInfo implementations. 1431 /// See AbstractAttribute::trackStatistics(). 1432 void trackPointerInfoStatistics(const IRPosition &IRP) const {} 1433 1434 /// Dump the state into \p O. 1435 void dumpState(raw_ostream &O) { 1436 for (auto &It : OffsetBins) { 1437 O << "[" << It.first.Offset << "-" << It.first.Offset + It.first.Size 1438 << "] : " << It.getSecond().size() << "\n"; 1439 for (auto AccIndex : It.getSecond()) { 1440 auto &Acc = AccessList[AccIndex]; 1441 O << " - " << Acc.getKind() << " - " << *Acc.getLocalInst() << "\n"; 1442 if (Acc.getLocalInst() != Acc.getRemoteInst()) 1443 O << " --> " << *Acc.getRemoteInst() 1444 << "\n"; 1445 if (!Acc.isWrittenValueYetUndetermined()) { 1446 if (isa_and_nonnull<Function>(Acc.getWrittenValue())) 1447 O << " - c: func " << Acc.getWrittenValue()->getName() 1448 << "\n"; 1449 else if (Acc.getWrittenValue()) 1450 O << " - c: " << *Acc.getWrittenValue() << "\n"; 1451 else 1452 O << " - c: <unknown>\n"; 1453 } 1454 } 1455 } 1456 } 1457 }; 1458 1459 struct AAPointerInfoFloating : public AAPointerInfoImpl { 1460 using AccessKind = AAPointerInfo::AccessKind; 1461 AAPointerInfoFloating(const IRPosition &IRP, Attributor &A) 1462 : AAPointerInfoImpl(IRP, A) {} 1463 1464 /// Deal with an access and signal if it was handled successfully. 1465 bool handleAccess(Attributor &A, Instruction &I, 1466 std::optional<Value *> Content, AccessKind Kind, 1467 OffsetInfo::VecTy &Offsets, ChangeStatus &Changed, 1468 Type &Ty) { 1469 using namespace AA::PointerInfo; 1470 auto Size = AA::RangeTy::Unknown; 1471 const DataLayout &DL = A.getDataLayout(); 1472 TypeSize AccessSize = DL.getTypeStoreSize(&Ty); 1473 if (!AccessSize.isScalable()) 1474 Size = AccessSize.getFixedValue(); 1475 1476 // Make a strictly ascending list of offsets as required by addAccess() 1477 SmallVector<int64_t> OffsetsSorted(Offsets.begin(), Offsets.end()); 1478 llvm::sort(OffsetsSorted); 1479 1480 VectorType *VT = dyn_cast<VectorType>(&Ty); 1481 if (!VT || VT->getElementCount().isScalable() || 1482 !Content.value_or(nullptr) || !isa<Constant>(*Content) || 1483 (*Content)->getType() != VT || 1484 DL.getTypeStoreSize(VT->getElementType()).isScalable()) { 1485 Changed = 1486 Changed | addAccess(A, {OffsetsSorted, Size}, I, Content, Kind, &Ty); 1487 } else { 1488 // Handle vector stores with constant content element-wise. 1489 // TODO: We could look for the elements or create instructions 1490 // representing them. 1491 // TODO: We need to push the Content into the range abstraction 1492 // (AA::RangeTy) to allow different content values for different 1493 // ranges. ranges. Hence, support vectors storing different values. 1494 Type *ElementType = VT->getElementType(); 1495 int64_t ElementSize = DL.getTypeStoreSize(ElementType).getFixedValue(); 1496 auto *ConstContent = cast<Constant>(*Content); 1497 Type *Int32Ty = Type::getInt32Ty(ElementType->getContext()); 1498 SmallVector<int64_t> ElementOffsets(Offsets.begin(), Offsets.end()); 1499 1500 for (int i = 0, e = VT->getElementCount().getFixedValue(); i != e; ++i) { 1501 Value *ElementContent = ConstantExpr::getExtractElement( 1502 ConstContent, ConstantInt::get(Int32Ty, i)); 1503 1504 // Add the element access. 1505 Changed = Changed | addAccess(A, {ElementOffsets, ElementSize}, I, 1506 ElementContent, Kind, ElementType); 1507 1508 // Advance the offsets for the next element. 1509 for (auto &ElementOffset : ElementOffsets) 1510 ElementOffset += ElementSize; 1511 } 1512 } 1513 return true; 1514 }; 1515 1516 /// See AbstractAttribute::updateImpl(...). 1517 ChangeStatus updateImpl(Attributor &A) override; 1518 1519 /// If the indices to \p GEP can be traced to constants, incorporate all 1520 /// of these into \p UsrOI. 1521 /// 1522 /// \return true iff \p UsrOI is updated. 1523 bool collectConstantsForGEP(Attributor &A, const DataLayout &DL, 1524 OffsetInfo &UsrOI, const OffsetInfo &PtrOI, 1525 const GEPOperator *GEP); 1526 1527 /// See AbstractAttribute::trackStatistics() 1528 void trackStatistics() const override { 1529 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition()); 1530 } 1531 }; 1532 1533 bool AAPointerInfoFloating::collectConstantsForGEP(Attributor &A, 1534 const DataLayout &DL, 1535 OffsetInfo &UsrOI, 1536 const OffsetInfo &PtrOI, 1537 const GEPOperator *GEP) { 1538 unsigned BitWidth = DL.getIndexTypeSizeInBits(GEP->getType()); 1539 SmallMapVector<Value *, APInt, 4> VariableOffsets; 1540 APInt ConstantOffset(BitWidth, 0); 1541 1542 assert(!UsrOI.isUnknown() && !PtrOI.isUnknown() && 1543 "Don't look for constant values if the offset has already been " 1544 "determined to be unknown."); 1545 1546 if (!GEP->collectOffset(DL, BitWidth, VariableOffsets, ConstantOffset)) { 1547 UsrOI.setUnknown(); 1548 return true; 1549 } 1550 1551 LLVM_DEBUG(dbgs() << "[AAPointerInfo] GEP offset is " 1552 << (VariableOffsets.empty() ? "" : "not") << " constant " 1553 << *GEP << "\n"); 1554 1555 auto Union = PtrOI; 1556 Union.addToAll(ConstantOffset.getSExtValue()); 1557 1558 // Each VI in VariableOffsets has a set of potential constant values. Every 1559 // combination of elements, picked one each from these sets, is separately 1560 // added to the original set of offsets, thus resulting in more offsets. 1561 for (const auto &VI : VariableOffsets) { 1562 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>( 1563 *this, IRPosition::value(*VI.first), DepClassTy::OPTIONAL); 1564 if (!PotentialConstantsAA || !PotentialConstantsAA->isValidState()) { 1565 UsrOI.setUnknown(); 1566 return true; 1567 } 1568 1569 // UndefValue is treated as a zero, which leaves Union as is. 1570 if (PotentialConstantsAA->undefIsContained()) 1571 continue; 1572 1573 // We need at least one constant in every set to compute an actual offset. 1574 // Otherwise, we end up pessimizing AAPointerInfo by respecting offsets that 1575 // don't actually exist. In other words, the absence of constant values 1576 // implies that the operation can be assumed dead for now. 1577 auto &AssumedSet = PotentialConstantsAA->getAssumedSet(); 1578 if (AssumedSet.empty()) 1579 return false; 1580 1581 OffsetInfo Product; 1582 for (const auto &ConstOffset : AssumedSet) { 1583 auto CopyPerOffset = Union; 1584 CopyPerOffset.addToAll(ConstOffset.getSExtValue() * 1585 VI.second.getZExtValue()); 1586 Product.merge(CopyPerOffset); 1587 } 1588 Union = Product; 1589 } 1590 1591 UsrOI = std::move(Union); 1592 return true; 1593 } 1594 1595 ChangeStatus AAPointerInfoFloating::updateImpl(Attributor &A) { 1596 using namespace AA::PointerInfo; 1597 ChangeStatus Changed = ChangeStatus::UNCHANGED; 1598 const DataLayout &DL = A.getDataLayout(); 1599 Value &AssociatedValue = getAssociatedValue(); 1600 1601 DenseMap<Value *, OffsetInfo> OffsetInfoMap; 1602 OffsetInfoMap[&AssociatedValue].insert(0); 1603 1604 auto HandlePassthroughUser = [&](Value *Usr, Value *CurPtr, bool &Follow) { 1605 // One does not simply walk into a map and assign a reference to a possibly 1606 // new location. That can cause an invalidation before the assignment 1607 // happens, like so: 1608 // 1609 // OffsetInfoMap[Usr] = OffsetInfoMap[CurPtr]; /* bad idea! */ 1610 // 1611 // The RHS is a reference that may be invalidated by an insertion caused by 1612 // the LHS. So we ensure that the side-effect of the LHS happens first. 1613 1614 assert(OffsetInfoMap.contains(CurPtr) && 1615 "CurPtr does not exist in the map!"); 1616 1617 auto &UsrOI = OffsetInfoMap[Usr]; 1618 auto &PtrOI = OffsetInfoMap[CurPtr]; 1619 assert(!PtrOI.isUnassigned() && 1620 "Cannot pass through if the input Ptr was not visited!"); 1621 UsrOI.merge(PtrOI); 1622 Follow = true; 1623 return true; 1624 }; 1625 1626 auto UsePred = [&](const Use &U, bool &Follow) -> bool { 1627 Value *CurPtr = U.get(); 1628 User *Usr = U.getUser(); 1629 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Analyze " << *CurPtr << " in " << *Usr 1630 << "\n"); 1631 assert(OffsetInfoMap.count(CurPtr) && 1632 "The current pointer offset should have been seeded!"); 1633 assert(!OffsetInfoMap[CurPtr].isUnassigned() && 1634 "Current pointer should be assigned"); 1635 1636 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Usr)) { 1637 if (CE->isCast()) 1638 return HandlePassthroughUser(Usr, CurPtr, Follow); 1639 if (!isa<GEPOperator>(CE)) { 1640 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled constant user " << *CE 1641 << "\n"); 1642 return false; 1643 } 1644 } 1645 if (auto *GEP = dyn_cast<GEPOperator>(Usr)) { 1646 // Note the order here, the Usr access might change the map, CurPtr is 1647 // already in it though. 1648 auto &UsrOI = OffsetInfoMap[Usr]; 1649 auto &PtrOI = OffsetInfoMap[CurPtr]; 1650 1651 if (UsrOI.isUnknown()) 1652 return true; 1653 1654 if (PtrOI.isUnknown()) { 1655 Follow = true; 1656 UsrOI.setUnknown(); 1657 return true; 1658 } 1659 1660 Follow = collectConstantsForGEP(A, DL, UsrOI, PtrOI, GEP); 1661 return true; 1662 } 1663 if (isa<PtrToIntInst>(Usr)) 1664 return false; 1665 if (isa<CastInst>(Usr) || isa<SelectInst>(Usr)) 1666 return HandlePassthroughUser(Usr, CurPtr, Follow); 1667 // Returns are allowed if they are in the associated functions. Users can 1668 // then check the call site return. Returns from other functions can't be 1669 // tracked and are cause for invalidation. 1670 if (auto *RI = dyn_cast<ReturnInst>(Usr)) { 1671 if (RI->getFunction() == getAssociatedFunction()) { 1672 auto &PtrOI = OffsetInfoMap[CurPtr]; 1673 Changed |= setReachesReturn(PtrOI); 1674 return true; 1675 } 1676 return false; 1677 } 1678 1679 // For PHIs we need to take care of the recurrence explicitly as the value 1680 // might change while we iterate through a loop. For now, we give up if 1681 // the PHI is not invariant. 1682 if (auto *PHI = dyn_cast<PHINode>(Usr)) { 1683 // Note the order here, the Usr access might change the map, CurPtr is 1684 // already in it though. 1685 bool IsFirstPHIUser = !OffsetInfoMap.count(PHI); 1686 auto &UsrOI = OffsetInfoMap[PHI]; 1687 auto &PtrOI = OffsetInfoMap[CurPtr]; 1688 1689 // Check if the PHI operand has already an unknown offset as we can't 1690 // improve on that anymore. 1691 if (PtrOI.isUnknown()) { 1692 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand offset unknown " 1693 << *CurPtr << " in " << *PHI << "\n"); 1694 Follow = !UsrOI.isUnknown(); 1695 UsrOI.setUnknown(); 1696 return true; 1697 } 1698 1699 // Check if the PHI is invariant (so far). 1700 if (UsrOI == PtrOI) { 1701 assert(!PtrOI.isUnassigned() && 1702 "Cannot assign if the current Ptr was not visited!"); 1703 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant (so far)"); 1704 return true; 1705 } 1706 1707 // Check if the PHI operand can be traced back to AssociatedValue. 1708 APInt Offset( 1709 DL.getIndexSizeInBits(CurPtr->getType()->getPointerAddressSpace()), 1710 0); 1711 Value *CurPtrBase = CurPtr->stripAndAccumulateConstantOffsets( 1712 DL, Offset, /* AllowNonInbounds */ true); 1713 auto It = OffsetInfoMap.find(CurPtrBase); 1714 if (It == OffsetInfoMap.end()) { 1715 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI operand is too complex " 1716 << *CurPtr << " in " << *PHI 1717 << " (base: " << *CurPtrBase << ")\n"); 1718 UsrOI.setUnknown(); 1719 Follow = true; 1720 return true; 1721 } 1722 1723 // Check if the PHI operand is not dependent on the PHI itself. Every 1724 // recurrence is a cyclic net of PHIs in the data flow, and has an 1725 // equivalent Cycle in the control flow. One of those PHIs must be in the 1726 // header of that control flow Cycle. This is independent of the choice of 1727 // Cycles reported by CycleInfo. It is sufficient to check the PHIs in 1728 // every Cycle header; if such a node is marked unknown, this will 1729 // eventually propagate through the whole net of PHIs in the recurrence. 1730 const auto *CI = 1731 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>( 1732 *PHI->getFunction()); 1733 if (mayBeInCycle(CI, cast<Instruction>(Usr), /* HeaderOnly */ true)) { 1734 auto BaseOI = It->getSecond(); 1735 BaseOI.addToAll(Offset.getZExtValue()); 1736 if (IsFirstPHIUser || BaseOI == UsrOI) { 1737 LLVM_DEBUG(dbgs() << "[AAPointerInfo] PHI is invariant " << *CurPtr 1738 << " in " << *Usr << "\n"); 1739 return HandlePassthroughUser(Usr, CurPtr, Follow); 1740 } 1741 1742 LLVM_DEBUG( 1743 dbgs() << "[AAPointerInfo] PHI operand pointer offset mismatch " 1744 << *CurPtr << " in " << *PHI << "\n"); 1745 UsrOI.setUnknown(); 1746 Follow = true; 1747 return true; 1748 } 1749 1750 UsrOI.merge(PtrOI); 1751 Follow = true; 1752 return true; 1753 } 1754 1755 if (auto *LoadI = dyn_cast<LoadInst>(Usr)) { 1756 // If the access is to a pointer that may or may not be the associated 1757 // value, e.g. due to a PHI, we cannot assume it will be read. 1758 AccessKind AK = AccessKind::AK_R; 1759 if (getUnderlyingObject(CurPtr) == &AssociatedValue) 1760 AK = AccessKind(AK | AccessKind::AK_MUST); 1761 else 1762 AK = AccessKind(AK | AccessKind::AK_MAY); 1763 if (!handleAccess(A, *LoadI, /* Content */ nullptr, AK, 1764 OffsetInfoMap[CurPtr].Offsets, Changed, 1765 *LoadI->getType())) 1766 return false; 1767 1768 auto IsAssumption = [](Instruction &I) { 1769 if (auto *II = dyn_cast<IntrinsicInst>(&I)) 1770 return II->isAssumeLikeIntrinsic(); 1771 return false; 1772 }; 1773 1774 auto IsImpactedInRange = [&](Instruction *FromI, Instruction *ToI) { 1775 // Check if the assumption and the load are executed together without 1776 // memory modification. 1777 do { 1778 if (FromI->mayWriteToMemory() && !IsAssumption(*FromI)) 1779 return true; 1780 FromI = FromI->getNextNonDebugInstruction(); 1781 } while (FromI && FromI != ToI); 1782 return false; 1783 }; 1784 1785 BasicBlock *BB = LoadI->getParent(); 1786 auto IsValidAssume = [&](IntrinsicInst &IntrI) { 1787 if (IntrI.getIntrinsicID() != Intrinsic::assume) 1788 return false; 1789 BasicBlock *IntrBB = IntrI.getParent(); 1790 if (IntrI.getParent() == BB) { 1791 if (IsImpactedInRange(LoadI->getNextNonDebugInstruction(), &IntrI)) 1792 return false; 1793 } else { 1794 auto PredIt = pred_begin(IntrBB); 1795 if (PredIt == pred_end(IntrBB)) 1796 return false; 1797 if ((*PredIt) != BB) 1798 return false; 1799 if (++PredIt != pred_end(IntrBB)) 1800 return false; 1801 for (auto *SuccBB : successors(BB)) { 1802 if (SuccBB == IntrBB) 1803 continue; 1804 if (isa<UnreachableInst>(SuccBB->getTerminator())) 1805 continue; 1806 return false; 1807 } 1808 if (IsImpactedInRange(LoadI->getNextNonDebugInstruction(), 1809 BB->getTerminator())) 1810 return false; 1811 if (IsImpactedInRange(&IntrBB->front(), &IntrI)) 1812 return false; 1813 } 1814 return true; 1815 }; 1816 1817 std::pair<Value *, IntrinsicInst *> Assumption; 1818 for (const Use &LoadU : LoadI->uses()) { 1819 if (auto *CmpI = dyn_cast<CmpInst>(LoadU.getUser())) { 1820 if (!CmpI->isEquality() || !CmpI->isTrueWhenEqual()) 1821 continue; 1822 for (const Use &CmpU : CmpI->uses()) { 1823 if (auto *IntrI = dyn_cast<IntrinsicInst>(CmpU.getUser())) { 1824 if (!IsValidAssume(*IntrI)) 1825 continue; 1826 int Idx = CmpI->getOperandUse(0) == LoadU; 1827 Assumption = {CmpI->getOperand(Idx), IntrI}; 1828 break; 1829 } 1830 } 1831 } 1832 if (Assumption.first) 1833 break; 1834 } 1835 1836 // Check if we found an assumption associated with this load. 1837 if (!Assumption.first || !Assumption.second) 1838 return true; 1839 1840 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Assumption found " 1841 << *Assumption.second << ": " << *LoadI 1842 << " == " << *Assumption.first << "\n"); 1843 bool UsedAssumedInformation = false; 1844 std::optional<Value *> Content = nullptr; 1845 if (Assumption.first) 1846 Content = 1847 A.getAssumedSimplified(*Assumption.first, *this, 1848 UsedAssumedInformation, AA::Interprocedural); 1849 return handleAccess( 1850 A, *Assumption.second, Content, AccessKind::AK_ASSUMPTION, 1851 OffsetInfoMap[CurPtr].Offsets, Changed, *LoadI->getType()); 1852 } 1853 1854 auto HandleStoreLike = [&](Instruction &I, Value *ValueOp, Type &ValueTy, 1855 ArrayRef<Value *> OtherOps, AccessKind AK) { 1856 for (auto *OtherOp : OtherOps) { 1857 if (OtherOp == CurPtr) { 1858 LLVM_DEBUG( 1859 dbgs() 1860 << "[AAPointerInfo] Escaping use in store like instruction " << I 1861 << "\n"); 1862 return false; 1863 } 1864 } 1865 1866 // If the access is to a pointer that may or may not be the associated 1867 // value, e.g. due to a PHI, we cannot assume it will be written. 1868 if (getUnderlyingObject(CurPtr) == &AssociatedValue) 1869 AK = AccessKind(AK | AccessKind::AK_MUST); 1870 else 1871 AK = AccessKind(AK | AccessKind::AK_MAY); 1872 bool UsedAssumedInformation = false; 1873 std::optional<Value *> Content = nullptr; 1874 if (ValueOp) 1875 Content = A.getAssumedSimplified( 1876 *ValueOp, *this, UsedAssumedInformation, AA::Interprocedural); 1877 return handleAccess(A, I, Content, AK, OffsetInfoMap[CurPtr].Offsets, 1878 Changed, ValueTy); 1879 }; 1880 1881 if (auto *StoreI = dyn_cast<StoreInst>(Usr)) 1882 return HandleStoreLike(*StoreI, StoreI->getValueOperand(), 1883 *StoreI->getValueOperand()->getType(), 1884 {StoreI->getValueOperand()}, AccessKind::AK_W); 1885 if (auto *RMWI = dyn_cast<AtomicRMWInst>(Usr)) 1886 return HandleStoreLike(*RMWI, nullptr, *RMWI->getValOperand()->getType(), 1887 {RMWI->getValOperand()}, AccessKind::AK_RW); 1888 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(Usr)) 1889 return HandleStoreLike( 1890 *CXI, nullptr, *CXI->getNewValOperand()->getType(), 1891 {CXI->getCompareOperand(), CXI->getNewValOperand()}, 1892 AccessKind::AK_RW); 1893 1894 if (auto *CB = dyn_cast<CallBase>(Usr)) { 1895 if (CB->isLifetimeStartOrEnd()) 1896 return true; 1897 const auto *TLI = 1898 A.getInfoCache().getTargetLibraryInfoForFunction(*CB->getFunction()); 1899 if (getFreedOperand(CB, TLI) == U) 1900 return true; 1901 if (CB->isArgOperand(&U)) { 1902 unsigned ArgNo = CB->getArgOperandNo(&U); 1903 const auto *CSArgPI = A.getAAFor<AAPointerInfo>( 1904 *this, IRPosition::callsite_argument(*CB, ArgNo), 1905 DepClassTy::REQUIRED); 1906 if (!CSArgPI) 1907 return false; 1908 bool IsArgMustAcc = (getUnderlyingObject(CurPtr) == &AssociatedValue); 1909 Changed = translateAndAddState(A, *CSArgPI, OffsetInfoMap[CurPtr], *CB, 1910 IsArgMustAcc) | 1911 Changed; 1912 if (!CSArgPI->reachesReturn()) 1913 return isValidState(); 1914 1915 Function *Callee = CB->getCalledFunction(); 1916 if (!Callee || Callee->arg_size() <= ArgNo) 1917 return false; 1918 bool UsedAssumedInformation = false; 1919 auto ReturnedValue = A.getAssumedSimplified( 1920 IRPosition::returned(*Callee), *this, UsedAssumedInformation, 1921 AA::ValueScope::Intraprocedural); 1922 auto *ReturnedArg = 1923 dyn_cast_or_null<Argument>(ReturnedValue.value_or(nullptr)); 1924 auto *Arg = Callee->getArg(ArgNo); 1925 if (ReturnedArg && Arg != ReturnedArg) 1926 return true; 1927 bool IsRetMustAcc = IsArgMustAcc && (ReturnedArg == Arg); 1928 const auto *CSRetPI = A.getAAFor<AAPointerInfo>( 1929 *this, IRPosition::callsite_returned(*CB), DepClassTy::REQUIRED); 1930 if (!CSRetPI) 1931 return false; 1932 OffsetInfo OI = OffsetInfoMap[CurPtr]; 1933 CSArgPI->addReturnedOffsetsTo(OI); 1934 Changed = 1935 translateAndAddState(A, *CSRetPI, OI, *CB, IsRetMustAcc) | Changed; 1936 return isValidState(); 1937 } 1938 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Call user not handled " << *CB 1939 << "\n"); 1940 return false; 1941 } 1942 1943 LLVM_DEBUG(dbgs() << "[AAPointerInfo] User not handled " << *Usr << "\n"); 1944 return false; 1945 }; 1946 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) { 1947 assert(OffsetInfoMap.count(OldU) && "Old use should be known already!"); 1948 assert(!OffsetInfoMap[OldU].isUnassigned() && "Old use should be assinged"); 1949 if (OffsetInfoMap.count(NewU)) { 1950 LLVM_DEBUG({ 1951 if (!(OffsetInfoMap[NewU] == OffsetInfoMap[OldU])) { 1952 dbgs() << "[AAPointerInfo] Equivalent use callback failed: " 1953 << OffsetInfoMap[NewU] << " vs " << OffsetInfoMap[OldU] 1954 << "\n"; 1955 } 1956 }); 1957 return OffsetInfoMap[NewU] == OffsetInfoMap[OldU]; 1958 } 1959 bool Unused; 1960 return HandlePassthroughUser(NewU.get(), OldU.get(), Unused); 1961 }; 1962 if (!A.checkForAllUses(UsePred, *this, AssociatedValue, 1963 /* CheckBBLivenessOnly */ true, DepClassTy::OPTIONAL, 1964 /* IgnoreDroppableUses */ true, EquivalentUseCB)) { 1965 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Check for all uses failed, abort!\n"); 1966 return indicatePessimisticFixpoint(); 1967 } 1968 1969 LLVM_DEBUG({ 1970 dbgs() << "Accesses by bin after update:\n"; 1971 dumpState(dbgs()); 1972 }); 1973 1974 return Changed; 1975 } 1976 1977 struct AAPointerInfoReturned final : AAPointerInfoImpl { 1978 AAPointerInfoReturned(const IRPosition &IRP, Attributor &A) 1979 : AAPointerInfoImpl(IRP, A) {} 1980 1981 /// See AbstractAttribute::updateImpl(...). 1982 ChangeStatus updateImpl(Attributor &A) override { 1983 return indicatePessimisticFixpoint(); 1984 } 1985 1986 /// See AbstractAttribute::trackStatistics() 1987 void trackStatistics() const override { 1988 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition()); 1989 } 1990 }; 1991 1992 struct AAPointerInfoArgument final : AAPointerInfoFloating { 1993 AAPointerInfoArgument(const IRPosition &IRP, Attributor &A) 1994 : AAPointerInfoFloating(IRP, A) {} 1995 1996 /// See AbstractAttribute::trackStatistics() 1997 void trackStatistics() const override { 1998 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition()); 1999 } 2000 }; 2001 2002 struct AAPointerInfoCallSiteArgument final : AAPointerInfoFloating { 2003 AAPointerInfoCallSiteArgument(const IRPosition &IRP, Attributor &A) 2004 : AAPointerInfoFloating(IRP, A) {} 2005 2006 /// See AbstractAttribute::updateImpl(...). 2007 ChangeStatus updateImpl(Attributor &A) override { 2008 using namespace AA::PointerInfo; 2009 // We handle memory intrinsics explicitly, at least the first (= 2010 // destination) and second (=source) arguments as we know how they are 2011 // accessed. 2012 if (auto *MI = dyn_cast_or_null<MemIntrinsic>(getCtxI())) { 2013 ConstantInt *Length = dyn_cast<ConstantInt>(MI->getLength()); 2014 int64_t LengthVal = AA::RangeTy::Unknown; 2015 if (Length) 2016 LengthVal = Length->getSExtValue(); 2017 unsigned ArgNo = getIRPosition().getCallSiteArgNo(); 2018 ChangeStatus Changed = ChangeStatus::UNCHANGED; 2019 if (ArgNo > 1) { 2020 LLVM_DEBUG(dbgs() << "[AAPointerInfo] Unhandled memory intrinsic " 2021 << *MI << "\n"); 2022 return indicatePessimisticFixpoint(); 2023 } else { 2024 auto Kind = 2025 ArgNo == 0 ? AccessKind::AK_MUST_WRITE : AccessKind::AK_MUST_READ; 2026 Changed = 2027 Changed | addAccess(A, {0, LengthVal}, *MI, nullptr, Kind, nullptr); 2028 } 2029 LLVM_DEBUG({ 2030 dbgs() << "Accesses by bin after update:\n"; 2031 dumpState(dbgs()); 2032 }); 2033 2034 return Changed; 2035 } 2036 2037 // TODO: Once we have call site specific value information we can provide 2038 // call site specific liveness information and then it makes 2039 // sense to specialize attributes for call sites arguments instead of 2040 // redirecting requests to the callee argument. 2041 Argument *Arg = getAssociatedArgument(); 2042 if (Arg) { 2043 const IRPosition &ArgPos = IRPosition::argument(*Arg); 2044 auto *ArgAA = 2045 A.getAAFor<AAPointerInfo>(*this, ArgPos, DepClassTy::REQUIRED); 2046 if (ArgAA && ArgAA->getState().isValidState()) 2047 return translateAndAddStateFromCallee(A, *ArgAA, 2048 *cast<CallBase>(getCtxI())); 2049 if (!Arg->getParent()->isDeclaration()) 2050 return indicatePessimisticFixpoint(); 2051 } 2052 2053 bool IsKnownNoCapture; 2054 if (!AA::hasAssumedIRAttr<Attribute::Captures>( 2055 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoCapture)) 2056 return indicatePessimisticFixpoint(); 2057 2058 bool IsKnown = false; 2059 if (AA::isAssumedReadNone(A, getIRPosition(), *this, IsKnown)) 2060 return ChangeStatus::UNCHANGED; 2061 bool ReadOnly = AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown); 2062 auto Kind = 2063 ReadOnly ? AccessKind::AK_MAY_READ : AccessKind::AK_MAY_READ_WRITE; 2064 return addAccess(A, AA::RangeTy::getUnknown(), *getCtxI(), nullptr, Kind, 2065 nullptr); 2066 } 2067 2068 /// See AbstractAttribute::trackStatistics() 2069 void trackStatistics() const override { 2070 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition()); 2071 } 2072 }; 2073 2074 struct AAPointerInfoCallSiteReturned final : AAPointerInfoFloating { 2075 AAPointerInfoCallSiteReturned(const IRPosition &IRP, Attributor &A) 2076 : AAPointerInfoFloating(IRP, A) {} 2077 2078 /// See AbstractAttribute::trackStatistics() 2079 void trackStatistics() const override { 2080 AAPointerInfoImpl::trackPointerInfoStatistics(getIRPosition()); 2081 } 2082 }; 2083 } // namespace 2084 2085 /// -----------------------NoUnwind Function Attribute-------------------------- 2086 2087 namespace { 2088 struct AANoUnwindImpl : AANoUnwind { 2089 AANoUnwindImpl(const IRPosition &IRP, Attributor &A) : AANoUnwind(IRP, A) {} 2090 2091 /// See AbstractAttribute::initialize(...). 2092 void initialize(Attributor &A) override { 2093 bool IsKnown; 2094 assert(!AA::hasAssumedIRAttr<Attribute::NoUnwind>( 2095 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown)); 2096 (void)IsKnown; 2097 } 2098 2099 const std::string getAsStr(Attributor *A) const override { 2100 return getAssumed() ? "nounwind" : "may-unwind"; 2101 } 2102 2103 /// See AbstractAttribute::updateImpl(...). 2104 ChangeStatus updateImpl(Attributor &A) override { 2105 auto Opcodes = { 2106 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr, 2107 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet, 2108 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume}; 2109 2110 auto CheckForNoUnwind = [&](Instruction &I) { 2111 if (!I.mayThrow(/* IncludePhaseOneUnwind */ true)) 2112 return true; 2113 2114 if (const auto *CB = dyn_cast<CallBase>(&I)) { 2115 bool IsKnownNoUnwind; 2116 return AA::hasAssumedIRAttr<Attribute::NoUnwind>( 2117 A, this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED, 2118 IsKnownNoUnwind); 2119 } 2120 return false; 2121 }; 2122 2123 bool UsedAssumedInformation = false; 2124 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes, 2125 UsedAssumedInformation)) 2126 return indicatePessimisticFixpoint(); 2127 2128 return ChangeStatus::UNCHANGED; 2129 } 2130 }; 2131 2132 struct AANoUnwindFunction final : public AANoUnwindImpl { 2133 AANoUnwindFunction(const IRPosition &IRP, Attributor &A) 2134 : AANoUnwindImpl(IRP, A) {} 2135 2136 /// See AbstractAttribute::trackStatistics() 2137 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) } 2138 }; 2139 2140 /// NoUnwind attribute deduction for a call sites. 2141 struct AANoUnwindCallSite final 2142 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl> { 2143 AANoUnwindCallSite(const IRPosition &IRP, Attributor &A) 2144 : AACalleeToCallSite<AANoUnwind, AANoUnwindImpl>(IRP, A) {} 2145 2146 /// See AbstractAttribute::trackStatistics() 2147 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); } 2148 }; 2149 } // namespace 2150 2151 /// ------------------------ NoSync Function Attribute ------------------------- 2152 2153 bool AANoSync::isAlignedBarrier(const CallBase &CB, bool ExecutedAligned) { 2154 switch (CB.getIntrinsicID()) { 2155 case Intrinsic::nvvm_barrier0: 2156 case Intrinsic::nvvm_barrier0_and: 2157 case Intrinsic::nvvm_barrier0_or: 2158 case Intrinsic::nvvm_barrier0_popc: 2159 return true; 2160 case Intrinsic::amdgcn_s_barrier: 2161 if (ExecutedAligned) 2162 return true; 2163 break; 2164 default: 2165 break; 2166 } 2167 return hasAssumption(CB, KnownAssumptionString("ompx_aligned_barrier")); 2168 } 2169 2170 bool AANoSync::isNonRelaxedAtomic(const Instruction *I) { 2171 if (!I->isAtomic()) 2172 return false; 2173 2174 if (auto *FI = dyn_cast<FenceInst>(I)) 2175 // All legal orderings for fence are stronger than monotonic. 2176 return FI->getSyncScopeID() != SyncScope::SingleThread; 2177 if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) { 2178 // Unordered is not a legal ordering for cmpxchg. 2179 return (AI->getSuccessOrdering() != AtomicOrdering::Monotonic || 2180 AI->getFailureOrdering() != AtomicOrdering::Monotonic); 2181 } 2182 2183 AtomicOrdering Ordering; 2184 switch (I->getOpcode()) { 2185 case Instruction::AtomicRMW: 2186 Ordering = cast<AtomicRMWInst>(I)->getOrdering(); 2187 break; 2188 case Instruction::Store: 2189 Ordering = cast<StoreInst>(I)->getOrdering(); 2190 break; 2191 case Instruction::Load: 2192 Ordering = cast<LoadInst>(I)->getOrdering(); 2193 break; 2194 default: 2195 llvm_unreachable( 2196 "New atomic operations need to be known in the attributor."); 2197 } 2198 2199 return (Ordering != AtomicOrdering::Unordered && 2200 Ordering != AtomicOrdering::Monotonic); 2201 } 2202 2203 /// Return true if this intrinsic is nosync. This is only used for intrinsics 2204 /// which would be nosync except that they have a volatile flag. All other 2205 /// intrinsics are simply annotated with the nosync attribute in Intrinsics.td. 2206 bool AANoSync::isNoSyncIntrinsic(const Instruction *I) { 2207 if (auto *MI = dyn_cast<MemIntrinsic>(I)) 2208 return !MI->isVolatile(); 2209 return false; 2210 } 2211 2212 namespace { 2213 struct AANoSyncImpl : AANoSync { 2214 AANoSyncImpl(const IRPosition &IRP, Attributor &A) : AANoSync(IRP, A) {} 2215 2216 /// See AbstractAttribute::initialize(...). 2217 void initialize(Attributor &A) override { 2218 bool IsKnown; 2219 assert(!AA::hasAssumedIRAttr<Attribute::NoSync>(A, nullptr, getIRPosition(), 2220 DepClassTy::NONE, IsKnown)); 2221 (void)IsKnown; 2222 } 2223 2224 const std::string getAsStr(Attributor *A) const override { 2225 return getAssumed() ? "nosync" : "may-sync"; 2226 } 2227 2228 /// See AbstractAttribute::updateImpl(...). 2229 ChangeStatus updateImpl(Attributor &A) override; 2230 }; 2231 2232 ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) { 2233 2234 auto CheckRWInstForNoSync = [&](Instruction &I) { 2235 return AA::isNoSyncInst(A, I, *this); 2236 }; 2237 2238 auto CheckForNoSync = [&](Instruction &I) { 2239 // At this point we handled all read/write effects and they are all 2240 // nosync, so they can be skipped. 2241 if (I.mayReadOrWriteMemory()) 2242 return true; 2243 2244 bool IsKnown; 2245 CallBase &CB = cast<CallBase>(I); 2246 if (AA::hasAssumedIRAttr<Attribute::NoSync>( 2247 A, this, IRPosition::callsite_function(CB), DepClassTy::OPTIONAL, 2248 IsKnown)) 2249 return true; 2250 2251 // non-convergent and readnone imply nosync. 2252 return !CB.isConvergent(); 2253 }; 2254 2255 bool UsedAssumedInformation = false; 2256 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this, 2257 UsedAssumedInformation) || 2258 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this, 2259 UsedAssumedInformation)) 2260 return indicatePessimisticFixpoint(); 2261 2262 return ChangeStatus::UNCHANGED; 2263 } 2264 2265 struct AANoSyncFunction final : public AANoSyncImpl { 2266 AANoSyncFunction(const IRPosition &IRP, Attributor &A) 2267 : AANoSyncImpl(IRP, A) {} 2268 2269 /// See AbstractAttribute::trackStatistics() 2270 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) } 2271 }; 2272 2273 /// NoSync attribute deduction for a call sites. 2274 struct AANoSyncCallSite final : AACalleeToCallSite<AANoSync, AANoSyncImpl> { 2275 AANoSyncCallSite(const IRPosition &IRP, Attributor &A) 2276 : AACalleeToCallSite<AANoSync, AANoSyncImpl>(IRP, A) {} 2277 2278 /// See AbstractAttribute::trackStatistics() 2279 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); } 2280 }; 2281 } // namespace 2282 2283 /// ------------------------ No-Free Attributes ---------------------------- 2284 2285 namespace { 2286 struct AANoFreeImpl : public AANoFree { 2287 AANoFreeImpl(const IRPosition &IRP, Attributor &A) : AANoFree(IRP, A) {} 2288 2289 /// See AbstractAttribute::initialize(...). 2290 void initialize(Attributor &A) override { 2291 bool IsKnown; 2292 assert(!AA::hasAssumedIRAttr<Attribute::NoFree>(A, nullptr, getIRPosition(), 2293 DepClassTy::NONE, IsKnown)); 2294 (void)IsKnown; 2295 } 2296 2297 /// See AbstractAttribute::updateImpl(...). 2298 ChangeStatus updateImpl(Attributor &A) override { 2299 auto CheckForNoFree = [&](Instruction &I) { 2300 bool IsKnown; 2301 return AA::hasAssumedIRAttr<Attribute::NoFree>( 2302 A, this, IRPosition::callsite_function(cast<CallBase>(I)), 2303 DepClassTy::REQUIRED, IsKnown); 2304 }; 2305 2306 bool UsedAssumedInformation = false; 2307 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this, 2308 UsedAssumedInformation)) 2309 return indicatePessimisticFixpoint(); 2310 return ChangeStatus::UNCHANGED; 2311 } 2312 2313 /// See AbstractAttribute::getAsStr(). 2314 const std::string getAsStr(Attributor *A) const override { 2315 return getAssumed() ? "nofree" : "may-free"; 2316 } 2317 }; 2318 2319 struct AANoFreeFunction final : public AANoFreeImpl { 2320 AANoFreeFunction(const IRPosition &IRP, Attributor &A) 2321 : AANoFreeImpl(IRP, A) {} 2322 2323 /// See AbstractAttribute::trackStatistics() 2324 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) } 2325 }; 2326 2327 /// NoFree attribute deduction for a call sites. 2328 struct AANoFreeCallSite final : AACalleeToCallSite<AANoFree, AANoFreeImpl> { 2329 AANoFreeCallSite(const IRPosition &IRP, Attributor &A) 2330 : AACalleeToCallSite<AANoFree, AANoFreeImpl>(IRP, A) {} 2331 2332 /// See AbstractAttribute::trackStatistics() 2333 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); } 2334 }; 2335 2336 /// NoFree attribute for floating values. 2337 struct AANoFreeFloating : AANoFreeImpl { 2338 AANoFreeFloating(const IRPosition &IRP, Attributor &A) 2339 : AANoFreeImpl(IRP, A) {} 2340 2341 /// See AbstractAttribute::trackStatistics() 2342 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)} 2343 2344 /// See Abstract Attribute::updateImpl(...). 2345 ChangeStatus updateImpl(Attributor &A) override { 2346 const IRPosition &IRP = getIRPosition(); 2347 2348 bool IsKnown; 2349 if (AA::hasAssumedIRAttr<Attribute::NoFree>(A, this, 2350 IRPosition::function_scope(IRP), 2351 DepClassTy::OPTIONAL, IsKnown)) 2352 return ChangeStatus::UNCHANGED; 2353 2354 Value &AssociatedValue = getIRPosition().getAssociatedValue(); 2355 auto Pred = [&](const Use &U, bool &Follow) -> bool { 2356 Instruction *UserI = cast<Instruction>(U.getUser()); 2357 if (auto *CB = dyn_cast<CallBase>(UserI)) { 2358 if (CB->isBundleOperand(&U)) 2359 return false; 2360 if (!CB->isArgOperand(&U)) 2361 return true; 2362 unsigned ArgNo = CB->getArgOperandNo(&U); 2363 2364 bool IsKnown; 2365 return AA::hasAssumedIRAttr<Attribute::NoFree>( 2366 A, this, IRPosition::callsite_argument(*CB, ArgNo), 2367 DepClassTy::REQUIRED, IsKnown); 2368 } 2369 2370 if (isa<GetElementPtrInst>(UserI) || isa<PHINode>(UserI) || 2371 isa<SelectInst>(UserI)) { 2372 Follow = true; 2373 return true; 2374 } 2375 if (isa<StoreInst>(UserI) || isa<LoadInst>(UserI)) 2376 return true; 2377 2378 if (isa<ReturnInst>(UserI) && getIRPosition().isArgumentPosition()) 2379 return true; 2380 2381 // Unknown user. 2382 return false; 2383 }; 2384 if (!A.checkForAllUses(Pred, *this, AssociatedValue)) 2385 return indicatePessimisticFixpoint(); 2386 2387 return ChangeStatus::UNCHANGED; 2388 } 2389 }; 2390 2391 /// NoFree attribute for a call site argument. 2392 struct AANoFreeArgument final : AANoFreeFloating { 2393 AANoFreeArgument(const IRPosition &IRP, Attributor &A) 2394 : AANoFreeFloating(IRP, A) {} 2395 2396 /// See AbstractAttribute::trackStatistics() 2397 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) } 2398 }; 2399 2400 /// NoFree attribute for call site arguments. 2401 struct AANoFreeCallSiteArgument final : AANoFreeFloating { 2402 AANoFreeCallSiteArgument(const IRPosition &IRP, Attributor &A) 2403 : AANoFreeFloating(IRP, A) {} 2404 2405 /// See AbstractAttribute::updateImpl(...). 2406 ChangeStatus updateImpl(Attributor &A) override { 2407 // TODO: Once we have call site specific value information we can provide 2408 // call site specific liveness information and then it makes 2409 // sense to specialize attributes for call sites arguments instead of 2410 // redirecting requests to the callee argument. 2411 Argument *Arg = getAssociatedArgument(); 2412 if (!Arg) 2413 return indicatePessimisticFixpoint(); 2414 const IRPosition &ArgPos = IRPosition::argument(*Arg); 2415 bool IsKnown; 2416 if (AA::hasAssumedIRAttr<Attribute::NoFree>(A, this, ArgPos, 2417 DepClassTy::REQUIRED, IsKnown)) 2418 return ChangeStatus::UNCHANGED; 2419 return indicatePessimisticFixpoint(); 2420 } 2421 2422 /// See AbstractAttribute::trackStatistics() 2423 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nofree)}; 2424 }; 2425 2426 /// NoFree attribute for function return value. 2427 struct AANoFreeReturned final : AANoFreeFloating { 2428 AANoFreeReturned(const IRPosition &IRP, Attributor &A) 2429 : AANoFreeFloating(IRP, A) { 2430 llvm_unreachable("NoFree is not applicable to function returns!"); 2431 } 2432 2433 /// See AbstractAttribute::initialize(...). 2434 void initialize(Attributor &A) override { 2435 llvm_unreachable("NoFree is not applicable to function returns!"); 2436 } 2437 2438 /// See AbstractAttribute::updateImpl(...). 2439 ChangeStatus updateImpl(Attributor &A) override { 2440 llvm_unreachable("NoFree is not applicable to function returns!"); 2441 } 2442 2443 /// See AbstractAttribute::trackStatistics() 2444 void trackStatistics() const override {} 2445 }; 2446 2447 /// NoFree attribute deduction for a call site return value. 2448 struct AANoFreeCallSiteReturned final : AANoFreeFloating { 2449 AANoFreeCallSiteReturned(const IRPosition &IRP, Attributor &A) 2450 : AANoFreeFloating(IRP, A) {} 2451 2452 ChangeStatus manifest(Attributor &A) override { 2453 return ChangeStatus::UNCHANGED; 2454 } 2455 /// See AbstractAttribute::trackStatistics() 2456 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) } 2457 }; 2458 } // namespace 2459 2460 /// ------------------------ NonNull Argument Attribute ------------------------ 2461 2462 bool AANonNull::isImpliedByIR(Attributor &A, const IRPosition &IRP, 2463 Attribute::AttrKind ImpliedAttributeKind, 2464 bool IgnoreSubsumingPositions) { 2465 SmallVector<Attribute::AttrKind, 2> AttrKinds; 2466 AttrKinds.push_back(Attribute::NonNull); 2467 if (!NullPointerIsDefined(IRP.getAnchorScope(), 2468 IRP.getAssociatedType()->getPointerAddressSpace())) 2469 AttrKinds.push_back(Attribute::Dereferenceable); 2470 if (A.hasAttr(IRP, AttrKinds, IgnoreSubsumingPositions, Attribute::NonNull)) 2471 return true; 2472 2473 DominatorTree *DT = nullptr; 2474 AssumptionCache *AC = nullptr; 2475 InformationCache &InfoCache = A.getInfoCache(); 2476 if (const Function *Fn = IRP.getAnchorScope()) { 2477 if (!Fn->isDeclaration()) { 2478 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*Fn); 2479 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*Fn); 2480 } 2481 } 2482 2483 SmallVector<AA::ValueAndContext> Worklist; 2484 if (IRP.getPositionKind() != IRP_RETURNED) { 2485 Worklist.push_back({IRP.getAssociatedValue(), IRP.getCtxI()}); 2486 } else { 2487 bool UsedAssumedInformation = false; 2488 if (!A.checkForAllInstructions( 2489 [&](Instruction &I) { 2490 Worklist.push_back({*cast<ReturnInst>(I).getReturnValue(), &I}); 2491 return true; 2492 }, 2493 IRP.getAssociatedFunction(), nullptr, {Instruction::Ret}, 2494 UsedAssumedInformation, false, /*CheckPotentiallyDead=*/true)) 2495 return false; 2496 } 2497 2498 if (llvm::any_of(Worklist, [&](AA::ValueAndContext VAC) { 2499 return !isKnownNonZero( 2500 VAC.getValue(), 2501 SimplifyQuery(A.getDataLayout(), DT, AC, VAC.getCtxI())); 2502 })) 2503 return false; 2504 2505 A.manifestAttrs(IRP, {Attribute::get(IRP.getAnchorValue().getContext(), 2506 Attribute::NonNull)}); 2507 return true; 2508 } 2509 2510 namespace { 2511 static int64_t getKnownNonNullAndDerefBytesForUse( 2512 Attributor &A, const AbstractAttribute &QueryingAA, Value &AssociatedValue, 2513 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) { 2514 TrackUse = false; 2515 2516 const Value *UseV = U->get(); 2517 if (!UseV->getType()->isPointerTy()) 2518 return 0; 2519 2520 // We need to follow common pointer manipulation uses to the accesses they 2521 // feed into. We can try to be smart to avoid looking through things we do not 2522 // like for now, e.g., non-inbounds GEPs. 2523 if (isa<CastInst>(I)) { 2524 TrackUse = true; 2525 return 0; 2526 } 2527 2528 if (isa<GetElementPtrInst>(I)) { 2529 TrackUse = true; 2530 return 0; 2531 } 2532 2533 Type *PtrTy = UseV->getType(); 2534 const Function *F = I->getFunction(); 2535 bool NullPointerIsDefined = 2536 F ? llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace()) : true; 2537 const DataLayout &DL = A.getInfoCache().getDL(); 2538 if (const auto *CB = dyn_cast<CallBase>(I)) { 2539 if (CB->isBundleOperand(U)) { 2540 if (RetainedKnowledge RK = getKnowledgeFromUse( 2541 U, {Attribute::NonNull, Attribute::Dereferenceable})) { 2542 IsNonNull |= 2543 (RK.AttrKind == Attribute::NonNull || !NullPointerIsDefined); 2544 return RK.ArgValue; 2545 } 2546 return 0; 2547 } 2548 2549 if (CB->isCallee(U)) { 2550 IsNonNull |= !NullPointerIsDefined; 2551 return 0; 2552 } 2553 2554 unsigned ArgNo = CB->getArgOperandNo(U); 2555 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo); 2556 // As long as we only use known information there is no need to track 2557 // dependences here. 2558 bool IsKnownNonNull; 2559 AA::hasAssumedIRAttr<Attribute::NonNull>(A, &QueryingAA, IRP, 2560 DepClassTy::NONE, IsKnownNonNull); 2561 IsNonNull |= IsKnownNonNull; 2562 auto *DerefAA = 2563 A.getAAFor<AADereferenceable>(QueryingAA, IRP, DepClassTy::NONE); 2564 return DerefAA ? DerefAA->getKnownDereferenceableBytes() : 0; 2565 } 2566 2567 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I); 2568 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || 2569 Loc->Size.isScalable() || I->isVolatile()) 2570 return 0; 2571 2572 int64_t Offset; 2573 const Value *Base = 2574 getMinimalBaseOfPointer(A, QueryingAA, Loc->Ptr, Offset, DL); 2575 if (Base && Base == &AssociatedValue) { 2576 int64_t DerefBytes = Loc->Size.getValue() + Offset; 2577 IsNonNull |= !NullPointerIsDefined; 2578 return std::max(int64_t(0), DerefBytes); 2579 } 2580 2581 /// Corner case when an offset is 0. 2582 Base = GetPointerBaseWithConstantOffset(Loc->Ptr, Offset, DL, 2583 /*AllowNonInbounds*/ true); 2584 if (Base && Base == &AssociatedValue && Offset == 0) { 2585 int64_t DerefBytes = Loc->Size.getValue(); 2586 IsNonNull |= !NullPointerIsDefined; 2587 return std::max(int64_t(0), DerefBytes); 2588 } 2589 2590 return 0; 2591 } 2592 2593 struct AANonNullImpl : AANonNull { 2594 AANonNullImpl(const IRPosition &IRP, Attributor &A) : AANonNull(IRP, A) {} 2595 2596 /// See AbstractAttribute::initialize(...). 2597 void initialize(Attributor &A) override { 2598 Value &V = *getAssociatedValue().stripPointerCasts(); 2599 if (isa<ConstantPointerNull>(V)) { 2600 indicatePessimisticFixpoint(); 2601 return; 2602 } 2603 2604 if (Instruction *CtxI = getCtxI()) 2605 followUsesInMBEC(*this, A, getState(), *CtxI); 2606 } 2607 2608 /// See followUsesInMBEC 2609 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I, 2610 AANonNull::StateType &State) { 2611 bool IsNonNull = false; 2612 bool TrackUse = false; 2613 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I, 2614 IsNonNull, TrackUse); 2615 State.setKnown(IsNonNull); 2616 return TrackUse; 2617 } 2618 2619 /// See AbstractAttribute::getAsStr(). 2620 const std::string getAsStr(Attributor *A) const override { 2621 return getAssumed() ? "nonnull" : "may-null"; 2622 } 2623 }; 2624 2625 /// NonNull attribute for a floating value. 2626 struct AANonNullFloating : public AANonNullImpl { 2627 AANonNullFloating(const IRPosition &IRP, Attributor &A) 2628 : AANonNullImpl(IRP, A) {} 2629 2630 /// See AbstractAttribute::updateImpl(...). 2631 ChangeStatus updateImpl(Attributor &A) override { 2632 auto CheckIRP = [&](const IRPosition &IRP) { 2633 bool IsKnownNonNull; 2634 return AA::hasAssumedIRAttr<Attribute::NonNull>( 2635 A, *this, IRP, DepClassTy::OPTIONAL, IsKnownNonNull); 2636 }; 2637 2638 bool Stripped; 2639 bool UsedAssumedInformation = false; 2640 Value *AssociatedValue = &getAssociatedValue(); 2641 SmallVector<AA::ValueAndContext> Values; 2642 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values, 2643 AA::AnyScope, UsedAssumedInformation)) 2644 Stripped = false; 2645 else 2646 Stripped = 2647 Values.size() != 1 || Values.front().getValue() != AssociatedValue; 2648 2649 if (!Stripped) { 2650 bool IsKnown; 2651 if (auto *PHI = dyn_cast<PHINode>(AssociatedValue)) 2652 if (llvm::all_of(PHI->incoming_values(), [&](Value *Op) { 2653 return AA::hasAssumedIRAttr<Attribute::NonNull>( 2654 A, this, IRPosition::value(*Op), DepClassTy::OPTIONAL, 2655 IsKnown); 2656 })) 2657 return ChangeStatus::UNCHANGED; 2658 if (auto *Select = dyn_cast<SelectInst>(AssociatedValue)) 2659 if (AA::hasAssumedIRAttr<Attribute::NonNull>( 2660 A, this, IRPosition::value(*Select->getFalseValue()), 2661 DepClassTy::OPTIONAL, IsKnown) && 2662 AA::hasAssumedIRAttr<Attribute::NonNull>( 2663 A, this, IRPosition::value(*Select->getTrueValue()), 2664 DepClassTy::OPTIONAL, IsKnown)) 2665 return ChangeStatus::UNCHANGED; 2666 2667 // If we haven't stripped anything we might still be able to use a 2668 // different AA, but only if the IRP changes. Effectively when we 2669 // interpret this not as a call site value but as a floating/argument 2670 // value. 2671 const IRPosition AVIRP = IRPosition::value(*AssociatedValue); 2672 if (AVIRP == getIRPosition() || !CheckIRP(AVIRP)) 2673 return indicatePessimisticFixpoint(); 2674 return ChangeStatus::UNCHANGED; 2675 } 2676 2677 for (const auto &VAC : Values) 2678 if (!CheckIRP(IRPosition::value(*VAC.getValue()))) 2679 return indicatePessimisticFixpoint(); 2680 2681 return ChangeStatus::UNCHANGED; 2682 } 2683 2684 /// See AbstractAttribute::trackStatistics() 2685 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) } 2686 }; 2687 2688 /// NonNull attribute for function return value. 2689 struct AANonNullReturned final 2690 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType, 2691 false, AANonNull::IRAttributeKind, false> { 2692 AANonNullReturned(const IRPosition &IRP, Attributor &A) 2693 : AAReturnedFromReturnedValues<AANonNull, AANonNull, AANonNull::StateType, 2694 false, Attribute::NonNull, false>(IRP, A) { 2695 } 2696 2697 /// See AbstractAttribute::getAsStr(). 2698 const std::string getAsStr(Attributor *A) const override { 2699 return getAssumed() ? "nonnull" : "may-null"; 2700 } 2701 2702 /// See AbstractAttribute::trackStatistics() 2703 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) } 2704 }; 2705 2706 /// NonNull attribute for function argument. 2707 struct AANonNullArgument final 2708 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl> { 2709 AANonNullArgument(const IRPosition &IRP, Attributor &A) 2710 : AAArgumentFromCallSiteArguments<AANonNull, AANonNullImpl>(IRP, A) {} 2711 2712 /// See AbstractAttribute::trackStatistics() 2713 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) } 2714 }; 2715 2716 struct AANonNullCallSiteArgument final : AANonNullFloating { 2717 AANonNullCallSiteArgument(const IRPosition &IRP, Attributor &A) 2718 : AANonNullFloating(IRP, A) {} 2719 2720 /// See AbstractAttribute::trackStatistics() 2721 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) } 2722 }; 2723 2724 /// NonNull attribute for a call site return position. 2725 struct AANonNullCallSiteReturned final 2726 : AACalleeToCallSite<AANonNull, AANonNullImpl> { 2727 AANonNullCallSiteReturned(const IRPosition &IRP, Attributor &A) 2728 : AACalleeToCallSite<AANonNull, AANonNullImpl>(IRP, A) {} 2729 2730 /// See AbstractAttribute::trackStatistics() 2731 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) } 2732 }; 2733 } // namespace 2734 2735 /// ------------------------ Must-Progress Attributes -------------------------- 2736 namespace { 2737 struct AAMustProgressImpl : public AAMustProgress { 2738 AAMustProgressImpl(const IRPosition &IRP, Attributor &A) 2739 : AAMustProgress(IRP, A) {} 2740 2741 /// See AbstractAttribute::initialize(...). 2742 void initialize(Attributor &A) override { 2743 bool IsKnown; 2744 assert(!AA::hasAssumedIRAttr<Attribute::MustProgress>( 2745 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown)); 2746 (void)IsKnown; 2747 } 2748 2749 /// See AbstractAttribute::getAsStr() 2750 const std::string getAsStr(Attributor *A) const override { 2751 return getAssumed() ? "mustprogress" : "may-not-progress"; 2752 } 2753 }; 2754 2755 struct AAMustProgressFunction final : AAMustProgressImpl { 2756 AAMustProgressFunction(const IRPosition &IRP, Attributor &A) 2757 : AAMustProgressImpl(IRP, A) {} 2758 2759 /// See AbstractAttribute::updateImpl(...). 2760 ChangeStatus updateImpl(Attributor &A) override { 2761 bool IsKnown; 2762 if (AA::hasAssumedIRAttr<Attribute::WillReturn>( 2763 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnown)) { 2764 if (IsKnown) 2765 return indicateOptimisticFixpoint(); 2766 return ChangeStatus::UNCHANGED; 2767 } 2768 2769 auto CheckForMustProgress = [&](AbstractCallSite ACS) { 2770 IRPosition IPos = IRPosition::callsite_function(*ACS.getInstruction()); 2771 bool IsKnownMustProgress; 2772 return AA::hasAssumedIRAttr<Attribute::MustProgress>( 2773 A, this, IPos, DepClassTy::REQUIRED, IsKnownMustProgress, 2774 /* IgnoreSubsumingPositions */ true); 2775 }; 2776 2777 bool AllCallSitesKnown = true; 2778 if (!A.checkForAllCallSites(CheckForMustProgress, *this, 2779 /* RequireAllCallSites */ true, 2780 AllCallSitesKnown)) 2781 return indicatePessimisticFixpoint(); 2782 2783 return ChangeStatus::UNCHANGED; 2784 } 2785 2786 /// See AbstractAttribute::trackStatistics() 2787 void trackStatistics() const override { 2788 STATS_DECLTRACK_FN_ATTR(mustprogress) 2789 } 2790 }; 2791 2792 /// MustProgress attribute deduction for a call sites. 2793 struct AAMustProgressCallSite final : AAMustProgressImpl { 2794 AAMustProgressCallSite(const IRPosition &IRP, Attributor &A) 2795 : AAMustProgressImpl(IRP, A) {} 2796 2797 /// See AbstractAttribute::updateImpl(...). 2798 ChangeStatus updateImpl(Attributor &A) override { 2799 // TODO: Once we have call site specific value information we can provide 2800 // call site specific liveness information and then it makes 2801 // sense to specialize attributes for call sites arguments instead of 2802 // redirecting requests to the callee argument. 2803 const IRPosition &FnPos = IRPosition::function(*getAnchorScope()); 2804 bool IsKnownMustProgress; 2805 if (!AA::hasAssumedIRAttr<Attribute::MustProgress>( 2806 A, this, FnPos, DepClassTy::REQUIRED, IsKnownMustProgress)) 2807 return indicatePessimisticFixpoint(); 2808 return ChangeStatus::UNCHANGED; 2809 } 2810 2811 /// See AbstractAttribute::trackStatistics() 2812 void trackStatistics() const override { 2813 STATS_DECLTRACK_CS_ATTR(mustprogress); 2814 } 2815 }; 2816 } // namespace 2817 2818 /// ------------------------ No-Recurse Attributes ---------------------------- 2819 2820 namespace { 2821 struct AANoRecurseImpl : public AANoRecurse { 2822 AANoRecurseImpl(const IRPosition &IRP, Attributor &A) : AANoRecurse(IRP, A) {} 2823 2824 /// See AbstractAttribute::initialize(...). 2825 void initialize(Attributor &A) override { 2826 bool IsKnown; 2827 assert(!AA::hasAssumedIRAttr<Attribute::NoRecurse>( 2828 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown)); 2829 (void)IsKnown; 2830 } 2831 2832 /// See AbstractAttribute::getAsStr() 2833 const std::string getAsStr(Attributor *A) const override { 2834 return getAssumed() ? "norecurse" : "may-recurse"; 2835 } 2836 }; 2837 2838 struct AANoRecurseFunction final : AANoRecurseImpl { 2839 AANoRecurseFunction(const IRPosition &IRP, Attributor &A) 2840 : AANoRecurseImpl(IRP, A) {} 2841 2842 /// See AbstractAttribute::updateImpl(...). 2843 ChangeStatus updateImpl(Attributor &A) override { 2844 2845 // If all live call sites are known to be no-recurse, we are as well. 2846 auto CallSitePred = [&](AbstractCallSite ACS) { 2847 bool IsKnownNoRecurse; 2848 if (!AA::hasAssumedIRAttr<Attribute::NoRecurse>( 2849 A, this, 2850 IRPosition::function(*ACS.getInstruction()->getFunction()), 2851 DepClassTy::NONE, IsKnownNoRecurse)) 2852 return false; 2853 return IsKnownNoRecurse; 2854 }; 2855 bool UsedAssumedInformation = false; 2856 if (A.checkForAllCallSites(CallSitePred, *this, true, 2857 UsedAssumedInformation)) { 2858 // If we know all call sites and all are known no-recurse, we are done. 2859 // If all known call sites, which might not be all that exist, are known 2860 // to be no-recurse, we are not done but we can continue to assume 2861 // no-recurse. If one of the call sites we have not visited will become 2862 // live, another update is triggered. 2863 if (!UsedAssumedInformation) 2864 indicateOptimisticFixpoint(); 2865 return ChangeStatus::UNCHANGED; 2866 } 2867 2868 const AAInterFnReachability *EdgeReachability = 2869 A.getAAFor<AAInterFnReachability>(*this, getIRPosition(), 2870 DepClassTy::REQUIRED); 2871 if (EdgeReachability && EdgeReachability->canReach(A, *getAnchorScope())) 2872 return indicatePessimisticFixpoint(); 2873 return ChangeStatus::UNCHANGED; 2874 } 2875 2876 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) } 2877 }; 2878 2879 /// NoRecurse attribute deduction for a call sites. 2880 struct AANoRecurseCallSite final 2881 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl> { 2882 AANoRecurseCallSite(const IRPosition &IRP, Attributor &A) 2883 : AACalleeToCallSite<AANoRecurse, AANoRecurseImpl>(IRP, A) {} 2884 2885 /// See AbstractAttribute::trackStatistics() 2886 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); } 2887 }; 2888 } // namespace 2889 2890 /// ------------------------ No-Convergent Attribute -------------------------- 2891 2892 namespace { 2893 struct AANonConvergentImpl : public AANonConvergent { 2894 AANonConvergentImpl(const IRPosition &IRP, Attributor &A) 2895 : AANonConvergent(IRP, A) {} 2896 2897 /// See AbstractAttribute::getAsStr() 2898 const std::string getAsStr(Attributor *A) const override { 2899 return getAssumed() ? "non-convergent" : "may-be-convergent"; 2900 } 2901 }; 2902 2903 struct AANonConvergentFunction final : AANonConvergentImpl { 2904 AANonConvergentFunction(const IRPosition &IRP, Attributor &A) 2905 : AANonConvergentImpl(IRP, A) {} 2906 2907 /// See AbstractAttribute::updateImpl(...). 2908 ChangeStatus updateImpl(Attributor &A) override { 2909 // If all function calls are known to not be convergent, we are not 2910 // convergent. 2911 auto CalleeIsNotConvergent = [&](Instruction &Inst) { 2912 CallBase &CB = cast<CallBase>(Inst); 2913 auto *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand()); 2914 if (!Callee || Callee->isIntrinsic()) { 2915 return false; 2916 } 2917 if (Callee->isDeclaration()) { 2918 return !Callee->hasFnAttribute(Attribute::Convergent); 2919 } 2920 const auto *ConvergentAA = A.getAAFor<AANonConvergent>( 2921 *this, IRPosition::function(*Callee), DepClassTy::REQUIRED); 2922 return ConvergentAA && ConvergentAA->isAssumedNotConvergent(); 2923 }; 2924 2925 bool UsedAssumedInformation = false; 2926 if (!A.checkForAllCallLikeInstructions(CalleeIsNotConvergent, *this, 2927 UsedAssumedInformation)) { 2928 return indicatePessimisticFixpoint(); 2929 } 2930 return ChangeStatus::UNCHANGED; 2931 } 2932 2933 ChangeStatus manifest(Attributor &A) override { 2934 if (isKnownNotConvergent() && 2935 A.hasAttr(getIRPosition(), Attribute::Convergent)) { 2936 A.removeAttrs(getIRPosition(), {Attribute::Convergent}); 2937 return ChangeStatus::CHANGED; 2938 } 2939 return ChangeStatus::UNCHANGED; 2940 } 2941 2942 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(convergent) } 2943 }; 2944 } // namespace 2945 2946 /// -------------------- Undefined-Behavior Attributes ------------------------ 2947 2948 namespace { 2949 struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior { 2950 AAUndefinedBehaviorImpl(const IRPosition &IRP, Attributor &A) 2951 : AAUndefinedBehavior(IRP, A) {} 2952 2953 /// See AbstractAttribute::updateImpl(...). 2954 // through a pointer (i.e. also branches etc.) 2955 ChangeStatus updateImpl(Attributor &A) override { 2956 const size_t UBPrevSize = KnownUBInsts.size(); 2957 const size_t NoUBPrevSize = AssumedNoUBInsts.size(); 2958 2959 auto InspectMemAccessInstForUB = [&](Instruction &I) { 2960 // Lang ref now states volatile store is not UB, let's skip them. 2961 if (I.isVolatile() && I.mayWriteToMemory()) 2962 return true; 2963 2964 // Skip instructions that are already saved. 2965 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I)) 2966 return true; 2967 2968 // If we reach here, we know we have an instruction 2969 // that accesses memory through a pointer operand, 2970 // for which getPointerOperand() should give it to us. 2971 Value *PtrOp = 2972 const_cast<Value *>(getPointerOperand(&I, /* AllowVolatile */ true)); 2973 assert(PtrOp && 2974 "Expected pointer operand of memory accessing instruction"); 2975 2976 // Either we stopped and the appropriate action was taken, 2977 // or we got back a simplified value to continue. 2978 std::optional<Value *> SimplifiedPtrOp = 2979 stopOnUndefOrAssumed(A, PtrOp, &I); 2980 if (!SimplifiedPtrOp || !*SimplifiedPtrOp) 2981 return true; 2982 const Value *PtrOpVal = *SimplifiedPtrOp; 2983 2984 // A memory access through a pointer is considered UB 2985 // only if the pointer has constant null value. 2986 // TODO: Expand it to not only check constant values. 2987 if (!isa<ConstantPointerNull>(PtrOpVal)) { 2988 AssumedNoUBInsts.insert(&I); 2989 return true; 2990 } 2991 const Type *PtrTy = PtrOpVal->getType(); 2992 2993 // Because we only consider instructions inside functions, 2994 // assume that a parent function exists. 2995 const Function *F = I.getFunction(); 2996 2997 // A memory access using constant null pointer is only considered UB 2998 // if null pointer is _not_ defined for the target platform. 2999 if (llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace())) 3000 AssumedNoUBInsts.insert(&I); 3001 else 3002 KnownUBInsts.insert(&I); 3003 return true; 3004 }; 3005 3006 auto InspectBrInstForUB = [&](Instruction &I) { 3007 // A conditional branch instruction is considered UB if it has `undef` 3008 // condition. 3009 3010 // Skip instructions that are already saved. 3011 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I)) 3012 return true; 3013 3014 // We know we have a branch instruction. 3015 auto *BrInst = cast<BranchInst>(&I); 3016 3017 // Unconditional branches are never considered UB. 3018 if (BrInst->isUnconditional()) 3019 return true; 3020 3021 // Either we stopped and the appropriate action was taken, 3022 // or we got back a simplified value to continue. 3023 std::optional<Value *> SimplifiedCond = 3024 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst); 3025 if (!SimplifiedCond || !*SimplifiedCond) 3026 return true; 3027 AssumedNoUBInsts.insert(&I); 3028 return true; 3029 }; 3030 3031 auto InspectCallSiteForUB = [&](Instruction &I) { 3032 // Check whether a callsite always cause UB or not 3033 3034 // Skip instructions that are already saved. 3035 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I)) 3036 return true; 3037 3038 // Check nonnull and noundef argument attribute violation for each 3039 // callsite. 3040 CallBase &CB = cast<CallBase>(I); 3041 auto *Callee = dyn_cast_if_present<Function>(CB.getCalledOperand()); 3042 if (!Callee) 3043 return true; 3044 for (unsigned idx = 0; idx < CB.arg_size(); idx++) { 3045 // If current argument is known to be simplified to null pointer and the 3046 // corresponding argument position is known to have nonnull attribute, 3047 // the argument is poison. Furthermore, if the argument is poison and 3048 // the position is known to have noundef attriubte, this callsite is 3049 // considered UB. 3050 if (idx >= Callee->arg_size()) 3051 break; 3052 Value *ArgVal = CB.getArgOperand(idx); 3053 if (!ArgVal) 3054 continue; 3055 // Here, we handle three cases. 3056 // (1) Not having a value means it is dead. (we can replace the value 3057 // with undef) 3058 // (2) Simplified to undef. The argument violate noundef attriubte. 3059 // (3) Simplified to null pointer where known to be nonnull. 3060 // The argument is a poison value and violate noundef attribute. 3061 IRPosition CalleeArgumentIRP = IRPosition::callsite_argument(CB, idx); 3062 bool IsKnownNoUndef; 3063 AA::hasAssumedIRAttr<Attribute::NoUndef>( 3064 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNoUndef); 3065 if (!IsKnownNoUndef) 3066 continue; 3067 bool UsedAssumedInformation = false; 3068 std::optional<Value *> SimplifiedVal = 3069 A.getAssumedSimplified(IRPosition::value(*ArgVal), *this, 3070 UsedAssumedInformation, AA::Interprocedural); 3071 if (UsedAssumedInformation) 3072 continue; 3073 if (SimplifiedVal && !*SimplifiedVal) 3074 return true; 3075 if (!SimplifiedVal || isa<UndefValue>(**SimplifiedVal)) { 3076 KnownUBInsts.insert(&I); 3077 continue; 3078 } 3079 if (!ArgVal->getType()->isPointerTy() || 3080 !isa<ConstantPointerNull>(**SimplifiedVal)) 3081 continue; 3082 bool IsKnownNonNull; 3083 AA::hasAssumedIRAttr<Attribute::NonNull>( 3084 A, this, CalleeArgumentIRP, DepClassTy::NONE, IsKnownNonNull); 3085 if (IsKnownNonNull) 3086 KnownUBInsts.insert(&I); 3087 } 3088 return true; 3089 }; 3090 3091 auto InspectReturnInstForUB = [&](Instruction &I) { 3092 auto &RI = cast<ReturnInst>(I); 3093 // Either we stopped and the appropriate action was taken, 3094 // or we got back a simplified return value to continue. 3095 std::optional<Value *> SimplifiedRetValue = 3096 stopOnUndefOrAssumed(A, RI.getReturnValue(), &I); 3097 if (!SimplifiedRetValue || !*SimplifiedRetValue) 3098 return true; 3099 3100 // Check if a return instruction always cause UB or not 3101 // Note: It is guaranteed that the returned position of the anchor 3102 // scope has noundef attribute when this is called. 3103 // We also ensure the return position is not "assumed dead" 3104 // because the returned value was then potentially simplified to 3105 // `undef` in AAReturnedValues without removing the `noundef` 3106 // attribute yet. 3107 3108 // When the returned position has noundef attriubte, UB occurs in the 3109 // following cases. 3110 // (1) Returned value is known to be undef. 3111 // (2) The value is known to be a null pointer and the returned 3112 // position has nonnull attribute (because the returned value is 3113 // poison). 3114 if (isa<ConstantPointerNull>(*SimplifiedRetValue)) { 3115 bool IsKnownNonNull; 3116 AA::hasAssumedIRAttr<Attribute::NonNull>( 3117 A, this, IRPosition::returned(*getAnchorScope()), DepClassTy::NONE, 3118 IsKnownNonNull); 3119 if (IsKnownNonNull) 3120 KnownUBInsts.insert(&I); 3121 } 3122 3123 return true; 3124 }; 3125 3126 bool UsedAssumedInformation = false; 3127 A.checkForAllInstructions(InspectMemAccessInstForUB, *this, 3128 {Instruction::Load, Instruction::Store, 3129 Instruction::AtomicCmpXchg, 3130 Instruction::AtomicRMW}, 3131 UsedAssumedInformation, 3132 /* CheckBBLivenessOnly */ true); 3133 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::Br}, 3134 UsedAssumedInformation, 3135 /* CheckBBLivenessOnly */ true); 3136 A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this, 3137 UsedAssumedInformation); 3138 3139 // If the returned position of the anchor scope has noundef attriubte, check 3140 // all returned instructions. 3141 if (!getAnchorScope()->getReturnType()->isVoidTy()) { 3142 const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope()); 3143 if (!A.isAssumedDead(ReturnIRP, this, nullptr, UsedAssumedInformation)) { 3144 bool IsKnownNoUndef; 3145 AA::hasAssumedIRAttr<Attribute::NoUndef>( 3146 A, this, ReturnIRP, DepClassTy::NONE, IsKnownNoUndef); 3147 if (IsKnownNoUndef) 3148 A.checkForAllInstructions(InspectReturnInstForUB, *this, 3149 {Instruction::Ret}, UsedAssumedInformation, 3150 /* CheckBBLivenessOnly */ true); 3151 } 3152 } 3153 3154 if (NoUBPrevSize != AssumedNoUBInsts.size() || 3155 UBPrevSize != KnownUBInsts.size()) 3156 return ChangeStatus::CHANGED; 3157 return ChangeStatus::UNCHANGED; 3158 } 3159 3160 bool isKnownToCauseUB(Instruction *I) const override { 3161 return KnownUBInsts.count(I); 3162 } 3163 3164 bool isAssumedToCauseUB(Instruction *I) const override { 3165 // In simple words, if an instruction is not in the assumed to _not_ 3166 // cause UB, then it is assumed UB (that includes those 3167 // in the KnownUBInsts set). The rest is boilerplate 3168 // is to ensure that it is one of the instructions we test 3169 // for UB. 3170 3171 switch (I->getOpcode()) { 3172 case Instruction::Load: 3173 case Instruction::Store: 3174 case Instruction::AtomicCmpXchg: 3175 case Instruction::AtomicRMW: 3176 return !AssumedNoUBInsts.count(I); 3177 case Instruction::Br: { 3178 auto *BrInst = cast<BranchInst>(I); 3179 if (BrInst->isUnconditional()) 3180 return false; 3181 return !AssumedNoUBInsts.count(I); 3182 } break; 3183 default: 3184 return false; 3185 } 3186 return false; 3187 } 3188 3189 ChangeStatus manifest(Attributor &A) override { 3190 if (KnownUBInsts.empty()) 3191 return ChangeStatus::UNCHANGED; 3192 for (Instruction *I : KnownUBInsts) 3193 A.changeToUnreachableAfterManifest(I); 3194 return ChangeStatus::CHANGED; 3195 } 3196 3197 /// See AbstractAttribute::getAsStr() 3198 const std::string getAsStr(Attributor *A) const override { 3199 return getAssumed() ? "undefined-behavior" : "no-ub"; 3200 } 3201 3202 /// Note: The correctness of this analysis depends on the fact that the 3203 /// following 2 sets will stop changing after some point. 3204 /// "Change" here means that their size changes. 3205 /// The size of each set is monotonically increasing 3206 /// (we only add items to them) and it is upper bounded by the number of 3207 /// instructions in the processed function (we can never save more 3208 /// elements in either set than this number). Hence, at some point, 3209 /// they will stop increasing. 3210 /// Consequently, at some point, both sets will have stopped 3211 /// changing, effectively making the analysis reach a fixpoint. 3212 3213 /// Note: These 2 sets are disjoint and an instruction can be considered 3214 /// one of 3 things: 3215 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in 3216 /// the KnownUBInsts set. 3217 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior 3218 /// has a reason to assume it). 3219 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior 3220 /// could not find a reason to assume or prove that it can cause UB, 3221 /// hence it assumes it doesn't. We have a set for these instructions 3222 /// so that we don't reprocess them in every update. 3223 /// Note however that instructions in this set may cause UB. 3224 3225 protected: 3226 /// A set of all live instructions _known_ to cause UB. 3227 SmallPtrSet<Instruction *, 8> KnownUBInsts; 3228 3229 private: 3230 /// A set of all the (live) instructions that are assumed to _not_ cause UB. 3231 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts; 3232 3233 // Should be called on updates in which if we're processing an instruction 3234 // \p I that depends on a value \p V, one of the following has to happen: 3235 // - If the value is assumed, then stop. 3236 // - If the value is known but undef, then consider it UB. 3237 // - Otherwise, do specific processing with the simplified value. 3238 // We return std::nullopt in the first 2 cases to signify that an appropriate 3239 // action was taken and the caller should stop. 3240 // Otherwise, we return the simplified value that the caller should 3241 // use for specific processing. 3242 std::optional<Value *> stopOnUndefOrAssumed(Attributor &A, Value *V, 3243 Instruction *I) { 3244 bool UsedAssumedInformation = false; 3245 std::optional<Value *> SimplifiedV = 3246 A.getAssumedSimplified(IRPosition::value(*V), *this, 3247 UsedAssumedInformation, AA::Interprocedural); 3248 if (!UsedAssumedInformation) { 3249 // Don't depend on assumed values. 3250 if (!SimplifiedV) { 3251 // If it is known (which we tested above) but it doesn't have a value, 3252 // then we can assume `undef` and hence the instruction is UB. 3253 KnownUBInsts.insert(I); 3254 return std::nullopt; 3255 } 3256 if (!*SimplifiedV) 3257 return nullptr; 3258 V = *SimplifiedV; 3259 } 3260 if (isa<UndefValue>(V)) { 3261 KnownUBInsts.insert(I); 3262 return std::nullopt; 3263 } 3264 return V; 3265 } 3266 }; 3267 3268 struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl { 3269 AAUndefinedBehaviorFunction(const IRPosition &IRP, Attributor &A) 3270 : AAUndefinedBehaviorImpl(IRP, A) {} 3271 3272 /// See AbstractAttribute::trackStatistics() 3273 void trackStatistics() const override { 3274 STATS_DECL(UndefinedBehaviorInstruction, Instruction, 3275 "Number of instructions known to have UB"); 3276 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) += 3277 KnownUBInsts.size(); 3278 } 3279 }; 3280 } // namespace 3281 3282 /// ------------------------ Will-Return Attributes ---------------------------- 3283 3284 namespace { 3285 // Helper function that checks whether a function has any cycle which we don't 3286 // know if it is bounded or not. 3287 // Loops with maximum trip count are considered bounded, any other cycle not. 3288 static bool mayContainUnboundedCycle(Function &F, Attributor &A) { 3289 ScalarEvolution *SE = 3290 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(F); 3291 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(F); 3292 // If either SCEV or LoopInfo is not available for the function then we assume 3293 // any cycle to be unbounded cycle. 3294 // We use scc_iterator which uses Tarjan algorithm to find all the maximal 3295 // SCCs.To detect if there's a cycle, we only need to find the maximal ones. 3296 if (!SE || !LI) { 3297 for (scc_iterator<Function *> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI) 3298 if (SCCI.hasCycle()) 3299 return true; 3300 return false; 3301 } 3302 3303 // If there's irreducible control, the function may contain non-loop cycles. 3304 if (mayContainIrreducibleControl(F, LI)) 3305 return true; 3306 3307 // Any loop that does not have a max trip count is considered unbounded cycle. 3308 for (auto *L : LI->getLoopsInPreorder()) { 3309 if (!SE->getSmallConstantMaxTripCount(L)) 3310 return true; 3311 } 3312 return false; 3313 } 3314 3315 struct AAWillReturnImpl : public AAWillReturn { 3316 AAWillReturnImpl(const IRPosition &IRP, Attributor &A) 3317 : AAWillReturn(IRP, A) {} 3318 3319 /// See AbstractAttribute::initialize(...). 3320 void initialize(Attributor &A) override { 3321 bool IsKnown; 3322 assert(!AA::hasAssumedIRAttr<Attribute::WillReturn>( 3323 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown)); 3324 (void)IsKnown; 3325 } 3326 3327 /// Check for `mustprogress` and `readonly` as they imply `willreturn`. 3328 bool isImpliedByMustprogressAndReadonly(Attributor &A, bool KnownOnly) { 3329 if (!A.hasAttr(getIRPosition(), {Attribute::MustProgress})) 3330 return false; 3331 3332 bool IsKnown; 3333 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown)) 3334 return IsKnown || !KnownOnly; 3335 return false; 3336 } 3337 3338 /// See AbstractAttribute::updateImpl(...). 3339 ChangeStatus updateImpl(Attributor &A) override { 3340 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false)) 3341 return ChangeStatus::UNCHANGED; 3342 3343 auto CheckForWillReturn = [&](Instruction &I) { 3344 IRPosition IPos = IRPosition::callsite_function(cast<CallBase>(I)); 3345 bool IsKnown; 3346 if (AA::hasAssumedIRAttr<Attribute::WillReturn>( 3347 A, this, IPos, DepClassTy::REQUIRED, IsKnown)) { 3348 if (IsKnown) 3349 return true; 3350 } else { 3351 return false; 3352 } 3353 bool IsKnownNoRecurse; 3354 return AA::hasAssumedIRAttr<Attribute::NoRecurse>( 3355 A, this, IPos, DepClassTy::REQUIRED, IsKnownNoRecurse); 3356 }; 3357 3358 bool UsedAssumedInformation = false; 3359 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this, 3360 UsedAssumedInformation)) 3361 return indicatePessimisticFixpoint(); 3362 3363 return ChangeStatus::UNCHANGED; 3364 } 3365 3366 /// See AbstractAttribute::getAsStr() 3367 const std::string getAsStr(Attributor *A) const override { 3368 return getAssumed() ? "willreturn" : "may-noreturn"; 3369 } 3370 }; 3371 3372 struct AAWillReturnFunction final : AAWillReturnImpl { 3373 AAWillReturnFunction(const IRPosition &IRP, Attributor &A) 3374 : AAWillReturnImpl(IRP, A) {} 3375 3376 /// See AbstractAttribute::initialize(...). 3377 void initialize(Attributor &A) override { 3378 AAWillReturnImpl::initialize(A); 3379 3380 Function *F = getAnchorScope(); 3381 assert(F && "Did expect an anchor function"); 3382 if (F->isDeclaration() || mayContainUnboundedCycle(*F, A)) 3383 indicatePessimisticFixpoint(); 3384 } 3385 3386 /// See AbstractAttribute::trackStatistics() 3387 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) } 3388 }; 3389 3390 /// WillReturn attribute deduction for a call sites. 3391 struct AAWillReturnCallSite final 3392 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl> { 3393 AAWillReturnCallSite(const IRPosition &IRP, Attributor &A) 3394 : AACalleeToCallSite<AAWillReturn, AAWillReturnImpl>(IRP, A) {} 3395 3396 /// See AbstractAttribute::updateImpl(...). 3397 ChangeStatus updateImpl(Attributor &A) override { 3398 if (isImpliedByMustprogressAndReadonly(A, /* KnownOnly */ false)) 3399 return ChangeStatus::UNCHANGED; 3400 3401 return AACalleeToCallSite::updateImpl(A); 3402 } 3403 3404 /// See AbstractAttribute::trackStatistics() 3405 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); } 3406 }; 3407 } // namespace 3408 3409 /// -------------------AAIntraFnReachability Attribute-------------------------- 3410 3411 /// All information associated with a reachability query. This boilerplate code 3412 /// is used by both AAIntraFnReachability and AAInterFnReachability, with 3413 /// different \p ToTy values. 3414 template <typename ToTy> struct ReachabilityQueryInfo { 3415 enum class Reachable { 3416 No, 3417 Yes, 3418 }; 3419 3420 /// Start here, 3421 const Instruction *From = nullptr; 3422 /// reach this place, 3423 const ToTy *To = nullptr; 3424 /// without going through any of these instructions, 3425 const AA::InstExclusionSetTy *ExclusionSet = nullptr; 3426 /// and remember if it worked: 3427 Reachable Result = Reachable::No; 3428 3429 /// Precomputed hash for this RQI. 3430 unsigned Hash = 0; 3431 3432 unsigned computeHashValue() const { 3433 assert(Hash == 0 && "Computed hash twice!"); 3434 using InstSetDMI = DenseMapInfo<const AA::InstExclusionSetTy *>; 3435 using PairDMI = DenseMapInfo<std::pair<const Instruction *, const ToTy *>>; 3436 return const_cast<ReachabilityQueryInfo<ToTy> *>(this)->Hash = 3437 detail::combineHashValue(PairDMI ::getHashValue({From, To}), 3438 InstSetDMI::getHashValue(ExclusionSet)); 3439 } 3440 3441 ReachabilityQueryInfo(const Instruction *From, const ToTy *To) 3442 : From(From), To(To) {} 3443 3444 /// Constructor replacement to ensure unique and stable sets are used for the 3445 /// cache. 3446 ReachabilityQueryInfo(Attributor &A, const Instruction &From, const ToTy &To, 3447 const AA::InstExclusionSetTy *ES, bool MakeUnique) 3448 : From(&From), To(&To), ExclusionSet(ES) { 3449 3450 if (!ES || ES->empty()) { 3451 ExclusionSet = nullptr; 3452 } else if (MakeUnique) { 3453 ExclusionSet = A.getInfoCache().getOrCreateUniqueBlockExecutionSet(ES); 3454 } 3455 } 3456 3457 ReachabilityQueryInfo(const ReachabilityQueryInfo &RQI) 3458 : From(RQI.From), To(RQI.To), ExclusionSet(RQI.ExclusionSet) {} 3459 }; 3460 3461 namespace llvm { 3462 template <typename ToTy> struct DenseMapInfo<ReachabilityQueryInfo<ToTy> *> { 3463 using InstSetDMI = DenseMapInfo<const AA::InstExclusionSetTy *>; 3464 using PairDMI = DenseMapInfo<std::pair<const Instruction *, const ToTy *>>; 3465 3466 static ReachabilityQueryInfo<ToTy> EmptyKey; 3467 static ReachabilityQueryInfo<ToTy> TombstoneKey; 3468 3469 static inline ReachabilityQueryInfo<ToTy> *getEmptyKey() { return &EmptyKey; } 3470 static inline ReachabilityQueryInfo<ToTy> *getTombstoneKey() { 3471 return &TombstoneKey; 3472 } 3473 static unsigned getHashValue(const ReachabilityQueryInfo<ToTy> *RQI) { 3474 return RQI->Hash ? RQI->Hash : RQI->computeHashValue(); 3475 } 3476 static bool isEqual(const ReachabilityQueryInfo<ToTy> *LHS, 3477 const ReachabilityQueryInfo<ToTy> *RHS) { 3478 if (!PairDMI::isEqual({LHS->From, LHS->To}, {RHS->From, RHS->To})) 3479 return false; 3480 return InstSetDMI::isEqual(LHS->ExclusionSet, RHS->ExclusionSet); 3481 } 3482 }; 3483 3484 #define DefineKeys(ToTy) \ 3485 template <> \ 3486 ReachabilityQueryInfo<ToTy> \ 3487 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::EmptyKey = \ 3488 ReachabilityQueryInfo<ToTy>( \ 3489 DenseMapInfo<const Instruction *>::getEmptyKey(), \ 3490 DenseMapInfo<const ToTy *>::getEmptyKey()); \ 3491 template <> \ 3492 ReachabilityQueryInfo<ToTy> \ 3493 DenseMapInfo<ReachabilityQueryInfo<ToTy> *>::TombstoneKey = \ 3494 ReachabilityQueryInfo<ToTy>( \ 3495 DenseMapInfo<const Instruction *>::getTombstoneKey(), \ 3496 DenseMapInfo<const ToTy *>::getTombstoneKey()); 3497 3498 DefineKeys(Instruction) DefineKeys(Function) 3499 #undef DefineKeys 3500 3501 } // namespace llvm 3502 3503 namespace { 3504 3505 template <typename BaseTy, typename ToTy> 3506 struct CachedReachabilityAA : public BaseTy { 3507 using RQITy = ReachabilityQueryInfo<ToTy>; 3508 3509 CachedReachabilityAA(const IRPosition &IRP, Attributor &A) : BaseTy(IRP, A) {} 3510 3511 /// See AbstractAttribute::isQueryAA. 3512 bool isQueryAA() const override { return true; } 3513 3514 /// See AbstractAttribute::updateImpl(...). 3515 ChangeStatus updateImpl(Attributor &A) override { 3516 ChangeStatus Changed = ChangeStatus::UNCHANGED; 3517 for (unsigned u = 0, e = QueryVector.size(); u < e; ++u) { 3518 RQITy *RQI = QueryVector[u]; 3519 if (RQI->Result == RQITy::Reachable::No && 3520 isReachableImpl(A, *RQI, /*IsTemporaryRQI=*/false)) 3521 Changed = ChangeStatus::CHANGED; 3522 } 3523 return Changed; 3524 } 3525 3526 virtual bool isReachableImpl(Attributor &A, RQITy &RQI, 3527 bool IsTemporaryRQI) = 0; 3528 3529 bool rememberResult(Attributor &A, typename RQITy::Reachable Result, 3530 RQITy &RQI, bool UsedExclusionSet, bool IsTemporaryRQI) { 3531 RQI.Result = Result; 3532 3533 // Remove the temporary RQI from the cache. 3534 if (IsTemporaryRQI) 3535 QueryCache.erase(&RQI); 3536 3537 // Insert a plain RQI (w/o exclusion set) if that makes sense. Two options: 3538 // 1) If it is reachable, it doesn't matter if we have an exclusion set for 3539 // this query. 2) We did not use the exclusion set, potentially because 3540 // there is none. 3541 if (Result == RQITy::Reachable::Yes || !UsedExclusionSet) { 3542 RQITy PlainRQI(RQI.From, RQI.To); 3543 if (!QueryCache.count(&PlainRQI)) { 3544 RQITy *RQIPtr = new (A.Allocator) RQITy(RQI.From, RQI.To); 3545 RQIPtr->Result = Result; 3546 QueryVector.push_back(RQIPtr); 3547 QueryCache.insert(RQIPtr); 3548 } 3549 } 3550 3551 // Check if we need to insert a new permanent RQI with the exclusion set. 3552 if (IsTemporaryRQI && Result != RQITy::Reachable::Yes && UsedExclusionSet) { 3553 assert((!RQI.ExclusionSet || !RQI.ExclusionSet->empty()) && 3554 "Did not expect empty set!"); 3555 RQITy *RQIPtr = new (A.Allocator) 3556 RQITy(A, *RQI.From, *RQI.To, RQI.ExclusionSet, true); 3557 assert(RQIPtr->Result == RQITy::Reachable::No && "Already reachable?"); 3558 RQIPtr->Result = Result; 3559 assert(!QueryCache.count(RQIPtr)); 3560 QueryVector.push_back(RQIPtr); 3561 QueryCache.insert(RQIPtr); 3562 } 3563 3564 if (Result == RQITy::Reachable::No && IsTemporaryRQI) 3565 A.registerForUpdate(*this); 3566 return Result == RQITy::Reachable::Yes; 3567 } 3568 3569 const std::string getAsStr(Attributor *A) const override { 3570 // TODO: Return the number of reachable queries. 3571 return "#queries(" + std::to_string(QueryVector.size()) + ")"; 3572 } 3573 3574 bool checkQueryCache(Attributor &A, RQITy &StackRQI, 3575 typename RQITy::Reachable &Result) { 3576 if (!this->getState().isValidState()) { 3577 Result = RQITy::Reachable::Yes; 3578 return true; 3579 } 3580 3581 // If we have an exclusion set we might be able to find our answer by 3582 // ignoring it first. 3583 if (StackRQI.ExclusionSet) { 3584 RQITy PlainRQI(StackRQI.From, StackRQI.To); 3585 auto It = QueryCache.find(&PlainRQI); 3586 if (It != QueryCache.end() && (*It)->Result == RQITy::Reachable::No) { 3587 Result = RQITy::Reachable::No; 3588 return true; 3589 } 3590 } 3591 3592 auto It = QueryCache.find(&StackRQI); 3593 if (It != QueryCache.end()) { 3594 Result = (*It)->Result; 3595 return true; 3596 } 3597 3598 // Insert a temporary for recursive queries. We will replace it with a 3599 // permanent entry later. 3600 QueryCache.insert(&StackRQI); 3601 return false; 3602 } 3603 3604 private: 3605 SmallVector<RQITy *> QueryVector; 3606 DenseSet<RQITy *> QueryCache; 3607 }; 3608 3609 struct AAIntraFnReachabilityFunction final 3610 : public CachedReachabilityAA<AAIntraFnReachability, Instruction> { 3611 using Base = CachedReachabilityAA<AAIntraFnReachability, Instruction>; 3612 AAIntraFnReachabilityFunction(const IRPosition &IRP, Attributor &A) 3613 : Base(IRP, A) { 3614 DT = A.getInfoCache().getAnalysisResultForFunction<DominatorTreeAnalysis>( 3615 *IRP.getAssociatedFunction()); 3616 } 3617 3618 bool isAssumedReachable( 3619 Attributor &A, const Instruction &From, const Instruction &To, 3620 const AA::InstExclusionSetTy *ExclusionSet) const override { 3621 auto *NonConstThis = const_cast<AAIntraFnReachabilityFunction *>(this); 3622 if (&From == &To) 3623 return true; 3624 3625 RQITy StackRQI(A, From, To, ExclusionSet, false); 3626 typename RQITy::Reachable Result; 3627 if (!NonConstThis->checkQueryCache(A, StackRQI, Result)) 3628 return NonConstThis->isReachableImpl(A, StackRQI, 3629 /*IsTemporaryRQI=*/true); 3630 return Result == RQITy::Reachable::Yes; 3631 } 3632 3633 ChangeStatus updateImpl(Attributor &A) override { 3634 // We only depend on liveness. DeadEdges is all we care about, check if any 3635 // of them changed. 3636 auto *LivenessAA = 3637 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL); 3638 if (LivenessAA && 3639 llvm::all_of(DeadEdges, 3640 [&](const auto &DeadEdge) { 3641 return LivenessAA->isEdgeDead(DeadEdge.first, 3642 DeadEdge.second); 3643 }) && 3644 llvm::all_of(DeadBlocks, [&](const BasicBlock *BB) { 3645 return LivenessAA->isAssumedDead(BB); 3646 })) { 3647 return ChangeStatus::UNCHANGED; 3648 } 3649 DeadEdges.clear(); 3650 DeadBlocks.clear(); 3651 return Base::updateImpl(A); 3652 } 3653 3654 bool isReachableImpl(Attributor &A, RQITy &RQI, 3655 bool IsTemporaryRQI) override { 3656 const Instruction *Origin = RQI.From; 3657 bool UsedExclusionSet = false; 3658 3659 auto WillReachInBlock = [&](const Instruction &From, const Instruction &To, 3660 const AA::InstExclusionSetTy *ExclusionSet) { 3661 const Instruction *IP = &From; 3662 while (IP && IP != &To) { 3663 if (ExclusionSet && IP != Origin && ExclusionSet->count(IP)) { 3664 UsedExclusionSet = true; 3665 break; 3666 } 3667 IP = IP->getNextNode(); 3668 } 3669 return IP == &To; 3670 }; 3671 3672 const BasicBlock *FromBB = RQI.From->getParent(); 3673 const BasicBlock *ToBB = RQI.To->getParent(); 3674 assert(FromBB->getParent() == ToBB->getParent() && 3675 "Not an intra-procedural query!"); 3676 3677 // Check intra-block reachability, however, other reaching paths are still 3678 // possible. 3679 if (FromBB == ToBB && 3680 WillReachInBlock(*RQI.From, *RQI.To, RQI.ExclusionSet)) 3681 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet, 3682 IsTemporaryRQI); 3683 3684 // Check if reaching the ToBB block is sufficient or if even that would not 3685 // ensure reaching the target. In the latter case we are done. 3686 if (!WillReachInBlock(ToBB->front(), *RQI.To, RQI.ExclusionSet)) 3687 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet, 3688 IsTemporaryRQI); 3689 3690 const Function *Fn = FromBB->getParent(); 3691 SmallPtrSet<const BasicBlock *, 16> ExclusionBlocks; 3692 if (RQI.ExclusionSet) 3693 for (auto *I : *RQI.ExclusionSet) 3694 if (I->getFunction() == Fn) 3695 ExclusionBlocks.insert(I->getParent()); 3696 3697 // Check if we make it out of the FromBB block at all. 3698 if (ExclusionBlocks.count(FromBB) && 3699 !WillReachInBlock(*RQI.From, *FromBB->getTerminator(), 3700 RQI.ExclusionSet)) 3701 return rememberResult(A, RQITy::Reachable::No, RQI, true, IsTemporaryRQI); 3702 3703 auto *LivenessAA = 3704 A.getAAFor<AAIsDead>(*this, getIRPosition(), DepClassTy::OPTIONAL); 3705 if (LivenessAA && LivenessAA->isAssumedDead(ToBB)) { 3706 DeadBlocks.insert(ToBB); 3707 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet, 3708 IsTemporaryRQI); 3709 } 3710 3711 SmallPtrSet<const BasicBlock *, 16> Visited; 3712 SmallVector<const BasicBlock *, 16> Worklist; 3713 Worklist.push_back(FromBB); 3714 3715 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> LocalDeadEdges; 3716 while (!Worklist.empty()) { 3717 const BasicBlock *BB = Worklist.pop_back_val(); 3718 if (!Visited.insert(BB).second) 3719 continue; 3720 for (const BasicBlock *SuccBB : successors(BB)) { 3721 if (LivenessAA && LivenessAA->isEdgeDead(BB, SuccBB)) { 3722 LocalDeadEdges.insert({BB, SuccBB}); 3723 continue; 3724 } 3725 // We checked before if we just need to reach the ToBB block. 3726 if (SuccBB == ToBB) 3727 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet, 3728 IsTemporaryRQI); 3729 if (DT && ExclusionBlocks.empty() && DT->dominates(BB, ToBB)) 3730 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet, 3731 IsTemporaryRQI); 3732 3733 if (ExclusionBlocks.count(SuccBB)) { 3734 UsedExclusionSet = true; 3735 continue; 3736 } 3737 Worklist.push_back(SuccBB); 3738 } 3739 } 3740 3741 DeadEdges.insert(LocalDeadEdges.begin(), LocalDeadEdges.end()); 3742 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet, 3743 IsTemporaryRQI); 3744 } 3745 3746 /// See AbstractAttribute::trackStatistics() 3747 void trackStatistics() const override {} 3748 3749 private: 3750 // Set of assumed dead blocks we used in the last query. If any changes we 3751 // update the state. 3752 DenseSet<const BasicBlock *> DeadBlocks; 3753 3754 // Set of assumed dead edges we used in the last query. If any changes we 3755 // update the state. 3756 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> DeadEdges; 3757 3758 /// The dominator tree of the function to short-circuit reasoning. 3759 const DominatorTree *DT = nullptr; 3760 }; 3761 } // namespace 3762 3763 /// ------------------------ NoAlias Argument Attribute ------------------------ 3764 3765 bool AANoAlias::isImpliedByIR(Attributor &A, const IRPosition &IRP, 3766 Attribute::AttrKind ImpliedAttributeKind, 3767 bool IgnoreSubsumingPositions) { 3768 assert(ImpliedAttributeKind == Attribute::NoAlias && 3769 "Unexpected attribute kind"); 3770 Value *Val = &IRP.getAssociatedValue(); 3771 if (IRP.getPositionKind() != IRP_CALL_SITE_ARGUMENT) { 3772 if (isa<AllocaInst>(Val)) 3773 return true; 3774 } else { 3775 IgnoreSubsumingPositions = true; 3776 } 3777 3778 if (isa<UndefValue>(Val)) 3779 return true; 3780 3781 if (isa<ConstantPointerNull>(Val) && 3782 !NullPointerIsDefined(IRP.getAnchorScope(), 3783 Val->getType()->getPointerAddressSpace())) 3784 return true; 3785 3786 if (A.hasAttr(IRP, {Attribute::ByVal, Attribute::NoAlias}, 3787 IgnoreSubsumingPositions, Attribute::NoAlias)) 3788 return true; 3789 3790 return false; 3791 } 3792 3793 namespace { 3794 struct AANoAliasImpl : AANoAlias { 3795 AANoAliasImpl(const IRPosition &IRP, Attributor &A) : AANoAlias(IRP, A) { 3796 assert(getAssociatedType()->isPointerTy() && 3797 "Noalias is a pointer attribute"); 3798 } 3799 3800 const std::string getAsStr(Attributor *A) const override { 3801 return getAssumed() ? "noalias" : "may-alias"; 3802 } 3803 }; 3804 3805 /// NoAlias attribute for a floating value. 3806 struct AANoAliasFloating final : AANoAliasImpl { 3807 AANoAliasFloating(const IRPosition &IRP, Attributor &A) 3808 : AANoAliasImpl(IRP, A) {} 3809 3810 /// See AbstractAttribute::updateImpl(...). 3811 ChangeStatus updateImpl(Attributor &A) override { 3812 // TODO: Implement this. 3813 return indicatePessimisticFixpoint(); 3814 } 3815 3816 /// See AbstractAttribute::trackStatistics() 3817 void trackStatistics() const override { 3818 STATS_DECLTRACK_FLOATING_ATTR(noalias) 3819 } 3820 }; 3821 3822 /// NoAlias attribute for an argument. 3823 struct AANoAliasArgument final 3824 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> { 3825 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>; 3826 AANoAliasArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {} 3827 3828 /// See AbstractAttribute::update(...). 3829 ChangeStatus updateImpl(Attributor &A) override { 3830 // We have to make sure no-alias on the argument does not break 3831 // synchronization when this is a callback argument, see also [1] below. 3832 // If synchronization cannot be affected, we delegate to the base updateImpl 3833 // function, otherwise we give up for now. 3834 3835 // If the function is no-sync, no-alias cannot break synchronization. 3836 bool IsKnownNoSycn; 3837 if (AA::hasAssumedIRAttr<Attribute::NoSync>( 3838 A, this, IRPosition::function_scope(getIRPosition()), 3839 DepClassTy::OPTIONAL, IsKnownNoSycn)) 3840 return Base::updateImpl(A); 3841 3842 // If the argument is read-only, no-alias cannot break synchronization. 3843 bool IsKnown; 3844 if (AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown)) 3845 return Base::updateImpl(A); 3846 3847 // If the argument is never passed through callbacks, no-alias cannot break 3848 // synchronization. 3849 bool UsedAssumedInformation = false; 3850 if (A.checkForAllCallSites( 3851 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this, 3852 true, UsedAssumedInformation)) 3853 return Base::updateImpl(A); 3854 3855 // TODO: add no-alias but make sure it doesn't break synchronization by 3856 // introducing fake uses. See: 3857 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel, 3858 // International Workshop on OpenMP 2018, 3859 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf 3860 3861 return indicatePessimisticFixpoint(); 3862 } 3863 3864 /// See AbstractAttribute::trackStatistics() 3865 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) } 3866 }; 3867 3868 struct AANoAliasCallSiteArgument final : AANoAliasImpl { 3869 AANoAliasCallSiteArgument(const IRPosition &IRP, Attributor &A) 3870 : AANoAliasImpl(IRP, A) {} 3871 3872 /// Determine if the underlying value may alias with the call site argument 3873 /// \p OtherArgNo of \p ICS (= the underlying call site). 3874 bool mayAliasWithArgument(Attributor &A, AAResults *&AAR, 3875 const AAMemoryBehavior &MemBehaviorAA, 3876 const CallBase &CB, unsigned OtherArgNo) { 3877 // We do not need to worry about aliasing with the underlying IRP. 3878 if (this->getCalleeArgNo() == (int)OtherArgNo) 3879 return false; 3880 3881 // If it is not a pointer or pointer vector we do not alias. 3882 const Value *ArgOp = CB.getArgOperand(OtherArgNo); 3883 if (!ArgOp->getType()->isPtrOrPtrVectorTy()) 3884 return false; 3885 3886 auto *CBArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>( 3887 *this, IRPosition::callsite_argument(CB, OtherArgNo), DepClassTy::NONE); 3888 3889 // If the argument is readnone, there is no read-write aliasing. 3890 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadNone()) { 3891 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL); 3892 return false; 3893 } 3894 3895 // If the argument is readonly and the underlying value is readonly, there 3896 // is no read-write aliasing. 3897 bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly(); 3898 if (CBArgMemBehaviorAA && CBArgMemBehaviorAA->isAssumedReadOnly() && 3899 IsReadOnly) { 3900 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL); 3901 A.recordDependence(*CBArgMemBehaviorAA, *this, DepClassTy::OPTIONAL); 3902 return false; 3903 } 3904 3905 // We have to utilize actual alias analysis queries so we need the object. 3906 if (!AAR) 3907 AAR = A.getInfoCache().getAnalysisResultForFunction<AAManager>( 3908 *getAnchorScope()); 3909 3910 // Try to rule it out at the call site. 3911 bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp); 3912 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between " 3913 "callsite arguments: " 3914 << getAssociatedValue() << " " << *ArgOp << " => " 3915 << (IsAliasing ? "" : "no-") << "alias \n"); 3916 3917 return IsAliasing; 3918 } 3919 3920 bool isKnownNoAliasDueToNoAliasPreservation( 3921 Attributor &A, AAResults *&AAR, const AAMemoryBehavior &MemBehaviorAA) { 3922 // We can deduce "noalias" if the following conditions hold. 3923 // (i) Associated value is assumed to be noalias in the definition. 3924 // (ii) Associated value is assumed to be no-capture in all the uses 3925 // possibly executed before this callsite. 3926 // (iii) There is no other pointer argument which could alias with the 3927 // value. 3928 3929 auto IsDereferenceableOrNull = [&](Value *O, const DataLayout &DL) { 3930 const auto *DerefAA = A.getAAFor<AADereferenceable>( 3931 *this, IRPosition::value(*O), DepClassTy::OPTIONAL); 3932 return DerefAA ? DerefAA->getAssumedDereferenceableBytes() : 0; 3933 }; 3934 3935 const IRPosition &VIRP = IRPosition::value(getAssociatedValue()); 3936 const Function *ScopeFn = VIRP.getAnchorScope(); 3937 // Check whether the value is captured in the scope using AANoCapture. 3938 // Look at CFG and check only uses possibly executed before this 3939 // callsite. 3940 auto UsePred = [&](const Use &U, bool &Follow) -> bool { 3941 Instruction *UserI = cast<Instruction>(U.getUser()); 3942 3943 // If UserI is the curr instruction and there is a single potential use of 3944 // the value in UserI we allow the use. 3945 // TODO: We should inspect the operands and allow those that cannot alias 3946 // with the value. 3947 if (UserI == getCtxI() && UserI->getNumOperands() == 1) 3948 return true; 3949 3950 if (ScopeFn) { 3951 if (auto *CB = dyn_cast<CallBase>(UserI)) { 3952 if (CB->isArgOperand(&U)) { 3953 3954 unsigned ArgNo = CB->getArgOperandNo(&U); 3955 3956 bool IsKnownNoCapture; 3957 if (AA::hasAssumedIRAttr<Attribute::Captures>( 3958 A, this, IRPosition::callsite_argument(*CB, ArgNo), 3959 DepClassTy::OPTIONAL, IsKnownNoCapture)) 3960 return true; 3961 } 3962 } 3963 3964 if (!AA::isPotentiallyReachable( 3965 A, *UserI, *getCtxI(), *this, /* ExclusionSet */ nullptr, 3966 [ScopeFn](const Function &Fn) { return &Fn != ScopeFn; })) 3967 return true; 3968 } 3969 3970 // TODO: We should track the capturing uses in AANoCapture but the problem 3971 // is CGSCC runs. For those we would need to "allow" AANoCapture for 3972 // a value in the module slice. 3973 switch (DetermineUseCaptureKind(U, IsDereferenceableOrNull)) { 3974 case UseCaptureKind::NO_CAPTURE: 3975 return true; 3976 case UseCaptureKind::MAY_CAPTURE: 3977 LLVM_DEBUG(dbgs() << "[AANoAliasCSArg] Unknown user: " << *UserI 3978 << "\n"); 3979 return false; 3980 case UseCaptureKind::PASSTHROUGH: 3981 Follow = true; 3982 return true; 3983 } 3984 llvm_unreachable("unknown UseCaptureKind"); 3985 }; 3986 3987 bool IsKnownNoCapture; 3988 const AANoCapture *NoCaptureAA = nullptr; 3989 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>( 3990 A, this, VIRP, DepClassTy::NONE, IsKnownNoCapture, false, &NoCaptureAA); 3991 if (!IsAssumedNoCapture && 3992 (!NoCaptureAA || !NoCaptureAA->isAssumedNoCaptureMaybeReturned())) { 3993 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) { 3994 LLVM_DEBUG( 3995 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue() 3996 << " cannot be noalias as it is potentially captured\n"); 3997 return false; 3998 } 3999 } 4000 if (NoCaptureAA) 4001 A.recordDependence(*NoCaptureAA, *this, DepClassTy::OPTIONAL); 4002 4003 // Check there is no other pointer argument which could alias with the 4004 // value passed at this call site. 4005 // TODO: AbstractCallSite 4006 const auto &CB = cast<CallBase>(getAnchorValue()); 4007 for (unsigned OtherArgNo = 0; OtherArgNo < CB.arg_size(); OtherArgNo++) 4008 if (mayAliasWithArgument(A, AAR, MemBehaviorAA, CB, OtherArgNo)) 4009 return false; 4010 4011 return true; 4012 } 4013 4014 /// See AbstractAttribute::updateImpl(...). 4015 ChangeStatus updateImpl(Attributor &A) override { 4016 // If the argument is readnone we are done as there are no accesses via the 4017 // argument. 4018 auto *MemBehaviorAA = 4019 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE); 4020 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) { 4021 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL); 4022 return ChangeStatus::UNCHANGED; 4023 } 4024 4025 bool IsKnownNoAlias; 4026 const IRPosition &VIRP = IRPosition::value(getAssociatedValue()); 4027 if (!AA::hasAssumedIRAttr<Attribute::NoAlias>( 4028 A, this, VIRP, DepClassTy::REQUIRED, IsKnownNoAlias)) { 4029 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue() 4030 << " is not no-alias at the definition\n"); 4031 return indicatePessimisticFixpoint(); 4032 } 4033 4034 AAResults *AAR = nullptr; 4035 if (MemBehaviorAA && 4036 isKnownNoAliasDueToNoAliasPreservation(A, AAR, *MemBehaviorAA)) { 4037 LLVM_DEBUG( 4038 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n"); 4039 return ChangeStatus::UNCHANGED; 4040 } 4041 4042 return indicatePessimisticFixpoint(); 4043 } 4044 4045 /// See AbstractAttribute::trackStatistics() 4046 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) } 4047 }; 4048 4049 /// NoAlias attribute for function return value. 4050 struct AANoAliasReturned final : AANoAliasImpl { 4051 AANoAliasReturned(const IRPosition &IRP, Attributor &A) 4052 : AANoAliasImpl(IRP, A) {} 4053 4054 /// See AbstractAttribute::updateImpl(...). 4055 ChangeStatus updateImpl(Attributor &A) override { 4056 4057 auto CheckReturnValue = [&](Value &RV) -> bool { 4058 if (Constant *C = dyn_cast<Constant>(&RV)) 4059 if (C->isNullValue() || isa<UndefValue>(C)) 4060 return true; 4061 4062 /// For now, we can only deduce noalias if we have call sites. 4063 /// FIXME: add more support. 4064 if (!isa<CallBase>(&RV)) 4065 return false; 4066 4067 const IRPosition &RVPos = IRPosition::value(RV); 4068 bool IsKnownNoAlias; 4069 if (!AA::hasAssumedIRAttr<Attribute::NoAlias>( 4070 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoAlias)) 4071 return false; 4072 4073 bool IsKnownNoCapture; 4074 const AANoCapture *NoCaptureAA = nullptr; 4075 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>( 4076 A, this, RVPos, DepClassTy::REQUIRED, IsKnownNoCapture, false, 4077 &NoCaptureAA); 4078 return IsAssumedNoCapture || 4079 (NoCaptureAA && NoCaptureAA->isAssumedNoCaptureMaybeReturned()); 4080 }; 4081 4082 if (!A.checkForAllReturnedValues(CheckReturnValue, *this)) 4083 return indicatePessimisticFixpoint(); 4084 4085 return ChangeStatus::UNCHANGED; 4086 } 4087 4088 /// See AbstractAttribute::trackStatistics() 4089 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) } 4090 }; 4091 4092 /// NoAlias attribute deduction for a call site return value. 4093 struct AANoAliasCallSiteReturned final 4094 : AACalleeToCallSite<AANoAlias, AANoAliasImpl> { 4095 AANoAliasCallSiteReturned(const IRPosition &IRP, Attributor &A) 4096 : AACalleeToCallSite<AANoAlias, AANoAliasImpl>(IRP, A) {} 4097 4098 /// See AbstractAttribute::trackStatistics() 4099 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); } 4100 }; 4101 } // namespace 4102 4103 /// -------------------AAIsDead Function Attribute----------------------- 4104 4105 namespace { 4106 struct AAIsDeadValueImpl : public AAIsDead { 4107 AAIsDeadValueImpl(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {} 4108 4109 /// See AAIsDead::isAssumedDead(). 4110 bool isAssumedDead() const override { return isAssumed(IS_DEAD); } 4111 4112 /// See AAIsDead::isKnownDead(). 4113 bool isKnownDead() const override { return isKnown(IS_DEAD); } 4114 4115 /// See AAIsDead::isAssumedDead(BasicBlock *). 4116 bool isAssumedDead(const BasicBlock *BB) const override { return false; } 4117 4118 /// See AAIsDead::isKnownDead(BasicBlock *). 4119 bool isKnownDead(const BasicBlock *BB) const override { return false; } 4120 4121 /// See AAIsDead::isAssumedDead(Instruction *I). 4122 bool isAssumedDead(const Instruction *I) const override { 4123 return I == getCtxI() && isAssumedDead(); 4124 } 4125 4126 /// See AAIsDead::isKnownDead(Instruction *I). 4127 bool isKnownDead(const Instruction *I) const override { 4128 return isAssumedDead(I) && isKnownDead(); 4129 } 4130 4131 /// See AbstractAttribute::getAsStr(). 4132 const std::string getAsStr(Attributor *A) const override { 4133 return isAssumedDead() ? "assumed-dead" : "assumed-live"; 4134 } 4135 4136 /// Check if all uses are assumed dead. 4137 bool areAllUsesAssumedDead(Attributor &A, Value &V) { 4138 // Callers might not check the type, void has no uses. 4139 if (V.getType()->isVoidTy() || V.use_empty()) 4140 return true; 4141 4142 // If we replace a value with a constant there are no uses left afterwards. 4143 if (!isa<Constant>(V)) { 4144 if (auto *I = dyn_cast<Instruction>(&V)) 4145 if (!A.isRunOn(*I->getFunction())) 4146 return false; 4147 bool UsedAssumedInformation = false; 4148 std::optional<Constant *> C = 4149 A.getAssumedConstant(V, *this, UsedAssumedInformation); 4150 if (!C || *C) 4151 return true; 4152 } 4153 4154 auto UsePred = [&](const Use &U, bool &Follow) { return false; }; 4155 // Explicitly set the dependence class to required because we want a long 4156 // chain of N dependent instructions to be considered live as soon as one is 4157 // without going through N update cycles. This is not required for 4158 // correctness. 4159 return A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ false, 4160 DepClassTy::REQUIRED, 4161 /* IgnoreDroppableUses */ false); 4162 } 4163 4164 /// Determine if \p I is assumed to be side-effect free. 4165 bool isAssumedSideEffectFree(Attributor &A, Instruction *I) { 4166 if (!I || wouldInstructionBeTriviallyDead(I)) 4167 return true; 4168 4169 auto *CB = dyn_cast<CallBase>(I); 4170 if (!CB || isa<IntrinsicInst>(CB)) 4171 return false; 4172 4173 const IRPosition &CallIRP = IRPosition::callsite_function(*CB); 4174 4175 bool IsKnownNoUnwind; 4176 if (!AA::hasAssumedIRAttr<Attribute::NoUnwind>( 4177 A, this, CallIRP, DepClassTy::OPTIONAL, IsKnownNoUnwind)) 4178 return false; 4179 4180 bool IsKnown; 4181 return AA::isAssumedReadOnly(A, CallIRP, *this, IsKnown); 4182 } 4183 }; 4184 4185 struct AAIsDeadFloating : public AAIsDeadValueImpl { 4186 AAIsDeadFloating(const IRPosition &IRP, Attributor &A) 4187 : AAIsDeadValueImpl(IRP, A) {} 4188 4189 /// See AbstractAttribute::initialize(...). 4190 void initialize(Attributor &A) override { 4191 AAIsDeadValueImpl::initialize(A); 4192 4193 if (isa<UndefValue>(getAssociatedValue())) { 4194 indicatePessimisticFixpoint(); 4195 return; 4196 } 4197 4198 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()); 4199 if (!isAssumedSideEffectFree(A, I)) { 4200 if (!isa_and_nonnull<StoreInst>(I) && !isa_and_nonnull<FenceInst>(I)) 4201 indicatePessimisticFixpoint(); 4202 else 4203 removeAssumedBits(HAS_NO_EFFECT); 4204 } 4205 } 4206 4207 bool isDeadFence(Attributor &A, FenceInst &FI) { 4208 const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>( 4209 IRPosition::function(*FI.getFunction()), *this, DepClassTy::NONE); 4210 if (!ExecDomainAA || !ExecDomainAA->isNoOpFence(FI)) 4211 return false; 4212 A.recordDependence(*ExecDomainAA, *this, DepClassTy::OPTIONAL); 4213 return true; 4214 } 4215 4216 bool isDeadStore(Attributor &A, StoreInst &SI, 4217 SmallSetVector<Instruction *, 8> *AssumeOnlyInst = nullptr) { 4218 // Lang ref now states volatile store is not UB/dead, let's skip them. 4219 if (SI.isVolatile()) 4220 return false; 4221 4222 // If we are collecting assumes to be deleted we are in the manifest stage. 4223 // It's problematic to collect the potential copies again now so we use the 4224 // cached ones. 4225 bool UsedAssumedInformation = false; 4226 if (!AssumeOnlyInst) { 4227 PotentialCopies.clear(); 4228 if (!AA::getPotentialCopiesOfStoredValue(A, SI, PotentialCopies, *this, 4229 UsedAssumedInformation)) { 4230 LLVM_DEBUG( 4231 dbgs() 4232 << "[AAIsDead] Could not determine potential copies of store!\n"); 4233 return false; 4234 } 4235 } 4236 LLVM_DEBUG(dbgs() << "[AAIsDead] Store has " << PotentialCopies.size() 4237 << " potential copies.\n"); 4238 4239 InformationCache &InfoCache = A.getInfoCache(); 4240 return llvm::all_of(PotentialCopies, [&](Value *V) { 4241 if (A.isAssumedDead(IRPosition::value(*V), this, nullptr, 4242 UsedAssumedInformation)) 4243 return true; 4244 if (auto *LI = dyn_cast<LoadInst>(V)) { 4245 if (llvm::all_of(LI->uses(), [&](const Use &U) { 4246 auto &UserI = cast<Instruction>(*U.getUser()); 4247 if (InfoCache.isOnlyUsedByAssume(UserI)) { 4248 if (AssumeOnlyInst) 4249 AssumeOnlyInst->insert(&UserI); 4250 return true; 4251 } 4252 return A.isAssumedDead(U, this, nullptr, UsedAssumedInformation); 4253 })) { 4254 return true; 4255 } 4256 } 4257 LLVM_DEBUG(dbgs() << "[AAIsDead] Potential copy " << *V 4258 << " is assumed live!\n"); 4259 return false; 4260 }); 4261 } 4262 4263 /// See AbstractAttribute::getAsStr(). 4264 const std::string getAsStr(Attributor *A) const override { 4265 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()); 4266 if (isa_and_nonnull<StoreInst>(I)) 4267 if (isValidState()) 4268 return "assumed-dead-store"; 4269 if (isa_and_nonnull<FenceInst>(I)) 4270 if (isValidState()) 4271 return "assumed-dead-fence"; 4272 return AAIsDeadValueImpl::getAsStr(A); 4273 } 4274 4275 /// See AbstractAttribute::updateImpl(...). 4276 ChangeStatus updateImpl(Attributor &A) override { 4277 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()); 4278 if (auto *SI = dyn_cast_or_null<StoreInst>(I)) { 4279 if (!isDeadStore(A, *SI)) 4280 return indicatePessimisticFixpoint(); 4281 } else if (auto *FI = dyn_cast_or_null<FenceInst>(I)) { 4282 if (!isDeadFence(A, *FI)) 4283 return indicatePessimisticFixpoint(); 4284 } else { 4285 if (!isAssumedSideEffectFree(A, I)) 4286 return indicatePessimisticFixpoint(); 4287 if (!areAllUsesAssumedDead(A, getAssociatedValue())) 4288 return indicatePessimisticFixpoint(); 4289 } 4290 return ChangeStatus::UNCHANGED; 4291 } 4292 4293 bool isRemovableStore() const override { 4294 return isAssumed(IS_REMOVABLE) && isa<StoreInst>(&getAssociatedValue()); 4295 } 4296 4297 /// See AbstractAttribute::manifest(...). 4298 ChangeStatus manifest(Attributor &A) override { 4299 Value &V = getAssociatedValue(); 4300 if (auto *I = dyn_cast<Instruction>(&V)) { 4301 // If we get here we basically know the users are all dead. We check if 4302 // isAssumedSideEffectFree returns true here again because it might not be 4303 // the case and only the users are dead but the instruction (=call) is 4304 // still needed. 4305 if (auto *SI = dyn_cast<StoreInst>(I)) { 4306 SmallSetVector<Instruction *, 8> AssumeOnlyInst; 4307 bool IsDead = isDeadStore(A, *SI, &AssumeOnlyInst); 4308 (void)IsDead; 4309 assert(IsDead && "Store was assumed to be dead!"); 4310 A.deleteAfterManifest(*I); 4311 for (size_t i = 0; i < AssumeOnlyInst.size(); ++i) { 4312 Instruction *AOI = AssumeOnlyInst[i]; 4313 for (auto *Usr : AOI->users()) 4314 AssumeOnlyInst.insert(cast<Instruction>(Usr)); 4315 A.deleteAfterManifest(*AOI); 4316 } 4317 return ChangeStatus::CHANGED; 4318 } 4319 if (auto *FI = dyn_cast<FenceInst>(I)) { 4320 assert(isDeadFence(A, *FI)); 4321 A.deleteAfterManifest(*FI); 4322 return ChangeStatus::CHANGED; 4323 } 4324 if (isAssumedSideEffectFree(A, I) && !isa<InvokeInst>(I)) { 4325 A.deleteAfterManifest(*I); 4326 return ChangeStatus::CHANGED; 4327 } 4328 } 4329 return ChangeStatus::UNCHANGED; 4330 } 4331 4332 /// See AbstractAttribute::trackStatistics() 4333 void trackStatistics() const override { 4334 STATS_DECLTRACK_FLOATING_ATTR(IsDead) 4335 } 4336 4337 private: 4338 // The potential copies of a dead store, used for deletion during manifest. 4339 SmallSetVector<Value *, 4> PotentialCopies; 4340 }; 4341 4342 struct AAIsDeadArgument : public AAIsDeadFloating { 4343 AAIsDeadArgument(const IRPosition &IRP, Attributor &A) 4344 : AAIsDeadFloating(IRP, A) {} 4345 4346 /// See AbstractAttribute::manifest(...). 4347 ChangeStatus manifest(Attributor &A) override { 4348 Argument &Arg = *getAssociatedArgument(); 4349 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {})) 4350 if (A.registerFunctionSignatureRewrite( 4351 Arg, /* ReplacementTypes */ {}, 4352 Attributor::ArgumentReplacementInfo::CalleeRepairCBTy{}, 4353 Attributor::ArgumentReplacementInfo::ACSRepairCBTy{})) { 4354 return ChangeStatus::CHANGED; 4355 } 4356 return ChangeStatus::UNCHANGED; 4357 } 4358 4359 /// See AbstractAttribute::trackStatistics() 4360 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) } 4361 }; 4362 4363 struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl { 4364 AAIsDeadCallSiteArgument(const IRPosition &IRP, Attributor &A) 4365 : AAIsDeadValueImpl(IRP, A) {} 4366 4367 /// See AbstractAttribute::initialize(...). 4368 void initialize(Attributor &A) override { 4369 AAIsDeadValueImpl::initialize(A); 4370 if (isa<UndefValue>(getAssociatedValue())) 4371 indicatePessimisticFixpoint(); 4372 } 4373 4374 /// See AbstractAttribute::updateImpl(...). 4375 ChangeStatus updateImpl(Attributor &A) override { 4376 // TODO: Once we have call site specific value information we can provide 4377 // call site specific liveness information and then it makes 4378 // sense to specialize attributes for call sites arguments instead of 4379 // redirecting requests to the callee argument. 4380 Argument *Arg = getAssociatedArgument(); 4381 if (!Arg) 4382 return indicatePessimisticFixpoint(); 4383 const IRPosition &ArgPos = IRPosition::argument(*Arg); 4384 auto *ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos, DepClassTy::REQUIRED); 4385 if (!ArgAA) 4386 return indicatePessimisticFixpoint(); 4387 return clampStateAndIndicateChange(getState(), ArgAA->getState()); 4388 } 4389 4390 /// See AbstractAttribute::manifest(...). 4391 ChangeStatus manifest(Attributor &A) override { 4392 CallBase &CB = cast<CallBase>(getAnchorValue()); 4393 Use &U = CB.getArgOperandUse(getCallSiteArgNo()); 4394 assert(!isa<UndefValue>(U.get()) && 4395 "Expected undef values to be filtered out!"); 4396 UndefValue &UV = *UndefValue::get(U->getType()); 4397 if (A.changeUseAfterManifest(U, UV)) 4398 return ChangeStatus::CHANGED; 4399 return ChangeStatus::UNCHANGED; 4400 } 4401 4402 /// See AbstractAttribute::trackStatistics() 4403 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) } 4404 }; 4405 4406 struct AAIsDeadCallSiteReturned : public AAIsDeadFloating { 4407 AAIsDeadCallSiteReturned(const IRPosition &IRP, Attributor &A) 4408 : AAIsDeadFloating(IRP, A) {} 4409 4410 /// See AAIsDead::isAssumedDead(). 4411 bool isAssumedDead() const override { 4412 return AAIsDeadFloating::isAssumedDead() && IsAssumedSideEffectFree; 4413 } 4414 4415 /// See AbstractAttribute::initialize(...). 4416 void initialize(Attributor &A) override { 4417 AAIsDeadFloating::initialize(A); 4418 if (isa<UndefValue>(getAssociatedValue())) { 4419 indicatePessimisticFixpoint(); 4420 return; 4421 } 4422 4423 // We track this separately as a secondary state. 4424 IsAssumedSideEffectFree = isAssumedSideEffectFree(A, getCtxI()); 4425 } 4426 4427 /// See AbstractAttribute::updateImpl(...). 4428 ChangeStatus updateImpl(Attributor &A) override { 4429 ChangeStatus Changed = ChangeStatus::UNCHANGED; 4430 if (IsAssumedSideEffectFree && !isAssumedSideEffectFree(A, getCtxI())) { 4431 IsAssumedSideEffectFree = false; 4432 Changed = ChangeStatus::CHANGED; 4433 } 4434 if (!areAllUsesAssumedDead(A, getAssociatedValue())) 4435 return indicatePessimisticFixpoint(); 4436 return Changed; 4437 } 4438 4439 /// See AbstractAttribute::trackStatistics() 4440 void trackStatistics() const override { 4441 if (IsAssumedSideEffectFree) 4442 STATS_DECLTRACK_CSRET_ATTR(IsDead) 4443 else 4444 STATS_DECLTRACK_CSRET_ATTR(UnusedResult) 4445 } 4446 4447 /// See AbstractAttribute::getAsStr(). 4448 const std::string getAsStr(Attributor *A) const override { 4449 return isAssumedDead() 4450 ? "assumed-dead" 4451 : (getAssumed() ? "assumed-dead-users" : "assumed-live"); 4452 } 4453 4454 private: 4455 bool IsAssumedSideEffectFree = true; 4456 }; 4457 4458 struct AAIsDeadReturned : public AAIsDeadValueImpl { 4459 AAIsDeadReturned(const IRPosition &IRP, Attributor &A) 4460 : AAIsDeadValueImpl(IRP, A) {} 4461 4462 /// See AbstractAttribute::updateImpl(...). 4463 ChangeStatus updateImpl(Attributor &A) override { 4464 4465 bool UsedAssumedInformation = false; 4466 A.checkForAllInstructions([](Instruction &) { return true; }, *this, 4467 {Instruction::Ret}, UsedAssumedInformation); 4468 4469 auto PredForCallSite = [&](AbstractCallSite ACS) { 4470 if (ACS.isCallbackCall() || !ACS.getInstruction()) 4471 return false; 4472 return areAllUsesAssumedDead(A, *ACS.getInstruction()); 4473 }; 4474 4475 if (!A.checkForAllCallSites(PredForCallSite, *this, true, 4476 UsedAssumedInformation)) 4477 return indicatePessimisticFixpoint(); 4478 4479 return ChangeStatus::UNCHANGED; 4480 } 4481 4482 /// See AbstractAttribute::manifest(...). 4483 ChangeStatus manifest(Attributor &A) override { 4484 // TODO: Rewrite the signature to return void? 4485 bool AnyChange = false; 4486 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType()); 4487 auto RetInstPred = [&](Instruction &I) { 4488 ReturnInst &RI = cast<ReturnInst>(I); 4489 if (!isa<UndefValue>(RI.getReturnValue())) 4490 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV); 4491 return true; 4492 }; 4493 bool UsedAssumedInformation = false; 4494 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret}, 4495 UsedAssumedInformation); 4496 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 4497 } 4498 4499 /// See AbstractAttribute::trackStatistics() 4500 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) } 4501 }; 4502 4503 struct AAIsDeadFunction : public AAIsDead { 4504 AAIsDeadFunction(const IRPosition &IRP, Attributor &A) : AAIsDead(IRP, A) {} 4505 4506 /// See AbstractAttribute::initialize(...). 4507 void initialize(Attributor &A) override { 4508 Function *F = getAnchorScope(); 4509 assert(F && "Did expect an anchor function"); 4510 if (!isAssumedDeadInternalFunction(A)) { 4511 ToBeExploredFrom.insert(&F->getEntryBlock().front()); 4512 assumeLive(A, F->getEntryBlock()); 4513 } 4514 } 4515 4516 bool isAssumedDeadInternalFunction(Attributor &A) { 4517 if (!getAnchorScope()->hasLocalLinkage()) 4518 return false; 4519 bool UsedAssumedInformation = false; 4520 return A.checkForAllCallSites([](AbstractCallSite) { return false; }, *this, 4521 true, UsedAssumedInformation); 4522 } 4523 4524 /// See AbstractAttribute::getAsStr(). 4525 const std::string getAsStr(Attributor *A) const override { 4526 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" + 4527 std::to_string(getAnchorScope()->size()) + "][#TBEP " + 4528 std::to_string(ToBeExploredFrom.size()) + "][#KDE " + 4529 std::to_string(KnownDeadEnds.size()) + "]"; 4530 } 4531 4532 /// See AbstractAttribute::manifest(...). 4533 ChangeStatus manifest(Attributor &A) override { 4534 assert(getState().isValidState() && 4535 "Attempted to manifest an invalid state!"); 4536 4537 ChangeStatus HasChanged = ChangeStatus::UNCHANGED; 4538 Function &F = *getAnchorScope(); 4539 4540 if (AssumedLiveBlocks.empty()) { 4541 A.deleteAfterManifest(F); 4542 return ChangeStatus::CHANGED; 4543 } 4544 4545 // Flag to determine if we can change an invoke to a call assuming the 4546 // callee is nounwind. This is not possible if the personality of the 4547 // function allows to catch asynchronous exceptions. 4548 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F); 4549 4550 KnownDeadEnds.set_union(ToBeExploredFrom); 4551 for (const Instruction *DeadEndI : KnownDeadEnds) { 4552 auto *CB = dyn_cast<CallBase>(DeadEndI); 4553 if (!CB) 4554 continue; 4555 bool IsKnownNoReturn; 4556 bool MayReturn = !AA::hasAssumedIRAttr<Attribute::NoReturn>( 4557 A, this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL, 4558 IsKnownNoReturn); 4559 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB))) 4560 continue; 4561 4562 if (auto *II = dyn_cast<InvokeInst>(DeadEndI)) 4563 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II)); 4564 else 4565 A.changeToUnreachableAfterManifest( 4566 const_cast<Instruction *>(DeadEndI->getNextNode())); 4567 HasChanged = ChangeStatus::CHANGED; 4568 } 4569 4570 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted."); 4571 for (BasicBlock &BB : F) 4572 if (!AssumedLiveBlocks.count(&BB)) { 4573 A.deleteAfterManifest(BB); 4574 ++BUILD_STAT_NAME(AAIsDead, BasicBlock); 4575 HasChanged = ChangeStatus::CHANGED; 4576 } 4577 4578 return HasChanged; 4579 } 4580 4581 /// See AbstractAttribute::updateImpl(...). 4582 ChangeStatus updateImpl(Attributor &A) override; 4583 4584 bool isEdgeDead(const BasicBlock *From, const BasicBlock *To) const override { 4585 assert(From->getParent() == getAnchorScope() && 4586 To->getParent() == getAnchorScope() && 4587 "Used AAIsDead of the wrong function"); 4588 return isValidState() && !AssumedLiveEdges.count(std::make_pair(From, To)); 4589 } 4590 4591 /// See AbstractAttribute::trackStatistics() 4592 void trackStatistics() const override {} 4593 4594 /// Returns true if the function is assumed dead. 4595 bool isAssumedDead() const override { return false; } 4596 4597 /// See AAIsDead::isKnownDead(). 4598 bool isKnownDead() const override { return false; } 4599 4600 /// See AAIsDead::isAssumedDead(BasicBlock *). 4601 bool isAssumedDead(const BasicBlock *BB) const override { 4602 assert(BB->getParent() == getAnchorScope() && 4603 "BB must be in the same anchor scope function."); 4604 4605 if (!getAssumed()) 4606 return false; 4607 return !AssumedLiveBlocks.count(BB); 4608 } 4609 4610 /// See AAIsDead::isKnownDead(BasicBlock *). 4611 bool isKnownDead(const BasicBlock *BB) const override { 4612 return getKnown() && isAssumedDead(BB); 4613 } 4614 4615 /// See AAIsDead::isAssumed(Instruction *I). 4616 bool isAssumedDead(const Instruction *I) const override { 4617 assert(I->getParent()->getParent() == getAnchorScope() && 4618 "Instruction must be in the same anchor scope function."); 4619 4620 if (!getAssumed()) 4621 return false; 4622 4623 // If it is not in AssumedLiveBlocks then it for sure dead. 4624 // Otherwise, it can still be after noreturn call in a live block. 4625 if (!AssumedLiveBlocks.count(I->getParent())) 4626 return true; 4627 4628 // If it is not after a liveness barrier it is live. 4629 const Instruction *PrevI = I->getPrevNode(); 4630 while (PrevI) { 4631 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI)) 4632 return true; 4633 PrevI = PrevI->getPrevNode(); 4634 } 4635 return false; 4636 } 4637 4638 /// See AAIsDead::isKnownDead(Instruction *I). 4639 bool isKnownDead(const Instruction *I) const override { 4640 return getKnown() && isAssumedDead(I); 4641 } 4642 4643 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A 4644 /// that internal function called from \p BB should now be looked at. 4645 bool assumeLive(Attributor &A, const BasicBlock &BB) { 4646 if (!AssumedLiveBlocks.insert(&BB).second) 4647 return false; 4648 4649 // We assume that all of BB is (probably) live now and if there are calls to 4650 // internal functions we will assume that those are now live as well. This 4651 // is a performance optimization for blocks with calls to a lot of internal 4652 // functions. It can however cause dead functions to be treated as live. 4653 for (const Instruction &I : BB) 4654 if (const auto *CB = dyn_cast<CallBase>(&I)) 4655 if (auto *F = dyn_cast_if_present<Function>(CB->getCalledOperand())) 4656 if (F->hasLocalLinkage()) 4657 A.markLiveInternalFunction(*F); 4658 return true; 4659 } 4660 4661 /// Collection of instructions that need to be explored again, e.g., we 4662 /// did assume they do not transfer control to (one of their) successors. 4663 SmallSetVector<const Instruction *, 8> ToBeExploredFrom; 4664 4665 /// Collection of instructions that are known to not transfer control. 4666 SmallSetVector<const Instruction *, 8> KnownDeadEnds; 4667 4668 /// Collection of all assumed live edges 4669 DenseSet<std::pair<const BasicBlock *, const BasicBlock *>> AssumedLiveEdges; 4670 4671 /// Collection of all assumed live BasicBlocks. 4672 DenseSet<const BasicBlock *> AssumedLiveBlocks; 4673 }; 4674 4675 static bool 4676 identifyAliveSuccessors(Attributor &A, const CallBase &CB, 4677 AbstractAttribute &AA, 4678 SmallVectorImpl<const Instruction *> &AliveSuccessors) { 4679 const IRPosition &IPos = IRPosition::callsite_function(CB); 4680 4681 bool IsKnownNoReturn; 4682 if (AA::hasAssumedIRAttr<Attribute::NoReturn>( 4683 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoReturn)) 4684 return !IsKnownNoReturn; 4685 if (CB.isTerminator()) 4686 AliveSuccessors.push_back(&CB.getSuccessor(0)->front()); 4687 else 4688 AliveSuccessors.push_back(CB.getNextNode()); 4689 return false; 4690 } 4691 4692 static bool 4693 identifyAliveSuccessors(Attributor &A, const InvokeInst &II, 4694 AbstractAttribute &AA, 4695 SmallVectorImpl<const Instruction *> &AliveSuccessors) { 4696 bool UsedAssumedInformation = 4697 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors); 4698 4699 // First, determine if we can change an invoke to a call assuming the 4700 // callee is nounwind. This is not possible if the personality of the 4701 // function allows to catch asynchronous exceptions. 4702 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) { 4703 AliveSuccessors.push_back(&II.getUnwindDest()->front()); 4704 } else { 4705 const IRPosition &IPos = IRPosition::callsite_function(II); 4706 4707 bool IsKnownNoUnwind; 4708 if (AA::hasAssumedIRAttr<Attribute::NoUnwind>( 4709 A, &AA, IPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) { 4710 UsedAssumedInformation |= !IsKnownNoUnwind; 4711 } else { 4712 AliveSuccessors.push_back(&II.getUnwindDest()->front()); 4713 } 4714 } 4715 return UsedAssumedInformation; 4716 } 4717 4718 static bool 4719 identifyAliveSuccessors(Attributor &A, const BranchInst &BI, 4720 AbstractAttribute &AA, 4721 SmallVectorImpl<const Instruction *> &AliveSuccessors) { 4722 bool UsedAssumedInformation = false; 4723 if (BI.getNumSuccessors() == 1) { 4724 AliveSuccessors.push_back(&BI.getSuccessor(0)->front()); 4725 } else { 4726 std::optional<Constant *> C = 4727 A.getAssumedConstant(*BI.getCondition(), AA, UsedAssumedInformation); 4728 if (!C || isa_and_nonnull<UndefValue>(*C)) { 4729 // No value yet, assume both edges are dead. 4730 } else if (isa_and_nonnull<ConstantInt>(*C)) { 4731 const BasicBlock *SuccBB = 4732 BI.getSuccessor(1 - cast<ConstantInt>(*C)->getValue().getZExtValue()); 4733 AliveSuccessors.push_back(&SuccBB->front()); 4734 } else { 4735 AliveSuccessors.push_back(&BI.getSuccessor(0)->front()); 4736 AliveSuccessors.push_back(&BI.getSuccessor(1)->front()); 4737 UsedAssumedInformation = false; 4738 } 4739 } 4740 return UsedAssumedInformation; 4741 } 4742 4743 static bool 4744 identifyAliveSuccessors(Attributor &A, const SwitchInst &SI, 4745 AbstractAttribute &AA, 4746 SmallVectorImpl<const Instruction *> &AliveSuccessors) { 4747 bool UsedAssumedInformation = false; 4748 SmallVector<AA::ValueAndContext> Values; 4749 if (!A.getAssumedSimplifiedValues(IRPosition::value(*SI.getCondition()), &AA, 4750 Values, AA::AnyScope, 4751 UsedAssumedInformation)) { 4752 // Something went wrong, assume all successors are live. 4753 for (const BasicBlock *SuccBB : successors(SI.getParent())) 4754 AliveSuccessors.push_back(&SuccBB->front()); 4755 return false; 4756 } 4757 4758 if (Values.empty() || 4759 (Values.size() == 1 && 4760 isa_and_nonnull<UndefValue>(Values.front().getValue()))) { 4761 // No valid value yet, assume all edges are dead. 4762 return UsedAssumedInformation; 4763 } 4764 4765 Type &Ty = *SI.getCondition()->getType(); 4766 SmallPtrSet<ConstantInt *, 8> Constants; 4767 auto CheckForConstantInt = [&](Value *V) { 4768 if (auto *CI = dyn_cast_if_present<ConstantInt>(AA::getWithType(*V, Ty))) { 4769 Constants.insert(CI); 4770 return true; 4771 } 4772 return false; 4773 }; 4774 4775 if (!all_of(Values, [&](AA::ValueAndContext &VAC) { 4776 return CheckForConstantInt(VAC.getValue()); 4777 })) { 4778 for (const BasicBlock *SuccBB : successors(SI.getParent())) 4779 AliveSuccessors.push_back(&SuccBB->front()); 4780 return UsedAssumedInformation; 4781 } 4782 4783 unsigned MatchedCases = 0; 4784 for (const auto &CaseIt : SI.cases()) { 4785 if (Constants.count(CaseIt.getCaseValue())) { 4786 ++MatchedCases; 4787 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front()); 4788 } 4789 } 4790 4791 // If all potential values have been matched, we will not visit the default 4792 // case. 4793 if (MatchedCases < Constants.size()) 4794 AliveSuccessors.push_back(&SI.getDefaultDest()->front()); 4795 return UsedAssumedInformation; 4796 } 4797 4798 ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) { 4799 ChangeStatus Change = ChangeStatus::UNCHANGED; 4800 4801 if (AssumedLiveBlocks.empty()) { 4802 if (isAssumedDeadInternalFunction(A)) 4803 return ChangeStatus::UNCHANGED; 4804 4805 Function *F = getAnchorScope(); 4806 ToBeExploredFrom.insert(&F->getEntryBlock().front()); 4807 assumeLive(A, F->getEntryBlock()); 4808 Change = ChangeStatus::CHANGED; 4809 } 4810 4811 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/" 4812 << getAnchorScope()->size() << "] BBs and " 4813 << ToBeExploredFrom.size() << " exploration points and " 4814 << KnownDeadEnds.size() << " known dead ends\n"); 4815 4816 // Copy and clear the list of instructions we need to explore from. It is 4817 // refilled with instructions the next update has to look at. 4818 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(), 4819 ToBeExploredFrom.end()); 4820 decltype(ToBeExploredFrom) NewToBeExploredFrom; 4821 4822 SmallVector<const Instruction *, 8> AliveSuccessors; 4823 while (!Worklist.empty()) { 4824 const Instruction *I = Worklist.pop_back_val(); 4825 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n"); 4826 4827 // Fast forward for uninteresting instructions. We could look for UB here 4828 // though. 4829 while (!I->isTerminator() && !isa<CallBase>(I)) 4830 I = I->getNextNode(); 4831 4832 AliveSuccessors.clear(); 4833 4834 bool UsedAssumedInformation = false; 4835 switch (I->getOpcode()) { 4836 // TODO: look for (assumed) UB to backwards propagate "deadness". 4837 default: 4838 assert(I->isTerminator() && 4839 "Expected non-terminators to be handled already!"); 4840 for (const BasicBlock *SuccBB : successors(I->getParent())) 4841 AliveSuccessors.push_back(&SuccBB->front()); 4842 break; 4843 case Instruction::Call: 4844 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I), 4845 *this, AliveSuccessors); 4846 break; 4847 case Instruction::Invoke: 4848 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I), 4849 *this, AliveSuccessors); 4850 break; 4851 case Instruction::Br: 4852 UsedAssumedInformation = identifyAliveSuccessors(A, cast<BranchInst>(*I), 4853 *this, AliveSuccessors); 4854 break; 4855 case Instruction::Switch: 4856 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I), 4857 *this, AliveSuccessors); 4858 break; 4859 } 4860 4861 if (UsedAssumedInformation) { 4862 NewToBeExploredFrom.insert(I); 4863 } else if (AliveSuccessors.empty() || 4864 (I->isTerminator() && 4865 AliveSuccessors.size() < I->getNumSuccessors())) { 4866 if (KnownDeadEnds.insert(I)) 4867 Change = ChangeStatus::CHANGED; 4868 } 4869 4870 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: " 4871 << AliveSuccessors.size() << " UsedAssumedInformation: " 4872 << UsedAssumedInformation << "\n"); 4873 4874 for (const Instruction *AliveSuccessor : AliveSuccessors) { 4875 if (!I->isTerminator()) { 4876 assert(AliveSuccessors.size() == 1 && 4877 "Non-terminator expected to have a single successor!"); 4878 Worklist.push_back(AliveSuccessor); 4879 } else { 4880 // record the assumed live edge 4881 auto Edge = std::make_pair(I->getParent(), AliveSuccessor->getParent()); 4882 if (AssumedLiveEdges.insert(Edge).second) 4883 Change = ChangeStatus::CHANGED; 4884 if (assumeLive(A, *AliveSuccessor->getParent())) 4885 Worklist.push_back(AliveSuccessor); 4886 } 4887 } 4888 } 4889 4890 // Check if the content of ToBeExploredFrom changed, ignore the order. 4891 if (NewToBeExploredFrom.size() != ToBeExploredFrom.size() || 4892 llvm::any_of(NewToBeExploredFrom, [&](const Instruction *I) { 4893 return !ToBeExploredFrom.count(I); 4894 })) { 4895 Change = ChangeStatus::CHANGED; 4896 ToBeExploredFrom = std::move(NewToBeExploredFrom); 4897 } 4898 4899 // If we know everything is live there is no need to query for liveness. 4900 // Instead, indicating a pessimistic fixpoint will cause the state to be 4901 // "invalid" and all queries to be answered conservatively without lookups. 4902 // To be in this state we have to (1) finished the exploration and (3) not 4903 // discovered any non-trivial dead end and (2) not ruled unreachable code 4904 // dead. 4905 if (ToBeExploredFrom.empty() && 4906 getAnchorScope()->size() == AssumedLiveBlocks.size() && 4907 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) { 4908 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0; 4909 })) 4910 return indicatePessimisticFixpoint(); 4911 return Change; 4912 } 4913 4914 /// Liveness information for a call sites. 4915 struct AAIsDeadCallSite final : AAIsDeadFunction { 4916 AAIsDeadCallSite(const IRPosition &IRP, Attributor &A) 4917 : AAIsDeadFunction(IRP, A) {} 4918 4919 /// See AbstractAttribute::initialize(...). 4920 void initialize(Attributor &A) override { 4921 // TODO: Once we have call site specific value information we can provide 4922 // call site specific liveness information and then it makes 4923 // sense to specialize attributes for call sites instead of 4924 // redirecting requests to the callee. 4925 llvm_unreachable("Abstract attributes for liveness are not " 4926 "supported for call sites yet!"); 4927 } 4928 4929 /// See AbstractAttribute::updateImpl(...). 4930 ChangeStatus updateImpl(Attributor &A) override { 4931 return indicatePessimisticFixpoint(); 4932 } 4933 4934 /// See AbstractAttribute::trackStatistics() 4935 void trackStatistics() const override {} 4936 }; 4937 } // namespace 4938 4939 /// -------------------- Dereferenceable Argument Attribute -------------------- 4940 4941 namespace { 4942 struct AADereferenceableImpl : AADereferenceable { 4943 AADereferenceableImpl(const IRPosition &IRP, Attributor &A) 4944 : AADereferenceable(IRP, A) {} 4945 using StateType = DerefState; 4946 4947 /// See AbstractAttribute::initialize(...). 4948 void initialize(Attributor &A) override { 4949 Value &V = *getAssociatedValue().stripPointerCasts(); 4950 SmallVector<Attribute, 4> Attrs; 4951 A.getAttrs(getIRPosition(), 4952 {Attribute::Dereferenceable, Attribute::DereferenceableOrNull}, 4953 Attrs, /* IgnoreSubsumingPositions */ false); 4954 for (const Attribute &Attr : Attrs) 4955 takeKnownDerefBytesMaximum(Attr.getValueAsInt()); 4956 4957 // Ensure we initialize the non-null AA (if necessary). 4958 bool IsKnownNonNull; 4959 AA::hasAssumedIRAttr<Attribute::NonNull>( 4960 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNonNull); 4961 4962 bool CanBeNull, CanBeFreed; 4963 takeKnownDerefBytesMaximum(V.getPointerDereferenceableBytes( 4964 A.getDataLayout(), CanBeNull, CanBeFreed)); 4965 4966 if (Instruction *CtxI = getCtxI()) 4967 followUsesInMBEC(*this, A, getState(), *CtxI); 4968 } 4969 4970 /// See AbstractAttribute::getState() 4971 /// { 4972 StateType &getState() override { return *this; } 4973 const StateType &getState() const override { return *this; } 4974 /// } 4975 4976 /// Helper function for collecting accessed bytes in must-be-executed-context 4977 void addAccessedBytesForUse(Attributor &A, const Use *U, const Instruction *I, 4978 DerefState &State) { 4979 const Value *UseV = U->get(); 4980 if (!UseV->getType()->isPointerTy()) 4981 return; 4982 4983 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(I); 4984 if (!Loc || Loc->Ptr != UseV || !Loc->Size.isPrecise() || I->isVolatile()) 4985 return; 4986 4987 int64_t Offset; 4988 const Value *Base = GetPointerBaseWithConstantOffset( 4989 Loc->Ptr, Offset, A.getDataLayout(), /*AllowNonInbounds*/ true); 4990 if (Base && Base == &getAssociatedValue()) 4991 State.addAccessedBytes(Offset, Loc->Size.getValue()); 4992 } 4993 4994 /// See followUsesInMBEC 4995 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I, 4996 AADereferenceable::StateType &State) { 4997 bool IsNonNull = false; 4998 bool TrackUse = false; 4999 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse( 5000 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse); 5001 LLVM_DEBUG(dbgs() << "[AADereferenceable] Deref bytes: " << DerefBytes 5002 << " for instruction " << *I << "\n"); 5003 5004 addAccessedBytesForUse(A, U, I, State); 5005 State.takeKnownDerefBytesMaximum(DerefBytes); 5006 return TrackUse; 5007 } 5008 5009 /// See AbstractAttribute::manifest(...). 5010 ChangeStatus manifest(Attributor &A) override { 5011 ChangeStatus Change = AADereferenceable::manifest(A); 5012 bool IsKnownNonNull; 5013 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>( 5014 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull); 5015 if (IsAssumedNonNull && 5016 A.hasAttr(getIRPosition(), Attribute::DereferenceableOrNull)) { 5017 A.removeAttrs(getIRPosition(), {Attribute::DereferenceableOrNull}); 5018 return ChangeStatus::CHANGED; 5019 } 5020 return Change; 5021 } 5022 5023 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, 5024 SmallVectorImpl<Attribute> &Attrs) const override { 5025 // TODO: Add *_globally support 5026 bool IsKnownNonNull; 5027 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>( 5028 A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull); 5029 if (IsAssumedNonNull) 5030 Attrs.emplace_back(Attribute::getWithDereferenceableBytes( 5031 Ctx, getAssumedDereferenceableBytes())); 5032 else 5033 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes( 5034 Ctx, getAssumedDereferenceableBytes())); 5035 } 5036 5037 /// See AbstractAttribute::getAsStr(). 5038 const std::string getAsStr(Attributor *A) const override { 5039 if (!getAssumedDereferenceableBytes()) 5040 return "unknown-dereferenceable"; 5041 bool IsKnownNonNull; 5042 bool IsAssumedNonNull = false; 5043 if (A) 5044 IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>( 5045 *A, this, getIRPosition(), DepClassTy::NONE, IsKnownNonNull); 5046 return std::string("dereferenceable") + 5047 (IsAssumedNonNull ? "" : "_or_null") + 5048 (isAssumedGlobal() ? "_globally" : "") + "<" + 5049 std::to_string(getKnownDereferenceableBytes()) + "-" + 5050 std::to_string(getAssumedDereferenceableBytes()) + ">" + 5051 (!A ? " [non-null is unknown]" : ""); 5052 } 5053 }; 5054 5055 /// Dereferenceable attribute for a floating value. 5056 struct AADereferenceableFloating : AADereferenceableImpl { 5057 AADereferenceableFloating(const IRPosition &IRP, Attributor &A) 5058 : AADereferenceableImpl(IRP, A) {} 5059 5060 /// See AbstractAttribute::updateImpl(...). 5061 ChangeStatus updateImpl(Attributor &A) override { 5062 bool Stripped; 5063 bool UsedAssumedInformation = false; 5064 SmallVector<AA::ValueAndContext> Values; 5065 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values, 5066 AA::AnyScope, UsedAssumedInformation)) { 5067 Values.push_back({getAssociatedValue(), getCtxI()}); 5068 Stripped = false; 5069 } else { 5070 Stripped = Values.size() != 1 || 5071 Values.front().getValue() != &getAssociatedValue(); 5072 } 5073 5074 const DataLayout &DL = A.getDataLayout(); 5075 DerefState T; 5076 5077 auto VisitValueCB = [&](const Value &V) -> bool { 5078 unsigned IdxWidth = 5079 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace()); 5080 APInt Offset(IdxWidth, 0); 5081 const Value *Base = stripAndAccumulateOffsets( 5082 A, *this, &V, DL, Offset, /* GetMinOffset */ false, 5083 /* AllowNonInbounds */ true); 5084 5085 const auto *AA = A.getAAFor<AADereferenceable>( 5086 *this, IRPosition::value(*Base), DepClassTy::REQUIRED); 5087 int64_t DerefBytes = 0; 5088 if (!AA || (!Stripped && this == AA)) { 5089 // Use IR information if we did not strip anything. 5090 // TODO: track globally. 5091 bool CanBeNull, CanBeFreed; 5092 DerefBytes = 5093 Base->getPointerDereferenceableBytes(DL, CanBeNull, CanBeFreed); 5094 T.GlobalState.indicatePessimisticFixpoint(); 5095 } else { 5096 const DerefState &DS = AA->getState(); 5097 DerefBytes = DS.DerefBytesState.getAssumed(); 5098 T.GlobalState &= DS.GlobalState; 5099 } 5100 5101 // For now we do not try to "increase" dereferenceability due to negative 5102 // indices as we first have to come up with code to deal with loops and 5103 // for overflows of the dereferenceable bytes. 5104 int64_t OffsetSExt = Offset.getSExtValue(); 5105 if (OffsetSExt < 0) 5106 OffsetSExt = 0; 5107 5108 T.takeAssumedDerefBytesMinimum( 5109 std::max(int64_t(0), DerefBytes - OffsetSExt)); 5110 5111 if (this == AA) { 5112 if (!Stripped) { 5113 // If nothing was stripped IR information is all we got. 5114 T.takeKnownDerefBytesMaximum( 5115 std::max(int64_t(0), DerefBytes - OffsetSExt)); 5116 T.indicatePessimisticFixpoint(); 5117 } else if (OffsetSExt > 0) { 5118 // If something was stripped but there is circular reasoning we look 5119 // for the offset. If it is positive we basically decrease the 5120 // dereferenceable bytes in a circular loop now, which will simply 5121 // drive them down to the known value in a very slow way which we 5122 // can accelerate. 5123 T.indicatePessimisticFixpoint(); 5124 } 5125 } 5126 5127 return T.isValidState(); 5128 }; 5129 5130 for (const auto &VAC : Values) 5131 if (!VisitValueCB(*VAC.getValue())) 5132 return indicatePessimisticFixpoint(); 5133 5134 return clampStateAndIndicateChange(getState(), T); 5135 } 5136 5137 /// See AbstractAttribute::trackStatistics() 5138 void trackStatistics() const override { 5139 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable) 5140 } 5141 }; 5142 5143 /// Dereferenceable attribute for a return value. 5144 struct AADereferenceableReturned final 5145 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> { 5146 using Base = 5147 AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>; 5148 AADereferenceableReturned(const IRPosition &IRP, Attributor &A) 5149 : Base(IRP, A) {} 5150 5151 /// See AbstractAttribute::trackStatistics() 5152 void trackStatistics() const override { 5153 STATS_DECLTRACK_FNRET_ATTR(dereferenceable) 5154 } 5155 }; 5156 5157 /// Dereferenceable attribute for an argument 5158 struct AADereferenceableArgument final 5159 : AAArgumentFromCallSiteArguments<AADereferenceable, 5160 AADereferenceableImpl> { 5161 using Base = 5162 AAArgumentFromCallSiteArguments<AADereferenceable, AADereferenceableImpl>; 5163 AADereferenceableArgument(const IRPosition &IRP, Attributor &A) 5164 : Base(IRP, A) {} 5165 5166 /// See AbstractAttribute::trackStatistics() 5167 void trackStatistics() const override { 5168 STATS_DECLTRACK_ARG_ATTR(dereferenceable) 5169 } 5170 }; 5171 5172 /// Dereferenceable attribute for a call site argument. 5173 struct AADereferenceableCallSiteArgument final : AADereferenceableFloating { 5174 AADereferenceableCallSiteArgument(const IRPosition &IRP, Attributor &A) 5175 : AADereferenceableFloating(IRP, A) {} 5176 5177 /// See AbstractAttribute::trackStatistics() 5178 void trackStatistics() const override { 5179 STATS_DECLTRACK_CSARG_ATTR(dereferenceable) 5180 } 5181 }; 5182 5183 /// Dereferenceable attribute deduction for a call site return value. 5184 struct AADereferenceableCallSiteReturned final 5185 : AACalleeToCallSite<AADereferenceable, AADereferenceableImpl> { 5186 using Base = AACalleeToCallSite<AADereferenceable, AADereferenceableImpl>; 5187 AADereferenceableCallSiteReturned(const IRPosition &IRP, Attributor &A) 5188 : Base(IRP, A) {} 5189 5190 /// See AbstractAttribute::trackStatistics() 5191 void trackStatistics() const override { 5192 STATS_DECLTRACK_CS_ATTR(dereferenceable); 5193 } 5194 }; 5195 } // namespace 5196 5197 // ------------------------ Align Argument Attribute ------------------------ 5198 5199 namespace { 5200 static unsigned getKnownAlignForUse(Attributor &A, AAAlign &QueryingAA, 5201 Value &AssociatedValue, const Use *U, 5202 const Instruction *I, bool &TrackUse) { 5203 // We need to follow common pointer manipulation uses to the accesses they 5204 // feed into. 5205 if (isa<CastInst>(I)) { 5206 // Follow all but ptr2int casts. 5207 TrackUse = !isa<PtrToIntInst>(I); 5208 return 0; 5209 } 5210 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) { 5211 if (GEP->hasAllConstantIndices()) 5212 TrackUse = true; 5213 return 0; 5214 } 5215 5216 MaybeAlign MA; 5217 if (const auto *CB = dyn_cast<CallBase>(I)) { 5218 if (CB->isBundleOperand(U) || CB->isCallee(U)) 5219 return 0; 5220 5221 unsigned ArgNo = CB->getArgOperandNo(U); 5222 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo); 5223 // As long as we only use known information there is no need to track 5224 // dependences here. 5225 auto *AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP, DepClassTy::NONE); 5226 if (AlignAA) 5227 MA = MaybeAlign(AlignAA->getKnownAlign()); 5228 } 5229 5230 const DataLayout &DL = A.getDataLayout(); 5231 const Value *UseV = U->get(); 5232 if (auto *SI = dyn_cast<StoreInst>(I)) { 5233 if (SI->getPointerOperand() == UseV) 5234 MA = SI->getAlign(); 5235 } else if (auto *LI = dyn_cast<LoadInst>(I)) { 5236 if (LI->getPointerOperand() == UseV) 5237 MA = LI->getAlign(); 5238 } else if (auto *AI = dyn_cast<AtomicRMWInst>(I)) { 5239 if (AI->getPointerOperand() == UseV) 5240 MA = AI->getAlign(); 5241 } else if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I)) { 5242 if (AI->getPointerOperand() == UseV) 5243 MA = AI->getAlign(); 5244 } 5245 5246 if (!MA || *MA <= QueryingAA.getKnownAlign()) 5247 return 0; 5248 5249 unsigned Alignment = MA->value(); 5250 int64_t Offset; 5251 5252 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) { 5253 if (Base == &AssociatedValue) { 5254 // BasePointerAddr + Offset = Alignment * Q for some integer Q. 5255 // So we can say that the maximum power of two which is a divisor of 5256 // gcd(Offset, Alignment) is an alignment. 5257 5258 uint32_t gcd = std::gcd(uint32_t(abs((int32_t)Offset)), Alignment); 5259 Alignment = llvm::bit_floor(gcd); 5260 } 5261 } 5262 5263 return Alignment; 5264 } 5265 5266 struct AAAlignImpl : AAAlign { 5267 AAAlignImpl(const IRPosition &IRP, Attributor &A) : AAAlign(IRP, A) {} 5268 5269 /// See AbstractAttribute::initialize(...). 5270 void initialize(Attributor &A) override { 5271 SmallVector<Attribute, 4> Attrs; 5272 A.getAttrs(getIRPosition(), {Attribute::Alignment}, Attrs); 5273 for (const Attribute &Attr : Attrs) 5274 takeKnownMaximum(Attr.getValueAsInt()); 5275 5276 Value &V = *getAssociatedValue().stripPointerCasts(); 5277 takeKnownMaximum(V.getPointerAlignment(A.getDataLayout()).value()); 5278 5279 if (Instruction *CtxI = getCtxI()) 5280 followUsesInMBEC(*this, A, getState(), *CtxI); 5281 } 5282 5283 /// See AbstractAttribute::manifest(...). 5284 ChangeStatus manifest(Attributor &A) override { 5285 ChangeStatus LoadStoreChanged = ChangeStatus::UNCHANGED; 5286 5287 // Check for users that allow alignment annotations. 5288 Value &AssociatedValue = getAssociatedValue(); 5289 for (const Use &U : AssociatedValue.uses()) { 5290 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) { 5291 if (SI->getPointerOperand() == &AssociatedValue) 5292 if (SI->getAlign() < getAssumedAlign()) { 5293 STATS_DECLTRACK(AAAlign, Store, 5294 "Number of times alignment added to a store"); 5295 SI->setAlignment(getAssumedAlign()); 5296 LoadStoreChanged = ChangeStatus::CHANGED; 5297 } 5298 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) { 5299 if (LI->getPointerOperand() == &AssociatedValue) 5300 if (LI->getAlign() < getAssumedAlign()) { 5301 LI->setAlignment(getAssumedAlign()); 5302 STATS_DECLTRACK(AAAlign, Load, 5303 "Number of times alignment added to a load"); 5304 LoadStoreChanged = ChangeStatus::CHANGED; 5305 } 5306 } 5307 } 5308 5309 ChangeStatus Changed = AAAlign::manifest(A); 5310 5311 Align InheritAlign = 5312 getAssociatedValue().getPointerAlignment(A.getDataLayout()); 5313 if (InheritAlign >= getAssumedAlign()) 5314 return LoadStoreChanged; 5315 return Changed | LoadStoreChanged; 5316 } 5317 5318 // TODO: Provide a helper to determine the implied ABI alignment and check in 5319 // the existing manifest method and a new one for AAAlignImpl that value 5320 // to avoid making the alignment explicit if it did not improve. 5321 5322 /// See AbstractAttribute::getDeducedAttributes 5323 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, 5324 SmallVectorImpl<Attribute> &Attrs) const override { 5325 if (getAssumedAlign() > 1) 5326 Attrs.emplace_back( 5327 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign()))); 5328 } 5329 5330 /// See followUsesInMBEC 5331 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I, 5332 AAAlign::StateType &State) { 5333 bool TrackUse = false; 5334 5335 unsigned int KnownAlign = 5336 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse); 5337 State.takeKnownMaximum(KnownAlign); 5338 5339 return TrackUse; 5340 } 5341 5342 /// See AbstractAttribute::getAsStr(). 5343 const std::string getAsStr(Attributor *A) const override { 5344 return "align<" + std::to_string(getKnownAlign().value()) + "-" + 5345 std::to_string(getAssumedAlign().value()) + ">"; 5346 } 5347 }; 5348 5349 /// Align attribute for a floating value. 5350 struct AAAlignFloating : AAAlignImpl { 5351 AAAlignFloating(const IRPosition &IRP, Attributor &A) : AAAlignImpl(IRP, A) {} 5352 5353 /// See AbstractAttribute::updateImpl(...). 5354 ChangeStatus updateImpl(Attributor &A) override { 5355 const DataLayout &DL = A.getDataLayout(); 5356 5357 bool Stripped; 5358 bool UsedAssumedInformation = false; 5359 SmallVector<AA::ValueAndContext> Values; 5360 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values, 5361 AA::AnyScope, UsedAssumedInformation)) { 5362 Values.push_back({getAssociatedValue(), getCtxI()}); 5363 Stripped = false; 5364 } else { 5365 Stripped = Values.size() != 1 || 5366 Values.front().getValue() != &getAssociatedValue(); 5367 } 5368 5369 StateType T; 5370 auto VisitValueCB = [&](Value &V) -> bool { 5371 if (isa<UndefValue>(V) || isa<ConstantPointerNull>(V)) 5372 return true; 5373 const auto *AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V), 5374 DepClassTy::REQUIRED); 5375 if (!AA || (!Stripped && this == AA)) { 5376 int64_t Offset; 5377 unsigned Alignment = 1; 5378 if (const Value *Base = 5379 GetPointerBaseWithConstantOffset(&V, Offset, DL)) { 5380 // TODO: Use AAAlign for the base too. 5381 Align PA = Base->getPointerAlignment(DL); 5382 // BasePointerAddr + Offset = Alignment * Q for some integer Q. 5383 // So we can say that the maximum power of two which is a divisor of 5384 // gcd(Offset, Alignment) is an alignment. 5385 5386 uint32_t gcd = 5387 std::gcd(uint32_t(abs((int32_t)Offset)), uint32_t(PA.value())); 5388 Alignment = llvm::bit_floor(gcd); 5389 } else { 5390 Alignment = V.getPointerAlignment(DL).value(); 5391 } 5392 // Use only IR information if we did not strip anything. 5393 T.takeKnownMaximum(Alignment); 5394 T.indicatePessimisticFixpoint(); 5395 } else { 5396 // Use abstract attribute information. 5397 const AAAlign::StateType &DS = AA->getState(); 5398 T ^= DS; 5399 } 5400 return T.isValidState(); 5401 }; 5402 5403 for (const auto &VAC : Values) { 5404 if (!VisitValueCB(*VAC.getValue())) 5405 return indicatePessimisticFixpoint(); 5406 } 5407 5408 // TODO: If we know we visited all incoming values, thus no are assumed 5409 // dead, we can take the known information from the state T. 5410 return clampStateAndIndicateChange(getState(), T); 5411 } 5412 5413 /// See AbstractAttribute::trackStatistics() 5414 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) } 5415 }; 5416 5417 /// Align attribute for function return value. 5418 struct AAAlignReturned final 5419 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> { 5420 using Base = AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>; 5421 AAAlignReturned(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {} 5422 5423 /// See AbstractAttribute::trackStatistics() 5424 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) } 5425 }; 5426 5427 /// Align attribute for function argument. 5428 struct AAAlignArgument final 5429 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> { 5430 using Base = AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>; 5431 AAAlignArgument(const IRPosition &IRP, Attributor &A) : Base(IRP, A) {} 5432 5433 /// See AbstractAttribute::manifest(...). 5434 ChangeStatus manifest(Attributor &A) override { 5435 // If the associated argument is involved in a must-tail call we give up 5436 // because we would need to keep the argument alignments of caller and 5437 // callee in-sync. Just does not seem worth the trouble right now. 5438 if (A.getInfoCache().isInvolvedInMustTailCall(*getAssociatedArgument())) 5439 return ChangeStatus::UNCHANGED; 5440 return Base::manifest(A); 5441 } 5442 5443 /// See AbstractAttribute::trackStatistics() 5444 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) } 5445 }; 5446 5447 struct AAAlignCallSiteArgument final : AAAlignFloating { 5448 AAAlignCallSiteArgument(const IRPosition &IRP, Attributor &A) 5449 : AAAlignFloating(IRP, A) {} 5450 5451 /// See AbstractAttribute::manifest(...). 5452 ChangeStatus manifest(Attributor &A) override { 5453 // If the associated argument is involved in a must-tail call we give up 5454 // because we would need to keep the argument alignments of caller and 5455 // callee in-sync. Just does not seem worth the trouble right now. 5456 if (Argument *Arg = getAssociatedArgument()) 5457 if (A.getInfoCache().isInvolvedInMustTailCall(*Arg)) 5458 return ChangeStatus::UNCHANGED; 5459 ChangeStatus Changed = AAAlignImpl::manifest(A); 5460 Align InheritAlign = 5461 getAssociatedValue().getPointerAlignment(A.getDataLayout()); 5462 if (InheritAlign >= getAssumedAlign()) 5463 Changed = ChangeStatus::UNCHANGED; 5464 return Changed; 5465 } 5466 5467 /// See AbstractAttribute::updateImpl(Attributor &A). 5468 ChangeStatus updateImpl(Attributor &A) override { 5469 ChangeStatus Changed = AAAlignFloating::updateImpl(A); 5470 if (Argument *Arg = getAssociatedArgument()) { 5471 // We only take known information from the argument 5472 // so we do not need to track a dependence. 5473 const auto *ArgAlignAA = A.getAAFor<AAAlign>( 5474 *this, IRPosition::argument(*Arg), DepClassTy::NONE); 5475 if (ArgAlignAA) 5476 takeKnownMaximum(ArgAlignAA->getKnownAlign().value()); 5477 } 5478 return Changed; 5479 } 5480 5481 /// See AbstractAttribute::trackStatistics() 5482 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) } 5483 }; 5484 5485 /// Align attribute deduction for a call site return value. 5486 struct AAAlignCallSiteReturned final 5487 : AACalleeToCallSite<AAAlign, AAAlignImpl> { 5488 using Base = AACalleeToCallSite<AAAlign, AAAlignImpl>; 5489 AAAlignCallSiteReturned(const IRPosition &IRP, Attributor &A) 5490 : Base(IRP, A) {} 5491 5492 /// See AbstractAttribute::trackStatistics() 5493 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); } 5494 }; 5495 } // namespace 5496 5497 /// ------------------ Function No-Return Attribute ---------------------------- 5498 namespace { 5499 struct AANoReturnImpl : public AANoReturn { 5500 AANoReturnImpl(const IRPosition &IRP, Attributor &A) : AANoReturn(IRP, A) {} 5501 5502 /// See AbstractAttribute::initialize(...). 5503 void initialize(Attributor &A) override { 5504 bool IsKnown; 5505 assert(!AA::hasAssumedIRAttr<Attribute::NoReturn>( 5506 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown)); 5507 (void)IsKnown; 5508 } 5509 5510 /// See AbstractAttribute::getAsStr(). 5511 const std::string getAsStr(Attributor *A) const override { 5512 return getAssumed() ? "noreturn" : "may-return"; 5513 } 5514 5515 /// See AbstractAttribute::updateImpl(Attributor &A). 5516 ChangeStatus updateImpl(Attributor &A) override { 5517 auto CheckForNoReturn = [](Instruction &) { return false; }; 5518 bool UsedAssumedInformation = false; 5519 if (!A.checkForAllInstructions(CheckForNoReturn, *this, 5520 {(unsigned)Instruction::Ret}, 5521 UsedAssumedInformation)) 5522 return indicatePessimisticFixpoint(); 5523 return ChangeStatus::UNCHANGED; 5524 } 5525 }; 5526 5527 struct AANoReturnFunction final : AANoReturnImpl { 5528 AANoReturnFunction(const IRPosition &IRP, Attributor &A) 5529 : AANoReturnImpl(IRP, A) {} 5530 5531 /// See AbstractAttribute::trackStatistics() 5532 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) } 5533 }; 5534 5535 /// NoReturn attribute deduction for a call sites. 5536 struct AANoReturnCallSite final 5537 : AACalleeToCallSite<AANoReturn, AANoReturnImpl> { 5538 AANoReturnCallSite(const IRPosition &IRP, Attributor &A) 5539 : AACalleeToCallSite<AANoReturn, AANoReturnImpl>(IRP, A) {} 5540 5541 /// See AbstractAttribute::trackStatistics() 5542 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); } 5543 }; 5544 } // namespace 5545 5546 /// ----------------------- Instance Info --------------------------------- 5547 5548 namespace { 5549 /// A class to hold the state of for no-capture attributes. 5550 struct AAInstanceInfoImpl : public AAInstanceInfo { 5551 AAInstanceInfoImpl(const IRPosition &IRP, Attributor &A) 5552 : AAInstanceInfo(IRP, A) {} 5553 5554 /// See AbstractAttribute::initialize(...). 5555 void initialize(Attributor &A) override { 5556 Value &V = getAssociatedValue(); 5557 if (auto *C = dyn_cast<Constant>(&V)) { 5558 if (C->isThreadDependent()) 5559 indicatePessimisticFixpoint(); 5560 else 5561 indicateOptimisticFixpoint(); 5562 return; 5563 } 5564 if (auto *CB = dyn_cast<CallBase>(&V)) 5565 if (CB->arg_size() == 0 && !CB->mayHaveSideEffects() && 5566 !CB->mayReadFromMemory()) { 5567 indicateOptimisticFixpoint(); 5568 return; 5569 } 5570 if (auto *I = dyn_cast<Instruction>(&V)) { 5571 const auto *CI = 5572 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>( 5573 *I->getFunction()); 5574 if (mayBeInCycle(CI, I, /* HeaderOnly */ false)) { 5575 indicatePessimisticFixpoint(); 5576 return; 5577 } 5578 } 5579 } 5580 5581 /// See AbstractAttribute::updateImpl(...). 5582 ChangeStatus updateImpl(Attributor &A) override { 5583 ChangeStatus Changed = ChangeStatus::UNCHANGED; 5584 5585 Value &V = getAssociatedValue(); 5586 const Function *Scope = nullptr; 5587 if (auto *I = dyn_cast<Instruction>(&V)) 5588 Scope = I->getFunction(); 5589 if (auto *A = dyn_cast<Argument>(&V)) { 5590 Scope = A->getParent(); 5591 if (!Scope->hasLocalLinkage()) 5592 return Changed; 5593 } 5594 if (!Scope) 5595 return indicateOptimisticFixpoint(); 5596 5597 bool IsKnownNoRecurse; 5598 if (AA::hasAssumedIRAttr<Attribute::NoRecurse>( 5599 A, this, IRPosition::function(*Scope), DepClassTy::OPTIONAL, 5600 IsKnownNoRecurse)) 5601 return Changed; 5602 5603 auto UsePred = [&](const Use &U, bool &Follow) { 5604 const Instruction *UserI = dyn_cast<Instruction>(U.getUser()); 5605 if (!UserI || isa<GetElementPtrInst>(UserI) || isa<CastInst>(UserI) || 5606 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) { 5607 Follow = true; 5608 return true; 5609 } 5610 if (isa<LoadInst>(UserI) || isa<CmpInst>(UserI) || 5611 (isa<StoreInst>(UserI) && 5612 cast<StoreInst>(UserI)->getValueOperand() != U.get())) 5613 return true; 5614 if (auto *CB = dyn_cast<CallBase>(UserI)) { 5615 // This check is not guaranteeing uniqueness but for now that we cannot 5616 // end up with two versions of \p U thinking it was one. 5617 auto *Callee = dyn_cast_if_present<Function>(CB->getCalledOperand()); 5618 if (!Callee || !Callee->hasLocalLinkage()) 5619 return true; 5620 if (!CB->isArgOperand(&U)) 5621 return false; 5622 const auto *ArgInstanceInfoAA = A.getAAFor<AAInstanceInfo>( 5623 *this, IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U)), 5624 DepClassTy::OPTIONAL); 5625 if (!ArgInstanceInfoAA || 5626 !ArgInstanceInfoAA->isAssumedUniqueForAnalysis()) 5627 return false; 5628 // If this call base might reach the scope again we might forward the 5629 // argument back here. This is very conservative. 5630 if (AA::isPotentiallyReachable( 5631 A, *CB, *Scope, *this, /* ExclusionSet */ nullptr, 5632 [Scope](const Function &Fn) { return &Fn != Scope; })) 5633 return false; 5634 return true; 5635 } 5636 return false; 5637 }; 5638 5639 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) { 5640 if (auto *SI = dyn_cast<StoreInst>(OldU.getUser())) { 5641 auto *Ptr = SI->getPointerOperand()->stripPointerCasts(); 5642 if ((isa<AllocaInst>(Ptr) || isNoAliasCall(Ptr)) && 5643 AA::isDynamicallyUnique(A, *this, *Ptr)) 5644 return true; 5645 } 5646 return false; 5647 }; 5648 5649 if (!A.checkForAllUses(UsePred, *this, V, /* CheckBBLivenessOnly */ true, 5650 DepClassTy::OPTIONAL, 5651 /* IgnoreDroppableUses */ true, EquivalentUseCB)) 5652 return indicatePessimisticFixpoint(); 5653 5654 return Changed; 5655 } 5656 5657 /// See AbstractState::getAsStr(). 5658 const std::string getAsStr(Attributor *A) const override { 5659 return isAssumedUniqueForAnalysis() ? "<unique [fAa]>" : "<unknown>"; 5660 } 5661 5662 /// See AbstractAttribute::trackStatistics() 5663 void trackStatistics() const override {} 5664 }; 5665 5666 /// InstanceInfo attribute for floating values. 5667 struct AAInstanceInfoFloating : AAInstanceInfoImpl { 5668 AAInstanceInfoFloating(const IRPosition &IRP, Attributor &A) 5669 : AAInstanceInfoImpl(IRP, A) {} 5670 }; 5671 5672 /// NoCapture attribute for function arguments. 5673 struct AAInstanceInfoArgument final : AAInstanceInfoFloating { 5674 AAInstanceInfoArgument(const IRPosition &IRP, Attributor &A) 5675 : AAInstanceInfoFloating(IRP, A) {} 5676 }; 5677 5678 /// InstanceInfo attribute for call site arguments. 5679 struct AAInstanceInfoCallSiteArgument final : AAInstanceInfoImpl { 5680 AAInstanceInfoCallSiteArgument(const IRPosition &IRP, Attributor &A) 5681 : AAInstanceInfoImpl(IRP, A) {} 5682 5683 /// See AbstractAttribute::updateImpl(...). 5684 ChangeStatus updateImpl(Attributor &A) override { 5685 // TODO: Once we have call site specific value information we can provide 5686 // call site specific liveness information and then it makes 5687 // sense to specialize attributes for call sites arguments instead of 5688 // redirecting requests to the callee argument. 5689 Argument *Arg = getAssociatedArgument(); 5690 if (!Arg) 5691 return indicatePessimisticFixpoint(); 5692 const IRPosition &ArgPos = IRPosition::argument(*Arg); 5693 auto *ArgAA = 5694 A.getAAFor<AAInstanceInfo>(*this, ArgPos, DepClassTy::REQUIRED); 5695 if (!ArgAA) 5696 return indicatePessimisticFixpoint(); 5697 return clampStateAndIndicateChange(getState(), ArgAA->getState()); 5698 } 5699 }; 5700 5701 /// InstanceInfo attribute for function return value. 5702 struct AAInstanceInfoReturned final : AAInstanceInfoImpl { 5703 AAInstanceInfoReturned(const IRPosition &IRP, Attributor &A) 5704 : AAInstanceInfoImpl(IRP, A) { 5705 llvm_unreachable("InstanceInfo is not applicable to function returns!"); 5706 } 5707 5708 /// See AbstractAttribute::initialize(...). 5709 void initialize(Attributor &A) override { 5710 llvm_unreachable("InstanceInfo is not applicable to function returns!"); 5711 } 5712 5713 /// See AbstractAttribute::updateImpl(...). 5714 ChangeStatus updateImpl(Attributor &A) override { 5715 llvm_unreachable("InstanceInfo is not applicable to function returns!"); 5716 } 5717 }; 5718 5719 /// InstanceInfo attribute deduction for a call site return value. 5720 struct AAInstanceInfoCallSiteReturned final : AAInstanceInfoFloating { 5721 AAInstanceInfoCallSiteReturned(const IRPosition &IRP, Attributor &A) 5722 : AAInstanceInfoFloating(IRP, A) {} 5723 }; 5724 } // namespace 5725 5726 /// ----------------------- Variable Capturing --------------------------------- 5727 bool AANoCapture::isImpliedByIR(Attributor &A, const IRPosition &IRP, 5728 Attribute::AttrKind ImpliedAttributeKind, 5729 bool IgnoreSubsumingPositions) { 5730 assert(ImpliedAttributeKind == Attribute::Captures && 5731 "Unexpected attribute kind"); 5732 Value &V = IRP.getAssociatedValue(); 5733 if (!IRP.isArgumentPosition()) 5734 return V.use_empty(); 5735 5736 // You cannot "capture" null in the default address space. 5737 // 5738 // FIXME: This should use NullPointerIsDefined to account for the function 5739 // attribute. 5740 if (isa<UndefValue>(V) || (isa<ConstantPointerNull>(V) && 5741 V.getType()->getPointerAddressSpace() == 0)) { 5742 return true; 5743 } 5744 5745 SmallVector<Attribute, 1> Attrs; 5746 A.getAttrs(IRP, {Attribute::Captures}, Attrs, 5747 /* IgnoreSubsumingPositions */ true); 5748 for (const Attribute &Attr : Attrs) 5749 if (capturesNothing(Attr.getCaptureInfo())) 5750 return true; 5751 5752 if (IRP.getPositionKind() == IRP_CALL_SITE_ARGUMENT) 5753 if (Argument *Arg = IRP.getAssociatedArgument()) { 5754 SmallVector<Attribute, 1> Attrs; 5755 A.getAttrs(IRPosition::argument(*Arg), 5756 {Attribute::Captures, Attribute::ByVal}, Attrs, 5757 /* IgnoreSubsumingPositions */ true); 5758 bool ArgNoCapture = any_of(Attrs, [](Attribute Attr) { 5759 return Attr.getKindAsEnum() == Attribute::ByVal || 5760 capturesNothing(Attr.getCaptureInfo()); 5761 }); 5762 if (ArgNoCapture) { 5763 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo( 5764 V.getContext(), CaptureInfo::none())); 5765 return true; 5766 } 5767 } 5768 5769 if (const Function *F = IRP.getAssociatedFunction()) { 5770 // Check what state the associated function can actually capture. 5771 AANoCapture::StateType State; 5772 determineFunctionCaptureCapabilities(IRP, *F, State); 5773 if (State.isKnown(NO_CAPTURE)) { 5774 A.manifestAttrs(IRP, Attribute::getWithCaptureInfo(V.getContext(), 5775 CaptureInfo::none())); 5776 return true; 5777 } 5778 } 5779 5780 return false; 5781 } 5782 5783 /// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known 5784 /// depending on the ability of the function associated with \p IRP to capture 5785 /// state in memory and through "returning/throwing", respectively. 5786 void AANoCapture::determineFunctionCaptureCapabilities(const IRPosition &IRP, 5787 const Function &F, 5788 BitIntegerState &State) { 5789 // TODO: Once we have memory behavior attributes we should use them here. 5790 5791 // If we know we cannot communicate or write to memory, we do not care about 5792 // ptr2int anymore. 5793 bool ReadOnly = F.onlyReadsMemory(); 5794 bool NoThrow = F.doesNotThrow(); 5795 bool IsVoidReturn = F.getReturnType()->isVoidTy(); 5796 if (ReadOnly && NoThrow && IsVoidReturn) { 5797 State.addKnownBits(NO_CAPTURE); 5798 return; 5799 } 5800 5801 // A function cannot capture state in memory if it only reads memory, it can 5802 // however return/throw state and the state might be influenced by the 5803 // pointer value, e.g., loading from a returned pointer might reveal a bit. 5804 if (ReadOnly) 5805 State.addKnownBits(NOT_CAPTURED_IN_MEM); 5806 5807 // A function cannot communicate state back if it does not through 5808 // exceptions and doesn not return values. 5809 if (NoThrow && IsVoidReturn) 5810 State.addKnownBits(NOT_CAPTURED_IN_RET); 5811 5812 // Check existing "returned" attributes. 5813 int ArgNo = IRP.getCalleeArgNo(); 5814 if (!NoThrow || ArgNo < 0 || 5815 !F.getAttributes().hasAttrSomewhere(Attribute::Returned)) 5816 return; 5817 5818 for (unsigned U = 0, E = F.arg_size(); U < E; ++U) 5819 if (F.hasParamAttribute(U, Attribute::Returned)) { 5820 if (U == unsigned(ArgNo)) 5821 State.removeAssumedBits(NOT_CAPTURED_IN_RET); 5822 else if (ReadOnly) 5823 State.addKnownBits(NO_CAPTURE); 5824 else 5825 State.addKnownBits(NOT_CAPTURED_IN_RET); 5826 break; 5827 } 5828 } 5829 5830 namespace { 5831 /// A class to hold the state of for no-capture attributes. 5832 struct AANoCaptureImpl : public AANoCapture { 5833 AANoCaptureImpl(const IRPosition &IRP, Attributor &A) : AANoCapture(IRP, A) {} 5834 5835 /// See AbstractAttribute::initialize(...). 5836 void initialize(Attributor &A) override { 5837 bool IsKnown; 5838 assert(!AA::hasAssumedIRAttr<Attribute::Captures>( 5839 A, nullptr, getIRPosition(), DepClassTy::NONE, IsKnown)); 5840 (void)IsKnown; 5841 } 5842 5843 /// See AbstractAttribute::updateImpl(...). 5844 ChangeStatus updateImpl(Attributor &A) override; 5845 5846 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...). 5847 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, 5848 SmallVectorImpl<Attribute> &Attrs) const override { 5849 if (!isAssumedNoCaptureMaybeReturned()) 5850 return; 5851 5852 if (isArgumentPosition()) { 5853 if (isAssumedNoCapture()) 5854 Attrs.emplace_back(Attribute::get(Ctx, Attribute::Captures)); 5855 else if (ManifestInternal) 5856 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned")); 5857 } 5858 } 5859 5860 /// See AbstractState::getAsStr(). 5861 const std::string getAsStr(Attributor *A) const override { 5862 if (isKnownNoCapture()) 5863 return "known not-captured"; 5864 if (isAssumedNoCapture()) 5865 return "assumed not-captured"; 5866 if (isKnownNoCaptureMaybeReturned()) 5867 return "known not-captured-maybe-returned"; 5868 if (isAssumedNoCaptureMaybeReturned()) 5869 return "assumed not-captured-maybe-returned"; 5870 return "assumed-captured"; 5871 } 5872 5873 /// Check the use \p U and update \p State accordingly. Return true if we 5874 /// should continue to update the state. 5875 bool checkUse(Attributor &A, AANoCapture::StateType &State, const Use &U, 5876 bool &Follow) { 5877 Instruction *UInst = cast<Instruction>(U.getUser()); 5878 LLVM_DEBUG(dbgs() << "[AANoCapture] Check use: " << *U.get() << " in " 5879 << *UInst << "\n"); 5880 5881 // Deal with ptr2int by following uses. 5882 if (isa<PtrToIntInst>(UInst)) { 5883 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n"); 5884 return isCapturedIn(State, /* Memory */ true, /* Integer */ true, 5885 /* Return */ true); 5886 } 5887 5888 // For stores we already checked if we can follow them, if they make it 5889 // here we give up. 5890 if (isa<StoreInst>(UInst)) 5891 return isCapturedIn(State, /* Memory */ true, /* Integer */ true, 5892 /* Return */ true); 5893 5894 // Explicitly catch return instructions. 5895 if (isa<ReturnInst>(UInst)) { 5896 if (UInst->getFunction() == getAnchorScope()) 5897 return isCapturedIn(State, /* Memory */ false, /* Integer */ false, 5898 /* Return */ true); 5899 return isCapturedIn(State, /* Memory */ true, /* Integer */ true, 5900 /* Return */ true); 5901 } 5902 5903 // For now we only use special logic for call sites. However, the tracker 5904 // itself knows about a lot of other non-capturing cases already. 5905 auto *CB = dyn_cast<CallBase>(UInst); 5906 if (!CB || !CB->isArgOperand(&U)) 5907 return isCapturedIn(State, /* Memory */ true, /* Integer */ true, 5908 /* Return */ true); 5909 5910 unsigned ArgNo = CB->getArgOperandNo(&U); 5911 const IRPosition &CSArgPos = IRPosition::callsite_argument(*CB, ArgNo); 5912 // If we have a abstract no-capture attribute for the argument we can use 5913 // it to justify a non-capture attribute here. This allows recursion! 5914 bool IsKnownNoCapture; 5915 const AANoCapture *ArgNoCaptureAA = nullptr; 5916 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>( 5917 A, this, CSArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false, 5918 &ArgNoCaptureAA); 5919 if (IsAssumedNoCapture) 5920 return isCapturedIn(State, /* Memory */ false, /* Integer */ false, 5921 /* Return */ false); 5922 if (ArgNoCaptureAA && ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned()) { 5923 Follow = true; 5924 return isCapturedIn(State, /* Memory */ false, /* Integer */ false, 5925 /* Return */ false); 5926 } 5927 5928 // Lastly, we could not find a reason no-capture can be assumed so we don't. 5929 return isCapturedIn(State, /* Memory */ true, /* Integer */ true, 5930 /* Return */ true); 5931 } 5932 5933 /// Update \p State according to \p CapturedInMem, \p CapturedInInt, and 5934 /// \p CapturedInRet, then return true if we should continue updating the 5935 /// state. 5936 static bool isCapturedIn(AANoCapture::StateType &State, bool CapturedInMem, 5937 bool CapturedInInt, bool CapturedInRet) { 5938 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int " 5939 << CapturedInInt << "|Ret " << CapturedInRet << "]\n"); 5940 if (CapturedInMem) 5941 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM); 5942 if (CapturedInInt) 5943 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT); 5944 if (CapturedInRet) 5945 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET); 5946 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED); 5947 } 5948 }; 5949 5950 ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) { 5951 const IRPosition &IRP = getIRPosition(); 5952 Value *V = isArgumentPosition() ? IRP.getAssociatedArgument() 5953 : &IRP.getAssociatedValue(); 5954 if (!V) 5955 return indicatePessimisticFixpoint(); 5956 5957 const Function *F = 5958 isArgumentPosition() ? IRP.getAssociatedFunction() : IRP.getAnchorScope(); 5959 5960 // TODO: Is the checkForAllUses below useful for constants? 5961 if (!F) 5962 return indicatePessimisticFixpoint(); 5963 5964 AANoCapture::StateType T; 5965 const IRPosition &FnPos = IRPosition::function(*F); 5966 5967 // Readonly means we cannot capture through memory. 5968 bool IsKnown; 5969 if (AA::isAssumedReadOnly(A, FnPos, *this, IsKnown)) { 5970 T.addKnownBits(NOT_CAPTURED_IN_MEM); 5971 if (IsKnown) 5972 addKnownBits(NOT_CAPTURED_IN_MEM); 5973 } 5974 5975 // Make sure all returned values are different than the underlying value. 5976 // TODO: we could do this in a more sophisticated way inside 5977 // AAReturnedValues, e.g., track all values that escape through returns 5978 // directly somehow. 5979 auto CheckReturnedArgs = [&](bool &UsedAssumedInformation) { 5980 SmallVector<AA::ValueAndContext> Values; 5981 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*F), this, Values, 5982 AA::ValueScope::Intraprocedural, 5983 UsedAssumedInformation)) 5984 return false; 5985 bool SeenConstant = false; 5986 for (const AA::ValueAndContext &VAC : Values) { 5987 if (isa<Constant>(VAC.getValue())) { 5988 if (SeenConstant) 5989 return false; 5990 SeenConstant = true; 5991 } else if (!isa<Argument>(VAC.getValue()) || 5992 VAC.getValue() == getAssociatedArgument()) 5993 return false; 5994 } 5995 return true; 5996 }; 5997 5998 bool IsKnownNoUnwind; 5999 if (AA::hasAssumedIRAttr<Attribute::NoUnwind>( 6000 A, this, FnPos, DepClassTy::OPTIONAL, IsKnownNoUnwind)) { 6001 bool IsVoidTy = F->getReturnType()->isVoidTy(); 6002 bool UsedAssumedInformation = false; 6003 if (IsVoidTy || CheckReturnedArgs(UsedAssumedInformation)) { 6004 T.addKnownBits(NOT_CAPTURED_IN_RET); 6005 if (T.isKnown(NOT_CAPTURED_IN_MEM)) 6006 return ChangeStatus::UNCHANGED; 6007 if (IsKnownNoUnwind && (IsVoidTy || !UsedAssumedInformation)) { 6008 addKnownBits(NOT_CAPTURED_IN_RET); 6009 if (isKnown(NOT_CAPTURED_IN_MEM)) 6010 return indicateOptimisticFixpoint(); 6011 } 6012 } 6013 } 6014 6015 auto IsDereferenceableOrNull = [&](Value *O, const DataLayout &DL) { 6016 const auto *DerefAA = A.getAAFor<AADereferenceable>( 6017 *this, IRPosition::value(*O), DepClassTy::OPTIONAL); 6018 return DerefAA && DerefAA->getAssumedDereferenceableBytes(); 6019 }; 6020 6021 auto UseCheck = [&](const Use &U, bool &Follow) -> bool { 6022 switch (DetermineUseCaptureKind(U, IsDereferenceableOrNull)) { 6023 case UseCaptureKind::NO_CAPTURE: 6024 return true; 6025 case UseCaptureKind::MAY_CAPTURE: 6026 return checkUse(A, T, U, Follow); 6027 case UseCaptureKind::PASSTHROUGH: 6028 Follow = true; 6029 return true; 6030 } 6031 llvm_unreachable("Unexpected use capture kind!"); 6032 }; 6033 6034 if (!A.checkForAllUses(UseCheck, *this, *V)) 6035 return indicatePessimisticFixpoint(); 6036 6037 AANoCapture::StateType &S = getState(); 6038 auto Assumed = S.getAssumed(); 6039 S.intersectAssumedBits(T.getAssumed()); 6040 if (!isAssumedNoCaptureMaybeReturned()) 6041 return indicatePessimisticFixpoint(); 6042 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED 6043 : ChangeStatus::CHANGED; 6044 } 6045 6046 /// NoCapture attribute for function arguments. 6047 struct AANoCaptureArgument final : AANoCaptureImpl { 6048 AANoCaptureArgument(const IRPosition &IRP, Attributor &A) 6049 : AANoCaptureImpl(IRP, A) {} 6050 6051 /// See AbstractAttribute::trackStatistics() 6052 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) } 6053 }; 6054 6055 /// NoCapture attribute for call site arguments. 6056 struct AANoCaptureCallSiteArgument final : AANoCaptureImpl { 6057 AANoCaptureCallSiteArgument(const IRPosition &IRP, Attributor &A) 6058 : AANoCaptureImpl(IRP, A) {} 6059 6060 /// See AbstractAttribute::updateImpl(...). 6061 ChangeStatus updateImpl(Attributor &A) override { 6062 // TODO: Once we have call site specific value information we can provide 6063 // call site specific liveness information and then it makes 6064 // sense to specialize attributes for call sites arguments instead of 6065 // redirecting requests to the callee argument. 6066 Argument *Arg = getAssociatedArgument(); 6067 if (!Arg) 6068 return indicatePessimisticFixpoint(); 6069 const IRPosition &ArgPos = IRPosition::argument(*Arg); 6070 bool IsKnownNoCapture; 6071 const AANoCapture *ArgAA = nullptr; 6072 if (AA::hasAssumedIRAttr<Attribute::Captures>( 6073 A, this, ArgPos, DepClassTy::REQUIRED, IsKnownNoCapture, false, 6074 &ArgAA)) 6075 return ChangeStatus::UNCHANGED; 6076 if (!ArgAA || !ArgAA->isAssumedNoCaptureMaybeReturned()) 6077 return indicatePessimisticFixpoint(); 6078 return clampStateAndIndicateChange(getState(), ArgAA->getState()); 6079 } 6080 6081 /// See AbstractAttribute::trackStatistics() 6082 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nocapture)}; 6083 }; 6084 6085 /// NoCapture attribute for floating values. 6086 struct AANoCaptureFloating final : AANoCaptureImpl { 6087 AANoCaptureFloating(const IRPosition &IRP, Attributor &A) 6088 : AANoCaptureImpl(IRP, A) {} 6089 6090 /// See AbstractAttribute::trackStatistics() 6091 void trackStatistics() const override { 6092 STATS_DECLTRACK_FLOATING_ATTR(nocapture) 6093 } 6094 }; 6095 6096 /// NoCapture attribute for function return value. 6097 struct AANoCaptureReturned final : AANoCaptureImpl { 6098 AANoCaptureReturned(const IRPosition &IRP, Attributor &A) 6099 : AANoCaptureImpl(IRP, A) { 6100 llvm_unreachable("NoCapture is not applicable to function returns!"); 6101 } 6102 6103 /// See AbstractAttribute::initialize(...). 6104 void initialize(Attributor &A) override { 6105 llvm_unreachable("NoCapture is not applicable to function returns!"); 6106 } 6107 6108 /// See AbstractAttribute::updateImpl(...). 6109 ChangeStatus updateImpl(Attributor &A) override { 6110 llvm_unreachable("NoCapture is not applicable to function returns!"); 6111 } 6112 6113 /// See AbstractAttribute::trackStatistics() 6114 void trackStatistics() const override {} 6115 }; 6116 6117 /// NoCapture attribute deduction for a call site return value. 6118 struct AANoCaptureCallSiteReturned final : AANoCaptureImpl { 6119 AANoCaptureCallSiteReturned(const IRPosition &IRP, Attributor &A) 6120 : AANoCaptureImpl(IRP, A) {} 6121 6122 /// See AbstractAttribute::initialize(...). 6123 void initialize(Attributor &A) override { 6124 const Function *F = getAnchorScope(); 6125 // Check what state the associated function can actually capture. 6126 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this); 6127 } 6128 6129 /// See AbstractAttribute::trackStatistics() 6130 void trackStatistics() const override { 6131 STATS_DECLTRACK_CSRET_ATTR(nocapture) 6132 } 6133 }; 6134 } // namespace 6135 6136 /// ------------------ Value Simplify Attribute ---------------------------- 6137 6138 bool ValueSimplifyStateType::unionAssumed(std::optional<Value *> Other) { 6139 // FIXME: Add a typecast support. 6140 SimplifiedAssociatedValue = AA::combineOptionalValuesInAAValueLatice( 6141 SimplifiedAssociatedValue, Other, Ty); 6142 if (SimplifiedAssociatedValue == std::optional<Value *>(nullptr)) 6143 return false; 6144 6145 LLVM_DEBUG({ 6146 if (SimplifiedAssociatedValue) 6147 dbgs() << "[ValueSimplify] is assumed to be " 6148 << **SimplifiedAssociatedValue << "\n"; 6149 else 6150 dbgs() << "[ValueSimplify] is assumed to be <none>\n"; 6151 }); 6152 return true; 6153 } 6154 6155 namespace { 6156 struct AAValueSimplifyImpl : AAValueSimplify { 6157 AAValueSimplifyImpl(const IRPosition &IRP, Attributor &A) 6158 : AAValueSimplify(IRP, A) {} 6159 6160 /// See AbstractAttribute::initialize(...). 6161 void initialize(Attributor &A) override { 6162 if (getAssociatedValue().getType()->isVoidTy()) 6163 indicatePessimisticFixpoint(); 6164 if (A.hasSimplificationCallback(getIRPosition())) 6165 indicatePessimisticFixpoint(); 6166 } 6167 6168 /// See AbstractAttribute::getAsStr(). 6169 const std::string getAsStr(Attributor *A) const override { 6170 LLVM_DEBUG({ 6171 dbgs() << "SAV: " << (bool)SimplifiedAssociatedValue << " "; 6172 if (SimplifiedAssociatedValue && *SimplifiedAssociatedValue) 6173 dbgs() << "SAV: " << **SimplifiedAssociatedValue << " "; 6174 }); 6175 return isValidState() ? (isAtFixpoint() ? "simplified" : "maybe-simple") 6176 : "not-simple"; 6177 } 6178 6179 /// See AbstractAttribute::trackStatistics() 6180 void trackStatistics() const override {} 6181 6182 /// See AAValueSimplify::getAssumedSimplifiedValue() 6183 std::optional<Value *> 6184 getAssumedSimplifiedValue(Attributor &A) const override { 6185 return SimplifiedAssociatedValue; 6186 } 6187 6188 /// Ensure the return value is \p V with type \p Ty, if not possible return 6189 /// nullptr. If \p Check is true we will only verify such an operation would 6190 /// suceed and return a non-nullptr value if that is the case. No IR is 6191 /// generated or modified. 6192 static Value *ensureType(Attributor &A, Value &V, Type &Ty, Instruction *CtxI, 6193 bool Check) { 6194 if (auto *TypedV = AA::getWithType(V, Ty)) 6195 return TypedV; 6196 if (CtxI && V.getType()->canLosslesslyBitCastTo(&Ty)) 6197 return Check ? &V 6198 : BitCastInst::CreatePointerBitCastOrAddrSpaceCast( 6199 &V, &Ty, "", CtxI->getIterator()); 6200 return nullptr; 6201 } 6202 6203 /// Reproduce \p I with type \p Ty or return nullptr if that is not posisble. 6204 /// If \p Check is true we will only verify such an operation would suceed and 6205 /// return a non-nullptr value if that is the case. No IR is generated or 6206 /// modified. 6207 static Value *reproduceInst(Attributor &A, 6208 const AbstractAttribute &QueryingAA, 6209 Instruction &I, Type &Ty, Instruction *CtxI, 6210 bool Check, ValueToValueMapTy &VMap) { 6211 assert(CtxI && "Cannot reproduce an instruction without context!"); 6212 if (Check && (I.mayReadFromMemory() || 6213 !isSafeToSpeculativelyExecute(&I, CtxI, /* DT */ nullptr, 6214 /* TLI */ nullptr))) 6215 return nullptr; 6216 for (Value *Op : I.operands()) { 6217 Value *NewOp = reproduceValue(A, QueryingAA, *Op, Ty, CtxI, Check, VMap); 6218 if (!NewOp) { 6219 assert(Check && "Manifest of new value unexpectedly failed!"); 6220 return nullptr; 6221 } 6222 if (!Check) 6223 VMap[Op] = NewOp; 6224 } 6225 if (Check) 6226 return &I; 6227 6228 Instruction *CloneI = I.clone(); 6229 // TODO: Try to salvage debug information here. 6230 CloneI->setDebugLoc(DebugLoc()); 6231 VMap[&I] = CloneI; 6232 CloneI->insertBefore(CtxI->getIterator()); 6233 RemapInstruction(CloneI, VMap); 6234 return CloneI; 6235 } 6236 6237 /// Reproduce \p V with type \p Ty or return nullptr if that is not posisble. 6238 /// If \p Check is true we will only verify such an operation would suceed and 6239 /// return a non-nullptr value if that is the case. No IR is generated or 6240 /// modified. 6241 static Value *reproduceValue(Attributor &A, 6242 const AbstractAttribute &QueryingAA, Value &V, 6243 Type &Ty, Instruction *CtxI, bool Check, 6244 ValueToValueMapTy &VMap) { 6245 if (const auto &NewV = VMap.lookup(&V)) 6246 return NewV; 6247 bool UsedAssumedInformation = false; 6248 std::optional<Value *> SimpleV = A.getAssumedSimplified( 6249 V, QueryingAA, UsedAssumedInformation, AA::Interprocedural); 6250 if (!SimpleV.has_value()) 6251 return PoisonValue::get(&Ty); 6252 Value *EffectiveV = &V; 6253 if (*SimpleV) 6254 EffectiveV = *SimpleV; 6255 if (auto *C = dyn_cast<Constant>(EffectiveV)) 6256 return C; 6257 if (CtxI && AA::isValidAtPosition(AA::ValueAndContext(*EffectiveV, *CtxI), 6258 A.getInfoCache())) 6259 return ensureType(A, *EffectiveV, Ty, CtxI, Check); 6260 if (auto *I = dyn_cast<Instruction>(EffectiveV)) 6261 if (Value *NewV = reproduceInst(A, QueryingAA, *I, Ty, CtxI, Check, VMap)) 6262 return ensureType(A, *NewV, Ty, CtxI, Check); 6263 return nullptr; 6264 } 6265 6266 /// Return a value we can use as replacement for the associated one, or 6267 /// nullptr if we don't have one that makes sense. 6268 Value *manifestReplacementValue(Attributor &A, Instruction *CtxI) const { 6269 Value *NewV = SimplifiedAssociatedValue 6270 ? *SimplifiedAssociatedValue 6271 : UndefValue::get(getAssociatedType()); 6272 if (NewV && NewV != &getAssociatedValue()) { 6273 ValueToValueMapTy VMap; 6274 // First verify we can reprduce the value with the required type at the 6275 // context location before we actually start modifying the IR. 6276 if (reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI, 6277 /* CheckOnly */ true, VMap)) 6278 return reproduceValue(A, *this, *NewV, *getAssociatedType(), CtxI, 6279 /* CheckOnly */ false, VMap); 6280 } 6281 return nullptr; 6282 } 6283 6284 /// Helper function for querying AAValueSimplify and updating candidate. 6285 /// \param IRP The value position we are trying to unify with SimplifiedValue 6286 bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA, 6287 const IRPosition &IRP, bool Simplify = true) { 6288 bool UsedAssumedInformation = false; 6289 std::optional<Value *> QueryingValueSimplified = &IRP.getAssociatedValue(); 6290 if (Simplify) 6291 QueryingValueSimplified = A.getAssumedSimplified( 6292 IRP, QueryingAA, UsedAssumedInformation, AA::Interprocedural); 6293 return unionAssumed(QueryingValueSimplified); 6294 } 6295 6296 /// Returns a candidate is found or not 6297 template <typename AAType> bool askSimplifiedValueFor(Attributor &A) { 6298 if (!getAssociatedValue().getType()->isIntegerTy()) 6299 return false; 6300 6301 // This will also pass the call base context. 6302 const auto *AA = 6303 A.getAAFor<AAType>(*this, getIRPosition(), DepClassTy::NONE); 6304 if (!AA) 6305 return false; 6306 6307 std::optional<Constant *> COpt = AA->getAssumedConstant(A); 6308 6309 if (!COpt) { 6310 SimplifiedAssociatedValue = std::nullopt; 6311 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL); 6312 return true; 6313 } 6314 if (auto *C = *COpt) { 6315 SimplifiedAssociatedValue = C; 6316 A.recordDependence(*AA, *this, DepClassTy::OPTIONAL); 6317 return true; 6318 } 6319 return false; 6320 } 6321 6322 bool askSimplifiedValueForOtherAAs(Attributor &A) { 6323 if (askSimplifiedValueFor<AAValueConstantRange>(A)) 6324 return true; 6325 if (askSimplifiedValueFor<AAPotentialConstantValues>(A)) 6326 return true; 6327 return false; 6328 } 6329 6330 /// See AbstractAttribute::manifest(...). 6331 ChangeStatus manifest(Attributor &A) override { 6332 ChangeStatus Changed = ChangeStatus::UNCHANGED; 6333 for (auto &U : getAssociatedValue().uses()) { 6334 // Check if we need to adjust the insertion point to make sure the IR is 6335 // valid. 6336 Instruction *IP = dyn_cast<Instruction>(U.getUser()); 6337 if (auto *PHI = dyn_cast_or_null<PHINode>(IP)) 6338 IP = PHI->getIncomingBlock(U)->getTerminator(); 6339 if (auto *NewV = manifestReplacementValue(A, IP)) { 6340 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << getAssociatedValue() 6341 << " -> " << *NewV << " :: " << *this << "\n"); 6342 if (A.changeUseAfterManifest(U, *NewV)) 6343 Changed = ChangeStatus::CHANGED; 6344 } 6345 } 6346 6347 return Changed | AAValueSimplify::manifest(A); 6348 } 6349 6350 /// See AbstractState::indicatePessimisticFixpoint(...). 6351 ChangeStatus indicatePessimisticFixpoint() override { 6352 SimplifiedAssociatedValue = &getAssociatedValue(); 6353 return AAValueSimplify::indicatePessimisticFixpoint(); 6354 } 6355 }; 6356 6357 struct AAValueSimplifyArgument final : AAValueSimplifyImpl { 6358 AAValueSimplifyArgument(const IRPosition &IRP, Attributor &A) 6359 : AAValueSimplifyImpl(IRP, A) {} 6360 6361 void initialize(Attributor &A) override { 6362 AAValueSimplifyImpl::initialize(A); 6363 if (A.hasAttr(getIRPosition(), 6364 {Attribute::InAlloca, Attribute::Preallocated, 6365 Attribute::StructRet, Attribute::Nest, Attribute::ByVal}, 6366 /* IgnoreSubsumingPositions */ true)) 6367 indicatePessimisticFixpoint(); 6368 } 6369 6370 /// See AbstractAttribute::updateImpl(...). 6371 ChangeStatus updateImpl(Attributor &A) override { 6372 // Byval is only replacable if it is readonly otherwise we would write into 6373 // the replaced value and not the copy that byval creates implicitly. 6374 Argument *Arg = getAssociatedArgument(); 6375 if (Arg->hasByValAttr()) { 6376 // TODO: We probably need to verify synchronization is not an issue, e.g., 6377 // there is no race by not copying a constant byval. 6378 bool IsKnown; 6379 if (!AA::isAssumedReadOnly(A, getIRPosition(), *this, IsKnown)) 6380 return indicatePessimisticFixpoint(); 6381 } 6382 6383 auto Before = SimplifiedAssociatedValue; 6384 6385 auto PredForCallSite = [&](AbstractCallSite ACS) { 6386 const IRPosition &ACSArgPos = 6387 IRPosition::callsite_argument(ACS, getCallSiteArgNo()); 6388 // Check if a coresponding argument was found or if it is on not 6389 // associated (which can happen for callback calls). 6390 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID) 6391 return false; 6392 6393 // Simplify the argument operand explicitly and check if the result is 6394 // valid in the current scope. This avoids refering to simplified values 6395 // in other functions, e.g., we don't want to say a an argument in a 6396 // static function is actually an argument in a different function. 6397 bool UsedAssumedInformation = false; 6398 std::optional<Constant *> SimpleArgOp = 6399 A.getAssumedConstant(ACSArgPos, *this, UsedAssumedInformation); 6400 if (!SimpleArgOp) 6401 return true; 6402 if (!*SimpleArgOp) 6403 return false; 6404 if (!AA::isDynamicallyUnique(A, *this, **SimpleArgOp)) 6405 return false; 6406 return unionAssumed(*SimpleArgOp); 6407 }; 6408 6409 // Generate a answer specific to a call site context. 6410 bool Success; 6411 bool UsedAssumedInformation = false; 6412 if (hasCallBaseContext() && 6413 getCallBaseContext()->getCalledOperand() == Arg->getParent()) 6414 Success = PredForCallSite( 6415 AbstractCallSite(&getCallBaseContext()->getCalledOperandUse())); 6416 else 6417 Success = A.checkForAllCallSites(PredForCallSite, *this, true, 6418 UsedAssumedInformation); 6419 6420 if (!Success) 6421 if (!askSimplifiedValueForOtherAAs(A)) 6422 return indicatePessimisticFixpoint(); 6423 6424 // If a candidate was found in this update, return CHANGED. 6425 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED 6426 : ChangeStatus ::CHANGED; 6427 } 6428 6429 /// See AbstractAttribute::trackStatistics() 6430 void trackStatistics() const override { 6431 STATS_DECLTRACK_ARG_ATTR(value_simplify) 6432 } 6433 }; 6434 6435 struct AAValueSimplifyReturned : AAValueSimplifyImpl { 6436 AAValueSimplifyReturned(const IRPosition &IRP, Attributor &A) 6437 : AAValueSimplifyImpl(IRP, A) {} 6438 6439 /// See AAValueSimplify::getAssumedSimplifiedValue() 6440 std::optional<Value *> 6441 getAssumedSimplifiedValue(Attributor &A) const override { 6442 if (!isValidState()) 6443 return nullptr; 6444 return SimplifiedAssociatedValue; 6445 } 6446 6447 /// See AbstractAttribute::updateImpl(...). 6448 ChangeStatus updateImpl(Attributor &A) override { 6449 auto Before = SimplifiedAssociatedValue; 6450 6451 auto ReturnInstCB = [&](Instruction &I) { 6452 auto &RI = cast<ReturnInst>(I); 6453 return checkAndUpdate( 6454 A, *this, 6455 IRPosition::value(*RI.getReturnValue(), getCallBaseContext())); 6456 }; 6457 6458 bool UsedAssumedInformation = false; 6459 if (!A.checkForAllInstructions(ReturnInstCB, *this, {Instruction::Ret}, 6460 UsedAssumedInformation)) 6461 if (!askSimplifiedValueForOtherAAs(A)) 6462 return indicatePessimisticFixpoint(); 6463 6464 // If a candidate was found in this update, return CHANGED. 6465 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED 6466 : ChangeStatus ::CHANGED; 6467 } 6468 6469 ChangeStatus manifest(Attributor &A) override { 6470 // We queried AAValueSimplify for the returned values so they will be 6471 // replaced if a simplified form was found. Nothing to do here. 6472 return ChangeStatus::UNCHANGED; 6473 } 6474 6475 /// See AbstractAttribute::trackStatistics() 6476 void trackStatistics() const override { 6477 STATS_DECLTRACK_FNRET_ATTR(value_simplify) 6478 } 6479 }; 6480 6481 struct AAValueSimplifyFloating : AAValueSimplifyImpl { 6482 AAValueSimplifyFloating(const IRPosition &IRP, Attributor &A) 6483 : AAValueSimplifyImpl(IRP, A) {} 6484 6485 /// See AbstractAttribute::initialize(...). 6486 void initialize(Attributor &A) override { 6487 AAValueSimplifyImpl::initialize(A); 6488 Value &V = getAnchorValue(); 6489 6490 // TODO: add other stuffs 6491 if (isa<Constant>(V)) 6492 indicatePessimisticFixpoint(); 6493 } 6494 6495 /// See AbstractAttribute::updateImpl(...). 6496 ChangeStatus updateImpl(Attributor &A) override { 6497 auto Before = SimplifiedAssociatedValue; 6498 if (!askSimplifiedValueForOtherAAs(A)) 6499 return indicatePessimisticFixpoint(); 6500 6501 // If a candidate was found in this update, return CHANGED. 6502 return Before == SimplifiedAssociatedValue ? ChangeStatus::UNCHANGED 6503 : ChangeStatus ::CHANGED; 6504 } 6505 6506 /// See AbstractAttribute::trackStatistics() 6507 void trackStatistics() const override { 6508 STATS_DECLTRACK_FLOATING_ATTR(value_simplify) 6509 } 6510 }; 6511 6512 struct AAValueSimplifyFunction : AAValueSimplifyImpl { 6513 AAValueSimplifyFunction(const IRPosition &IRP, Attributor &A) 6514 : AAValueSimplifyImpl(IRP, A) {} 6515 6516 /// See AbstractAttribute::initialize(...). 6517 void initialize(Attributor &A) override { 6518 SimplifiedAssociatedValue = nullptr; 6519 indicateOptimisticFixpoint(); 6520 } 6521 /// See AbstractAttribute::initialize(...). 6522 ChangeStatus updateImpl(Attributor &A) override { 6523 llvm_unreachable( 6524 "AAValueSimplify(Function|CallSite)::updateImpl will not be called"); 6525 } 6526 /// See AbstractAttribute::trackStatistics() 6527 void trackStatistics() const override { 6528 STATS_DECLTRACK_FN_ATTR(value_simplify) 6529 } 6530 }; 6531 6532 struct AAValueSimplifyCallSite : AAValueSimplifyFunction { 6533 AAValueSimplifyCallSite(const IRPosition &IRP, Attributor &A) 6534 : AAValueSimplifyFunction(IRP, A) {} 6535 /// See AbstractAttribute::trackStatistics() 6536 void trackStatistics() const override { 6537 STATS_DECLTRACK_CS_ATTR(value_simplify) 6538 } 6539 }; 6540 6541 struct AAValueSimplifyCallSiteReturned : AAValueSimplifyImpl { 6542 AAValueSimplifyCallSiteReturned(const IRPosition &IRP, Attributor &A) 6543 : AAValueSimplifyImpl(IRP, A) {} 6544 6545 void initialize(Attributor &A) override { 6546 AAValueSimplifyImpl::initialize(A); 6547 Function *Fn = getAssociatedFunction(); 6548 assert(Fn && "Did expect an associted function"); 6549 for (Argument &Arg : Fn->args()) { 6550 if (Arg.hasReturnedAttr()) { 6551 auto IRP = IRPosition::callsite_argument(*cast<CallBase>(getCtxI()), 6552 Arg.getArgNo()); 6553 if (IRP.getPositionKind() == IRPosition::IRP_CALL_SITE_ARGUMENT && 6554 checkAndUpdate(A, *this, IRP)) 6555 indicateOptimisticFixpoint(); 6556 else 6557 indicatePessimisticFixpoint(); 6558 return; 6559 } 6560 } 6561 } 6562 6563 /// See AbstractAttribute::updateImpl(...). 6564 ChangeStatus updateImpl(Attributor &A) override { 6565 return indicatePessimisticFixpoint(); 6566 } 6567 6568 void trackStatistics() const override { 6569 STATS_DECLTRACK_CSRET_ATTR(value_simplify) 6570 } 6571 }; 6572 6573 struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating { 6574 AAValueSimplifyCallSiteArgument(const IRPosition &IRP, Attributor &A) 6575 : AAValueSimplifyFloating(IRP, A) {} 6576 6577 /// See AbstractAttribute::manifest(...). 6578 ChangeStatus manifest(Attributor &A) override { 6579 ChangeStatus Changed = ChangeStatus::UNCHANGED; 6580 // TODO: We should avoid simplification duplication to begin with. 6581 auto *FloatAA = A.lookupAAFor<AAValueSimplify>( 6582 IRPosition::value(getAssociatedValue()), this, DepClassTy::NONE); 6583 if (FloatAA && FloatAA->getState().isValidState()) 6584 return Changed; 6585 6586 if (auto *NewV = manifestReplacementValue(A, getCtxI())) { 6587 Use &U = cast<CallBase>(&getAnchorValue()) 6588 ->getArgOperandUse(getCallSiteArgNo()); 6589 if (A.changeUseAfterManifest(U, *NewV)) 6590 Changed = ChangeStatus::CHANGED; 6591 } 6592 6593 return Changed | AAValueSimplify::manifest(A); 6594 } 6595 6596 void trackStatistics() const override { 6597 STATS_DECLTRACK_CSARG_ATTR(value_simplify) 6598 } 6599 }; 6600 } // namespace 6601 6602 /// ----------------------- Heap-To-Stack Conversion --------------------------- 6603 namespace { 6604 struct AAHeapToStackFunction final : public AAHeapToStack { 6605 6606 struct AllocationInfo { 6607 /// The call that allocates the memory. 6608 CallBase *const CB; 6609 6610 /// The library function id for the allocation. 6611 LibFunc LibraryFunctionId = NotLibFunc; 6612 6613 /// The status wrt. a rewrite. 6614 enum { 6615 STACK_DUE_TO_USE, 6616 STACK_DUE_TO_FREE, 6617 INVALID, 6618 } Status = STACK_DUE_TO_USE; 6619 6620 /// Flag to indicate if we encountered a use that might free this allocation 6621 /// but which is not in the deallocation infos. 6622 bool HasPotentiallyFreeingUnknownUses = false; 6623 6624 /// Flag to indicate that we should place the new alloca in the function 6625 /// entry block rather than where the call site (CB) is. 6626 bool MoveAllocaIntoEntry = true; 6627 6628 /// The set of free calls that use this allocation. 6629 SmallSetVector<CallBase *, 1> PotentialFreeCalls{}; 6630 }; 6631 6632 struct DeallocationInfo { 6633 /// The call that deallocates the memory. 6634 CallBase *const CB; 6635 /// The value freed by the call. 6636 Value *FreedOp; 6637 6638 /// Flag to indicate if we don't know all objects this deallocation might 6639 /// free. 6640 bool MightFreeUnknownObjects = false; 6641 6642 /// The set of allocation calls that are potentially freed. 6643 SmallSetVector<CallBase *, 1> PotentialAllocationCalls{}; 6644 }; 6645 6646 AAHeapToStackFunction(const IRPosition &IRP, Attributor &A) 6647 : AAHeapToStack(IRP, A) {} 6648 6649 ~AAHeapToStackFunction() { 6650 // Ensure we call the destructor so we release any memory allocated in the 6651 // sets. 6652 for (auto &It : AllocationInfos) 6653 It.second->~AllocationInfo(); 6654 for (auto &It : DeallocationInfos) 6655 It.second->~DeallocationInfo(); 6656 } 6657 6658 void initialize(Attributor &A) override { 6659 AAHeapToStack::initialize(A); 6660 6661 const Function *F = getAnchorScope(); 6662 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F); 6663 6664 auto AllocationIdentifierCB = [&](Instruction &I) { 6665 CallBase *CB = dyn_cast<CallBase>(&I); 6666 if (!CB) 6667 return true; 6668 if (Value *FreedOp = getFreedOperand(CB, TLI)) { 6669 DeallocationInfos[CB] = new (A.Allocator) DeallocationInfo{CB, FreedOp}; 6670 return true; 6671 } 6672 // To do heap to stack, we need to know that the allocation itself is 6673 // removable once uses are rewritten, and that we can initialize the 6674 // alloca to the same pattern as the original allocation result. 6675 if (isRemovableAlloc(CB, TLI)) { 6676 auto *I8Ty = Type::getInt8Ty(CB->getParent()->getContext()); 6677 if (nullptr != getInitialValueOfAllocation(CB, TLI, I8Ty)) { 6678 AllocationInfo *AI = new (A.Allocator) AllocationInfo{CB}; 6679 AllocationInfos[CB] = AI; 6680 if (TLI) 6681 TLI->getLibFunc(*CB, AI->LibraryFunctionId); 6682 } 6683 } 6684 return true; 6685 }; 6686 6687 bool UsedAssumedInformation = false; 6688 bool Success = A.checkForAllCallLikeInstructions( 6689 AllocationIdentifierCB, *this, UsedAssumedInformation, 6690 /* CheckBBLivenessOnly */ false, 6691 /* CheckPotentiallyDead */ true); 6692 (void)Success; 6693 assert(Success && "Did not expect the call base visit callback to fail!"); 6694 6695 Attributor::SimplifictionCallbackTy SCB = 6696 [](const IRPosition &, const AbstractAttribute *, 6697 bool &) -> std::optional<Value *> { return nullptr; }; 6698 for (const auto &It : AllocationInfos) 6699 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first), 6700 SCB); 6701 for (const auto &It : DeallocationInfos) 6702 A.registerSimplificationCallback(IRPosition::callsite_returned(*It.first), 6703 SCB); 6704 } 6705 6706 const std::string getAsStr(Attributor *A) const override { 6707 unsigned NumH2SMallocs = 0, NumInvalidMallocs = 0; 6708 for (const auto &It : AllocationInfos) { 6709 if (It.second->Status == AllocationInfo::INVALID) 6710 ++NumInvalidMallocs; 6711 else 6712 ++NumH2SMallocs; 6713 } 6714 return "[H2S] Mallocs Good/Bad: " + std::to_string(NumH2SMallocs) + "/" + 6715 std::to_string(NumInvalidMallocs); 6716 } 6717 6718 /// See AbstractAttribute::trackStatistics(). 6719 void trackStatistics() const override { 6720 STATS_DECL( 6721 MallocCalls, Function, 6722 "Number of malloc/calloc/aligned_alloc calls converted to allocas"); 6723 for (const auto &It : AllocationInfos) 6724 if (It.second->Status != AllocationInfo::INVALID) 6725 ++BUILD_STAT_NAME(MallocCalls, Function); 6726 } 6727 6728 bool isAssumedHeapToStack(const CallBase &CB) const override { 6729 if (isValidState()) 6730 if (AllocationInfo *AI = 6731 AllocationInfos.lookup(const_cast<CallBase *>(&CB))) 6732 return AI->Status != AllocationInfo::INVALID; 6733 return false; 6734 } 6735 6736 bool isAssumedHeapToStackRemovedFree(CallBase &CB) const override { 6737 if (!isValidState()) 6738 return false; 6739 6740 for (const auto &It : AllocationInfos) { 6741 AllocationInfo &AI = *It.second; 6742 if (AI.Status == AllocationInfo::INVALID) 6743 continue; 6744 6745 if (AI.PotentialFreeCalls.count(&CB)) 6746 return true; 6747 } 6748 6749 return false; 6750 } 6751 6752 ChangeStatus manifest(Attributor &A) override { 6753 assert(getState().isValidState() && 6754 "Attempted to manifest an invalid state!"); 6755 6756 ChangeStatus HasChanged = ChangeStatus::UNCHANGED; 6757 Function *F = getAnchorScope(); 6758 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F); 6759 6760 for (auto &It : AllocationInfos) { 6761 AllocationInfo &AI = *It.second; 6762 if (AI.Status == AllocationInfo::INVALID) 6763 continue; 6764 6765 for (CallBase *FreeCall : AI.PotentialFreeCalls) { 6766 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n"); 6767 A.deleteAfterManifest(*FreeCall); 6768 HasChanged = ChangeStatus::CHANGED; 6769 } 6770 6771 LLVM_DEBUG(dbgs() << "H2S: Removing malloc-like call: " << *AI.CB 6772 << "\n"); 6773 6774 auto Remark = [&](OptimizationRemark OR) { 6775 LibFunc IsAllocShared; 6776 if (TLI->getLibFunc(*AI.CB, IsAllocShared)) 6777 if (IsAllocShared == LibFunc___kmpc_alloc_shared) 6778 return OR << "Moving globalized variable to the stack."; 6779 return OR << "Moving memory allocation from the heap to the stack."; 6780 }; 6781 if (AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared) 6782 A.emitRemark<OptimizationRemark>(AI.CB, "OMP110", Remark); 6783 else 6784 A.emitRemark<OptimizationRemark>(AI.CB, "HeapToStack", Remark); 6785 6786 const DataLayout &DL = A.getInfoCache().getDL(); 6787 Value *Size; 6788 std::optional<APInt> SizeAPI = getSize(A, *this, AI); 6789 if (SizeAPI) { 6790 Size = ConstantInt::get(AI.CB->getContext(), *SizeAPI); 6791 } else { 6792 LLVMContext &Ctx = AI.CB->getContext(); 6793 ObjectSizeOpts Opts; 6794 ObjectSizeOffsetEvaluator Eval(DL, TLI, Ctx, Opts); 6795 SizeOffsetValue SizeOffsetPair = Eval.compute(AI.CB); 6796 assert(SizeOffsetPair != ObjectSizeOffsetEvaluator::unknown() && 6797 cast<ConstantInt>(SizeOffsetPair.Offset)->isZero()); 6798 Size = SizeOffsetPair.Size; 6799 } 6800 6801 BasicBlock::iterator IP = AI.MoveAllocaIntoEntry 6802 ? F->getEntryBlock().begin() 6803 : AI.CB->getIterator(); 6804 6805 Align Alignment(1); 6806 if (MaybeAlign RetAlign = AI.CB->getRetAlign()) 6807 Alignment = std::max(Alignment, *RetAlign); 6808 if (Value *Align = getAllocAlignment(AI.CB, TLI)) { 6809 std::optional<APInt> AlignmentAPI = getAPInt(A, *this, *Align); 6810 assert(AlignmentAPI && AlignmentAPI->getZExtValue() > 0 && 6811 "Expected an alignment during manifest!"); 6812 Alignment = 6813 std::max(Alignment, assumeAligned(AlignmentAPI->getZExtValue())); 6814 } 6815 6816 // TODO: Hoist the alloca towards the function entry. 6817 unsigned AS = DL.getAllocaAddrSpace(); 6818 Instruction *Alloca = 6819 new AllocaInst(Type::getInt8Ty(F->getContext()), AS, Size, Alignment, 6820 AI.CB->getName() + ".h2s", IP); 6821 6822 if (Alloca->getType() != AI.CB->getType()) 6823 Alloca = BitCastInst::CreatePointerBitCastOrAddrSpaceCast( 6824 Alloca, AI.CB->getType(), "malloc_cast", AI.CB->getIterator()); 6825 6826 auto *I8Ty = Type::getInt8Ty(F->getContext()); 6827 auto *InitVal = getInitialValueOfAllocation(AI.CB, TLI, I8Ty); 6828 assert(InitVal && 6829 "Must be able to materialize initial memory state of allocation"); 6830 6831 A.changeAfterManifest(IRPosition::inst(*AI.CB), *Alloca); 6832 6833 if (auto *II = dyn_cast<InvokeInst>(AI.CB)) { 6834 auto *NBB = II->getNormalDest(); 6835 BranchInst::Create(NBB, AI.CB->getParent()); 6836 A.deleteAfterManifest(*AI.CB); 6837 } else { 6838 A.deleteAfterManifest(*AI.CB); 6839 } 6840 6841 // Initialize the alloca with the same value as used by the allocation 6842 // function. We can skip undef as the initial value of an alloc is 6843 // undef, and the memset would simply end up being DSEd. 6844 if (!isa<UndefValue>(InitVal)) { 6845 IRBuilder<> Builder(Alloca->getNextNode()); 6846 // TODO: Use alignment above if align!=1 6847 Builder.CreateMemSet(Alloca, InitVal, Size, std::nullopt); 6848 } 6849 HasChanged = ChangeStatus::CHANGED; 6850 } 6851 6852 return HasChanged; 6853 } 6854 6855 std::optional<APInt> getAPInt(Attributor &A, const AbstractAttribute &AA, 6856 Value &V) { 6857 bool UsedAssumedInformation = false; 6858 std::optional<Constant *> SimpleV = 6859 A.getAssumedConstant(V, AA, UsedAssumedInformation); 6860 if (!SimpleV) 6861 return APInt(64, 0); 6862 if (auto *CI = dyn_cast_or_null<ConstantInt>(*SimpleV)) 6863 return CI->getValue(); 6864 return std::nullopt; 6865 } 6866 6867 std::optional<APInt> getSize(Attributor &A, const AbstractAttribute &AA, 6868 AllocationInfo &AI) { 6869 auto Mapper = [&](const Value *V) -> const Value * { 6870 bool UsedAssumedInformation = false; 6871 if (std::optional<Constant *> SimpleV = 6872 A.getAssumedConstant(*V, AA, UsedAssumedInformation)) 6873 if (*SimpleV) 6874 return *SimpleV; 6875 return V; 6876 }; 6877 6878 const Function *F = getAnchorScope(); 6879 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F); 6880 return getAllocSize(AI.CB, TLI, Mapper); 6881 } 6882 6883 /// Collection of all malloc-like calls in a function with associated 6884 /// information. 6885 MapVector<CallBase *, AllocationInfo *> AllocationInfos; 6886 6887 /// Collection of all free-like calls in a function with associated 6888 /// information. 6889 MapVector<CallBase *, DeallocationInfo *> DeallocationInfos; 6890 6891 ChangeStatus updateImpl(Attributor &A) override; 6892 }; 6893 6894 ChangeStatus AAHeapToStackFunction::updateImpl(Attributor &A) { 6895 ChangeStatus Changed = ChangeStatus::UNCHANGED; 6896 const Function *F = getAnchorScope(); 6897 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F); 6898 6899 const auto *LivenessAA = 6900 A.getAAFor<AAIsDead>(*this, IRPosition::function(*F), DepClassTy::NONE); 6901 6902 MustBeExecutedContextExplorer *Explorer = 6903 A.getInfoCache().getMustBeExecutedContextExplorer(); 6904 6905 bool StackIsAccessibleByOtherThreads = 6906 A.getInfoCache().stackIsAccessibleByOtherThreads(); 6907 6908 LoopInfo *LI = 6909 A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(*F); 6910 std::optional<bool> MayContainIrreducibleControl; 6911 auto IsInLoop = [&](BasicBlock &BB) { 6912 if (&F->getEntryBlock() == &BB) 6913 return false; 6914 if (!MayContainIrreducibleControl.has_value()) 6915 MayContainIrreducibleControl = mayContainIrreducibleControl(*F, LI); 6916 if (*MayContainIrreducibleControl) 6917 return true; 6918 if (!LI) 6919 return true; 6920 return LI->getLoopFor(&BB) != nullptr; 6921 }; 6922 6923 // Flag to ensure we update our deallocation information at most once per 6924 // updateImpl call and only if we use the free check reasoning. 6925 bool HasUpdatedFrees = false; 6926 6927 auto UpdateFrees = [&]() { 6928 HasUpdatedFrees = true; 6929 6930 for (auto &It : DeallocationInfos) { 6931 DeallocationInfo &DI = *It.second; 6932 // For now we cannot use deallocations that have unknown inputs, skip 6933 // them. 6934 if (DI.MightFreeUnknownObjects) 6935 continue; 6936 6937 // No need to analyze dead calls, ignore them instead. 6938 bool UsedAssumedInformation = false; 6939 if (A.isAssumedDead(*DI.CB, this, LivenessAA, UsedAssumedInformation, 6940 /* CheckBBLivenessOnly */ true)) 6941 continue; 6942 6943 // Use the non-optimistic version to get the freed object. 6944 Value *Obj = getUnderlyingObject(DI.FreedOp); 6945 if (!Obj) { 6946 LLVM_DEBUG(dbgs() << "[H2S] Unknown underlying object for free!\n"); 6947 DI.MightFreeUnknownObjects = true; 6948 continue; 6949 } 6950 6951 // Free of null and undef can be ignored as no-ops (or UB in the latter 6952 // case). 6953 if (isa<ConstantPointerNull>(Obj) || isa<UndefValue>(Obj)) 6954 continue; 6955 6956 CallBase *ObjCB = dyn_cast<CallBase>(Obj); 6957 if (!ObjCB) { 6958 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-call object: " << *Obj 6959 << "\n"); 6960 DI.MightFreeUnknownObjects = true; 6961 continue; 6962 } 6963 6964 AllocationInfo *AI = AllocationInfos.lookup(ObjCB); 6965 if (!AI) { 6966 LLVM_DEBUG(dbgs() << "[H2S] Free of a non-allocation object: " << *Obj 6967 << "\n"); 6968 DI.MightFreeUnknownObjects = true; 6969 continue; 6970 } 6971 6972 DI.PotentialAllocationCalls.insert(ObjCB); 6973 } 6974 }; 6975 6976 auto FreeCheck = [&](AllocationInfo &AI) { 6977 // If the stack is not accessible by other threads, the "must-free" logic 6978 // doesn't apply as the pointer could be shared and needs to be places in 6979 // "shareable" memory. 6980 if (!StackIsAccessibleByOtherThreads) { 6981 bool IsKnownNoSycn; 6982 if (!AA::hasAssumedIRAttr<Attribute::NoSync>( 6983 A, this, getIRPosition(), DepClassTy::OPTIONAL, IsKnownNoSycn)) { 6984 LLVM_DEBUG( 6985 dbgs() << "[H2S] found an escaping use, stack is not accessible by " 6986 "other threads and function is not nosync:\n"); 6987 return false; 6988 } 6989 } 6990 if (!HasUpdatedFrees) 6991 UpdateFrees(); 6992 6993 // TODO: Allow multi exit functions that have different free calls. 6994 if (AI.PotentialFreeCalls.size() != 1) { 6995 LLVM_DEBUG(dbgs() << "[H2S] did not find one free call but " 6996 << AI.PotentialFreeCalls.size() << "\n"); 6997 return false; 6998 } 6999 CallBase *UniqueFree = *AI.PotentialFreeCalls.begin(); 7000 DeallocationInfo *DI = DeallocationInfos.lookup(UniqueFree); 7001 if (!DI) { 7002 LLVM_DEBUG( 7003 dbgs() << "[H2S] unique free call was not known as deallocation call " 7004 << *UniqueFree << "\n"); 7005 return false; 7006 } 7007 if (DI->MightFreeUnknownObjects) { 7008 LLVM_DEBUG( 7009 dbgs() << "[H2S] unique free call might free unknown allocations\n"); 7010 return false; 7011 } 7012 if (DI->PotentialAllocationCalls.empty()) 7013 return true; 7014 if (DI->PotentialAllocationCalls.size() > 1) { 7015 LLVM_DEBUG(dbgs() << "[H2S] unique free call might free " 7016 << DI->PotentialAllocationCalls.size() 7017 << " different allocations\n"); 7018 return false; 7019 } 7020 if (*DI->PotentialAllocationCalls.begin() != AI.CB) { 7021 LLVM_DEBUG( 7022 dbgs() 7023 << "[H2S] unique free call not known to free this allocation but " 7024 << **DI->PotentialAllocationCalls.begin() << "\n"); 7025 return false; 7026 } 7027 7028 // __kmpc_alloc_shared and __kmpc_alloc_free are by construction matched. 7029 if (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared) { 7030 Instruction *CtxI = isa<InvokeInst>(AI.CB) ? AI.CB : AI.CB->getNextNode(); 7031 if (!Explorer || !Explorer->findInContextOf(UniqueFree, CtxI)) { 7032 LLVM_DEBUG(dbgs() << "[H2S] unique free call might not be executed " 7033 "with the allocation " 7034 << *UniqueFree << "\n"); 7035 return false; 7036 } 7037 } 7038 return true; 7039 }; 7040 7041 auto UsesCheck = [&](AllocationInfo &AI) { 7042 bool ValidUsesOnly = true; 7043 7044 auto Pred = [&](const Use &U, bool &Follow) -> bool { 7045 Instruction *UserI = cast<Instruction>(U.getUser()); 7046 if (isa<LoadInst>(UserI)) 7047 return true; 7048 if (auto *SI = dyn_cast<StoreInst>(UserI)) { 7049 if (SI->getValueOperand() == U.get()) { 7050 LLVM_DEBUG(dbgs() 7051 << "[H2S] escaping store to memory: " << *UserI << "\n"); 7052 ValidUsesOnly = false; 7053 } else { 7054 // A store into the malloc'ed memory is fine. 7055 } 7056 return true; 7057 } 7058 if (auto *CB = dyn_cast<CallBase>(UserI)) { 7059 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd()) 7060 return true; 7061 if (DeallocationInfos.count(CB)) { 7062 AI.PotentialFreeCalls.insert(CB); 7063 return true; 7064 } 7065 7066 unsigned ArgNo = CB->getArgOperandNo(&U); 7067 auto CBIRP = IRPosition::callsite_argument(*CB, ArgNo); 7068 7069 bool IsKnownNoCapture; 7070 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>( 7071 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoCapture); 7072 7073 // If a call site argument use is nofree, we are fine. 7074 bool IsKnownNoFree; 7075 bool IsAssumedNoFree = AA::hasAssumedIRAttr<Attribute::NoFree>( 7076 A, this, CBIRP, DepClassTy::OPTIONAL, IsKnownNoFree); 7077 7078 if (!IsAssumedNoCapture || 7079 (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared && 7080 !IsAssumedNoFree)) { 7081 AI.HasPotentiallyFreeingUnknownUses |= !IsAssumedNoFree; 7082 7083 // Emit a missed remark if this is missed OpenMP globalization. 7084 auto Remark = [&](OptimizationRemarkMissed ORM) { 7085 return ORM 7086 << "Could not move globalized variable to the stack. " 7087 "Variable is potentially captured in call. Mark " 7088 "parameter as `__attribute__((noescape))` to override."; 7089 }; 7090 7091 if (ValidUsesOnly && 7092 AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared) 7093 A.emitRemark<OptimizationRemarkMissed>(CB, "OMP113", Remark); 7094 7095 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n"); 7096 ValidUsesOnly = false; 7097 } 7098 return true; 7099 } 7100 7101 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) || 7102 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) { 7103 Follow = true; 7104 return true; 7105 } 7106 // Unknown user for which we can not track uses further (in a way that 7107 // makes sense). 7108 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n"); 7109 ValidUsesOnly = false; 7110 return true; 7111 }; 7112 if (!A.checkForAllUses(Pred, *this, *AI.CB, /* CheckBBLivenessOnly */ false, 7113 DepClassTy::OPTIONAL, /* IgnoreDroppableUses */ true, 7114 [&](const Use &OldU, const Use &NewU) { 7115 auto *SI = dyn_cast<StoreInst>(OldU.getUser()); 7116 return !SI || StackIsAccessibleByOtherThreads || 7117 AA::isAssumedThreadLocalObject( 7118 A, *SI->getPointerOperand(), *this); 7119 })) 7120 return false; 7121 return ValidUsesOnly; 7122 }; 7123 7124 // The actual update starts here. We look at all allocations and depending on 7125 // their status perform the appropriate check(s). 7126 for (auto &It : AllocationInfos) { 7127 AllocationInfo &AI = *It.second; 7128 if (AI.Status == AllocationInfo::INVALID) 7129 continue; 7130 7131 if (Value *Align = getAllocAlignment(AI.CB, TLI)) { 7132 std::optional<APInt> APAlign = getAPInt(A, *this, *Align); 7133 if (!APAlign) { 7134 // Can't generate an alloca which respects the required alignment 7135 // on the allocation. 7136 LLVM_DEBUG(dbgs() << "[H2S] Unknown allocation alignment: " << *AI.CB 7137 << "\n"); 7138 AI.Status = AllocationInfo::INVALID; 7139 Changed = ChangeStatus::CHANGED; 7140 continue; 7141 } 7142 if (APAlign->ugt(llvm::Value::MaximumAlignment) || 7143 !APAlign->isPowerOf2()) { 7144 LLVM_DEBUG(dbgs() << "[H2S] Invalid allocation alignment: " << APAlign 7145 << "\n"); 7146 AI.Status = AllocationInfo::INVALID; 7147 Changed = ChangeStatus::CHANGED; 7148 continue; 7149 } 7150 } 7151 7152 std::optional<APInt> Size = getSize(A, *this, AI); 7153 if (AI.LibraryFunctionId != LibFunc___kmpc_alloc_shared && 7154 MaxHeapToStackSize != -1) { 7155 if (!Size || Size->ugt(MaxHeapToStackSize)) { 7156 LLVM_DEBUG({ 7157 if (!Size) 7158 dbgs() << "[H2S] Unknown allocation size: " << *AI.CB << "\n"; 7159 else 7160 dbgs() << "[H2S] Allocation size too large: " << *AI.CB << " vs. " 7161 << MaxHeapToStackSize << "\n"; 7162 }); 7163 7164 AI.Status = AllocationInfo::INVALID; 7165 Changed = ChangeStatus::CHANGED; 7166 continue; 7167 } 7168 } 7169 7170 switch (AI.Status) { 7171 case AllocationInfo::STACK_DUE_TO_USE: 7172 if (UsesCheck(AI)) 7173 break; 7174 AI.Status = AllocationInfo::STACK_DUE_TO_FREE; 7175 [[fallthrough]]; 7176 case AllocationInfo::STACK_DUE_TO_FREE: 7177 if (FreeCheck(AI)) 7178 break; 7179 AI.Status = AllocationInfo::INVALID; 7180 Changed = ChangeStatus::CHANGED; 7181 break; 7182 case AllocationInfo::INVALID: 7183 llvm_unreachable("Invalid allocations should never reach this point!"); 7184 }; 7185 7186 // Check if we still think we can move it into the entry block. If the 7187 // alloca comes from a converted __kmpc_alloc_shared then we can usually 7188 // ignore the potential compilations associated with loops. 7189 bool IsGlobalizedLocal = 7190 AI.LibraryFunctionId == LibFunc___kmpc_alloc_shared; 7191 if (AI.MoveAllocaIntoEntry && 7192 (!Size.has_value() || 7193 (!IsGlobalizedLocal && IsInLoop(*AI.CB->getParent())))) 7194 AI.MoveAllocaIntoEntry = false; 7195 } 7196 7197 return Changed; 7198 } 7199 } // namespace 7200 7201 /// ----------------------- Privatizable Pointers ------------------------------ 7202 namespace { 7203 struct AAPrivatizablePtrImpl : public AAPrivatizablePtr { 7204 AAPrivatizablePtrImpl(const IRPosition &IRP, Attributor &A) 7205 : AAPrivatizablePtr(IRP, A), PrivatizableType(std::nullopt) {} 7206 7207 ChangeStatus indicatePessimisticFixpoint() override { 7208 AAPrivatizablePtr::indicatePessimisticFixpoint(); 7209 PrivatizableType = nullptr; 7210 return ChangeStatus::CHANGED; 7211 } 7212 7213 /// Identify the type we can chose for a private copy of the underlying 7214 /// argument. std::nullopt means it is not clear yet, nullptr means there is 7215 /// none. 7216 virtual std::optional<Type *> identifyPrivatizableType(Attributor &A) = 0; 7217 7218 /// Return a privatizable type that encloses both T0 and T1. 7219 /// TODO: This is merely a stub for now as we should manage a mapping as well. 7220 std::optional<Type *> combineTypes(std::optional<Type *> T0, 7221 std::optional<Type *> T1) { 7222 if (!T0) 7223 return T1; 7224 if (!T1) 7225 return T0; 7226 if (T0 == T1) 7227 return T0; 7228 return nullptr; 7229 } 7230 7231 std::optional<Type *> getPrivatizableType() const override { 7232 return PrivatizableType; 7233 } 7234 7235 const std::string getAsStr(Attributor *A) const override { 7236 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]"; 7237 } 7238 7239 protected: 7240 std::optional<Type *> PrivatizableType; 7241 }; 7242 7243 // TODO: Do this for call site arguments (probably also other values) as well. 7244 7245 struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl { 7246 AAPrivatizablePtrArgument(const IRPosition &IRP, Attributor &A) 7247 : AAPrivatizablePtrImpl(IRP, A) {} 7248 7249 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...) 7250 std::optional<Type *> identifyPrivatizableType(Attributor &A) override { 7251 // If this is a byval argument and we know all the call sites (so we can 7252 // rewrite them), there is no need to check them explicitly. 7253 bool UsedAssumedInformation = false; 7254 SmallVector<Attribute, 1> Attrs; 7255 A.getAttrs(getIRPosition(), {Attribute::ByVal}, Attrs, 7256 /* IgnoreSubsumingPositions */ true); 7257 if (!Attrs.empty() && 7258 A.checkForAllCallSites([](AbstractCallSite ACS) { return true; }, *this, 7259 true, UsedAssumedInformation)) 7260 return Attrs[0].getValueAsType(); 7261 7262 std::optional<Type *> Ty; 7263 unsigned ArgNo = getIRPosition().getCallSiteArgNo(); 7264 7265 // Make sure the associated call site argument has the same type at all call 7266 // sites and it is an allocation we know is safe to privatize, for now that 7267 // means we only allow alloca instructions. 7268 // TODO: We can additionally analyze the accesses in the callee to create 7269 // the type from that information instead. That is a little more 7270 // involved and will be done in a follow up patch. 7271 auto CallSiteCheck = [&](AbstractCallSite ACS) { 7272 IRPosition ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo); 7273 // Check if a coresponding argument was found or if it is one not 7274 // associated (which can happen for callback calls). 7275 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID) 7276 return false; 7277 7278 // Check that all call sites agree on a type. 7279 auto *PrivCSArgAA = 7280 A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos, DepClassTy::REQUIRED); 7281 if (!PrivCSArgAA) 7282 return false; 7283 std::optional<Type *> CSTy = PrivCSArgAA->getPrivatizableType(); 7284 7285 LLVM_DEBUG({ 7286 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: "; 7287 if (CSTy && *CSTy) 7288 (*CSTy)->print(dbgs()); 7289 else if (CSTy) 7290 dbgs() << "<nullptr>"; 7291 else 7292 dbgs() << "<none>"; 7293 }); 7294 7295 Ty = combineTypes(Ty, CSTy); 7296 7297 LLVM_DEBUG({ 7298 dbgs() << " : New Type: "; 7299 if (Ty && *Ty) 7300 (*Ty)->print(dbgs()); 7301 else if (Ty) 7302 dbgs() << "<nullptr>"; 7303 else 7304 dbgs() << "<none>"; 7305 dbgs() << "\n"; 7306 }); 7307 7308 return !Ty || *Ty; 7309 }; 7310 7311 if (!A.checkForAllCallSites(CallSiteCheck, *this, true, 7312 UsedAssumedInformation)) 7313 return nullptr; 7314 return Ty; 7315 } 7316 7317 /// See AbstractAttribute::updateImpl(...). 7318 ChangeStatus updateImpl(Attributor &A) override { 7319 PrivatizableType = identifyPrivatizableType(A); 7320 if (!PrivatizableType) 7321 return ChangeStatus::UNCHANGED; 7322 if (!*PrivatizableType) 7323 return indicatePessimisticFixpoint(); 7324 7325 // The dependence is optional so we don't give up once we give up on the 7326 // alignment. 7327 A.getAAFor<AAAlign>(*this, IRPosition::value(getAssociatedValue()), 7328 DepClassTy::OPTIONAL); 7329 7330 // Avoid arguments with padding for now. 7331 if (!A.hasAttr(getIRPosition(), Attribute::ByVal) && 7332 !isDenselyPacked(*PrivatizableType, A.getInfoCache().getDL())) { 7333 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n"); 7334 return indicatePessimisticFixpoint(); 7335 } 7336 7337 // Collect the types that will replace the privatizable type in the function 7338 // signature. 7339 SmallVector<Type *, 16> ReplacementTypes; 7340 identifyReplacementTypes(*PrivatizableType, ReplacementTypes); 7341 7342 // Verify callee and caller agree on how the promoted argument would be 7343 // passed. 7344 Function &Fn = *getIRPosition().getAnchorScope(); 7345 const auto *TTI = 7346 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn); 7347 if (!TTI) { 7348 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Missing TTI for function " 7349 << Fn.getName() << "\n"); 7350 return indicatePessimisticFixpoint(); 7351 } 7352 7353 auto CallSiteCheck = [&](AbstractCallSite ACS) { 7354 CallBase *CB = ACS.getInstruction(); 7355 return TTI->areTypesABICompatible( 7356 CB->getCaller(), 7357 dyn_cast_if_present<Function>(CB->getCalledOperand()), 7358 ReplacementTypes); 7359 }; 7360 bool UsedAssumedInformation = false; 7361 if (!A.checkForAllCallSites(CallSiteCheck, *this, true, 7362 UsedAssumedInformation)) { 7363 LLVM_DEBUG( 7364 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for " 7365 << Fn.getName() << "\n"); 7366 return indicatePessimisticFixpoint(); 7367 } 7368 7369 // Register a rewrite of the argument. 7370 Argument *Arg = getAssociatedArgument(); 7371 if (!A.isValidFunctionSignatureRewrite(*Arg, ReplacementTypes)) { 7372 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n"); 7373 return indicatePessimisticFixpoint(); 7374 } 7375 7376 unsigned ArgNo = Arg->getArgNo(); 7377 7378 // Helper to check if for the given call site the associated argument is 7379 // passed to a callback where the privatization would be different. 7380 auto IsCompatiblePrivArgOfCallback = [&](CallBase &CB) { 7381 SmallVector<const Use *, 4> CallbackUses; 7382 AbstractCallSite::getCallbackUses(CB, CallbackUses); 7383 for (const Use *U : CallbackUses) { 7384 AbstractCallSite CBACS(U); 7385 assert(CBACS && CBACS.isCallbackCall()); 7386 for (Argument &CBArg : CBACS.getCalledFunction()->args()) { 7387 int CBArgNo = CBACS.getCallArgOperandNo(CBArg); 7388 7389 LLVM_DEBUG({ 7390 dbgs() 7391 << "[AAPrivatizablePtr] Argument " << *Arg 7392 << "check if can be privatized in the context of its parent (" 7393 << Arg->getParent()->getName() 7394 << ")\n[AAPrivatizablePtr] because it is an argument in a " 7395 "callback (" 7396 << CBArgNo << "@" << CBACS.getCalledFunction()->getName() 7397 << ")\n[AAPrivatizablePtr] " << CBArg << " : " 7398 << CBACS.getCallArgOperand(CBArg) << " vs " 7399 << CB.getArgOperand(ArgNo) << "\n" 7400 << "[AAPrivatizablePtr] " << CBArg << " : " 7401 << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n"; 7402 }); 7403 7404 if (CBArgNo != int(ArgNo)) 7405 continue; 7406 const auto *CBArgPrivAA = A.getAAFor<AAPrivatizablePtr>( 7407 *this, IRPosition::argument(CBArg), DepClassTy::REQUIRED); 7408 if (CBArgPrivAA && CBArgPrivAA->isValidState()) { 7409 auto CBArgPrivTy = CBArgPrivAA->getPrivatizableType(); 7410 if (!CBArgPrivTy) 7411 continue; 7412 if (*CBArgPrivTy == PrivatizableType) 7413 continue; 7414 } 7415 7416 LLVM_DEBUG({ 7417 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg 7418 << " cannot be privatized in the context of its parent (" 7419 << Arg->getParent()->getName() 7420 << ")\n[AAPrivatizablePtr] because it is an argument in a " 7421 "callback (" 7422 << CBArgNo << "@" << CBACS.getCalledFunction()->getName() 7423 << ").\n[AAPrivatizablePtr] for which the argument " 7424 "privatization is not compatible.\n"; 7425 }); 7426 return false; 7427 } 7428 } 7429 return true; 7430 }; 7431 7432 // Helper to check if for the given call site the associated argument is 7433 // passed to a direct call where the privatization would be different. 7434 auto IsCompatiblePrivArgOfDirectCS = [&](AbstractCallSite ACS) { 7435 CallBase *DC = cast<CallBase>(ACS.getInstruction()); 7436 int DCArgNo = ACS.getCallArgOperandNo(ArgNo); 7437 assert(DCArgNo >= 0 && unsigned(DCArgNo) < DC->arg_size() && 7438 "Expected a direct call operand for callback call operand"); 7439 7440 Function *DCCallee = 7441 dyn_cast_if_present<Function>(DC->getCalledOperand()); 7442 LLVM_DEBUG({ 7443 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg 7444 << " check if be privatized in the context of its parent (" 7445 << Arg->getParent()->getName() 7446 << ")\n[AAPrivatizablePtr] because it is an argument in a " 7447 "direct call of (" 7448 << DCArgNo << "@" << DCCallee->getName() << ").\n"; 7449 }); 7450 7451 if (unsigned(DCArgNo) < DCCallee->arg_size()) { 7452 const auto *DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>( 7453 *this, IRPosition::argument(*DCCallee->getArg(DCArgNo)), 7454 DepClassTy::REQUIRED); 7455 if (DCArgPrivAA && DCArgPrivAA->isValidState()) { 7456 auto DCArgPrivTy = DCArgPrivAA->getPrivatizableType(); 7457 if (!DCArgPrivTy) 7458 return true; 7459 if (*DCArgPrivTy == PrivatizableType) 7460 return true; 7461 } 7462 } 7463 7464 LLVM_DEBUG({ 7465 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg 7466 << " cannot be privatized in the context of its parent (" 7467 << Arg->getParent()->getName() 7468 << ")\n[AAPrivatizablePtr] because it is an argument in a " 7469 "direct call of (" 7470 << ACS.getInstruction()->getCalledOperand()->getName() 7471 << ").\n[AAPrivatizablePtr] for which the argument " 7472 "privatization is not compatible.\n"; 7473 }); 7474 return false; 7475 }; 7476 7477 // Helper to check if the associated argument is used at the given abstract 7478 // call site in a way that is incompatible with the privatization assumed 7479 // here. 7480 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) { 7481 if (ACS.isDirectCall()) 7482 return IsCompatiblePrivArgOfCallback(*ACS.getInstruction()); 7483 if (ACS.isCallbackCall()) 7484 return IsCompatiblePrivArgOfDirectCS(ACS); 7485 return false; 7486 }; 7487 7488 if (!A.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite, *this, true, 7489 UsedAssumedInformation)) 7490 return indicatePessimisticFixpoint(); 7491 7492 return ChangeStatus::UNCHANGED; 7493 } 7494 7495 /// Given a type to private \p PrivType, collect the constituates (which are 7496 /// used) in \p ReplacementTypes. 7497 static void 7498 identifyReplacementTypes(Type *PrivType, 7499 SmallVectorImpl<Type *> &ReplacementTypes) { 7500 // TODO: For now we expand the privatization type to the fullest which can 7501 // lead to dead arguments that need to be removed later. 7502 assert(PrivType && "Expected privatizable type!"); 7503 7504 // Traverse the type, extract constituate types on the outermost level. 7505 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) { 7506 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) 7507 ReplacementTypes.push_back(PrivStructType->getElementType(u)); 7508 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) { 7509 ReplacementTypes.append(PrivArrayType->getNumElements(), 7510 PrivArrayType->getElementType()); 7511 } else { 7512 ReplacementTypes.push_back(PrivType); 7513 } 7514 } 7515 7516 /// Initialize \p Base according to the type \p PrivType at position \p IP. 7517 /// The values needed are taken from the arguments of \p F starting at 7518 /// position \p ArgNo. 7519 static void createInitialization(Type *PrivType, Value &Base, Function &F, 7520 unsigned ArgNo, BasicBlock::iterator IP) { 7521 assert(PrivType && "Expected privatizable type!"); 7522 7523 IRBuilder<NoFolder> IRB(IP->getParent(), IP); 7524 const DataLayout &DL = F.getDataLayout(); 7525 7526 // Traverse the type, build GEPs and stores. 7527 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) { 7528 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType); 7529 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) { 7530 Value *Ptr = 7531 constructPointer(&Base, PrivStructLayout->getElementOffset(u), IRB); 7532 new StoreInst(F.getArg(ArgNo + u), Ptr, IP); 7533 } 7534 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) { 7535 Type *PointeeTy = PrivArrayType->getElementType(); 7536 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy); 7537 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) { 7538 Value *Ptr = constructPointer(&Base, u * PointeeTySize, IRB); 7539 new StoreInst(F.getArg(ArgNo + u), Ptr, IP); 7540 } 7541 } else { 7542 new StoreInst(F.getArg(ArgNo), &Base, IP); 7543 } 7544 } 7545 7546 /// Extract values from \p Base according to the type \p PrivType at the 7547 /// call position \p ACS. The values are appended to \p ReplacementValues. 7548 void createReplacementValues(Align Alignment, Type *PrivType, 7549 AbstractCallSite ACS, Value *Base, 7550 SmallVectorImpl<Value *> &ReplacementValues) { 7551 assert(Base && "Expected base value!"); 7552 assert(PrivType && "Expected privatizable type!"); 7553 Instruction *IP = ACS.getInstruction(); 7554 7555 IRBuilder<NoFolder> IRB(IP); 7556 const DataLayout &DL = IP->getDataLayout(); 7557 7558 // Traverse the type, build GEPs and loads. 7559 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) { 7560 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType); 7561 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) { 7562 Type *PointeeTy = PrivStructType->getElementType(u); 7563 Value *Ptr = 7564 constructPointer(Base, PrivStructLayout->getElementOffset(u), IRB); 7565 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator()); 7566 L->setAlignment(Alignment); 7567 ReplacementValues.push_back(L); 7568 } 7569 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) { 7570 Type *PointeeTy = PrivArrayType->getElementType(); 7571 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy); 7572 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) { 7573 Value *Ptr = constructPointer(Base, u * PointeeTySize, IRB); 7574 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP->getIterator()); 7575 L->setAlignment(Alignment); 7576 ReplacementValues.push_back(L); 7577 } 7578 } else { 7579 LoadInst *L = new LoadInst(PrivType, Base, "", IP->getIterator()); 7580 L->setAlignment(Alignment); 7581 ReplacementValues.push_back(L); 7582 } 7583 } 7584 7585 /// See AbstractAttribute::manifest(...) 7586 ChangeStatus manifest(Attributor &A) override { 7587 if (!PrivatizableType) 7588 return ChangeStatus::UNCHANGED; 7589 assert(*PrivatizableType && "Expected privatizable type!"); 7590 7591 // Collect all tail calls in the function as we cannot allow new allocas to 7592 // escape into tail recursion. 7593 // TODO: Be smarter about new allocas escaping into tail calls. 7594 SmallVector<CallInst *, 16> TailCalls; 7595 bool UsedAssumedInformation = false; 7596 if (!A.checkForAllInstructions( 7597 [&](Instruction &I) { 7598 CallInst &CI = cast<CallInst>(I); 7599 if (CI.isTailCall()) 7600 TailCalls.push_back(&CI); 7601 return true; 7602 }, 7603 *this, {Instruction::Call}, UsedAssumedInformation)) 7604 return ChangeStatus::UNCHANGED; 7605 7606 Argument *Arg = getAssociatedArgument(); 7607 // Query AAAlign attribute for alignment of associated argument to 7608 // determine the best alignment of loads. 7609 const auto *AlignAA = 7610 A.getAAFor<AAAlign>(*this, IRPosition::value(*Arg), DepClassTy::NONE); 7611 7612 // Callback to repair the associated function. A new alloca is placed at the 7613 // beginning and initialized with the values passed through arguments. The 7614 // new alloca replaces the use of the old pointer argument. 7615 Attributor::ArgumentReplacementInfo::CalleeRepairCBTy FnRepairCB = 7616 [=](const Attributor::ArgumentReplacementInfo &ARI, 7617 Function &ReplacementFn, Function::arg_iterator ArgIt) { 7618 BasicBlock &EntryBB = ReplacementFn.getEntryBlock(); 7619 BasicBlock::iterator IP = EntryBB.getFirstInsertionPt(); 7620 const DataLayout &DL = IP->getDataLayout(); 7621 unsigned AS = DL.getAllocaAddrSpace(); 7622 Instruction *AI = new AllocaInst(*PrivatizableType, AS, 7623 Arg->getName() + ".priv", IP); 7624 createInitialization(*PrivatizableType, *AI, ReplacementFn, 7625 ArgIt->getArgNo(), IP); 7626 7627 if (AI->getType() != Arg->getType()) 7628 AI = BitCastInst::CreatePointerBitCastOrAddrSpaceCast( 7629 AI, Arg->getType(), "", IP); 7630 Arg->replaceAllUsesWith(AI); 7631 7632 for (CallInst *CI : TailCalls) 7633 CI->setTailCall(false); 7634 }; 7635 7636 // Callback to repair a call site of the associated function. The elements 7637 // of the privatizable type are loaded prior to the call and passed to the 7638 // new function version. 7639 Attributor::ArgumentReplacementInfo::ACSRepairCBTy ACSRepairCB = 7640 [=](const Attributor::ArgumentReplacementInfo &ARI, 7641 AbstractCallSite ACS, SmallVectorImpl<Value *> &NewArgOperands) { 7642 // When no alignment is specified for the load instruction, 7643 // natural alignment is assumed. 7644 createReplacementValues( 7645 AlignAA ? AlignAA->getAssumedAlign() : Align(0), 7646 *PrivatizableType, ACS, 7647 ACS.getCallArgOperand(ARI.getReplacedArg().getArgNo()), 7648 NewArgOperands); 7649 }; 7650 7651 // Collect the types that will replace the privatizable type in the function 7652 // signature. 7653 SmallVector<Type *, 16> ReplacementTypes; 7654 identifyReplacementTypes(*PrivatizableType, ReplacementTypes); 7655 7656 // Register a rewrite of the argument. 7657 if (A.registerFunctionSignatureRewrite(*Arg, ReplacementTypes, 7658 std::move(FnRepairCB), 7659 std::move(ACSRepairCB))) 7660 return ChangeStatus::CHANGED; 7661 return ChangeStatus::UNCHANGED; 7662 } 7663 7664 /// See AbstractAttribute::trackStatistics() 7665 void trackStatistics() const override { 7666 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr); 7667 } 7668 }; 7669 7670 struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl { 7671 AAPrivatizablePtrFloating(const IRPosition &IRP, Attributor &A) 7672 : AAPrivatizablePtrImpl(IRP, A) {} 7673 7674 /// See AbstractAttribute::initialize(...). 7675 void initialize(Attributor &A) override { 7676 // TODO: We can privatize more than arguments. 7677 indicatePessimisticFixpoint(); 7678 } 7679 7680 ChangeStatus updateImpl(Attributor &A) override { 7681 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::" 7682 "updateImpl will not be called"); 7683 } 7684 7685 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...) 7686 std::optional<Type *> identifyPrivatizableType(Attributor &A) override { 7687 Value *Obj = getUnderlyingObject(&getAssociatedValue()); 7688 if (!Obj) { 7689 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n"); 7690 return nullptr; 7691 } 7692 7693 if (auto *AI = dyn_cast<AllocaInst>(Obj)) 7694 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize())) 7695 if (CI->isOne()) 7696 return AI->getAllocatedType(); 7697 if (auto *Arg = dyn_cast<Argument>(Obj)) { 7698 auto *PrivArgAA = A.getAAFor<AAPrivatizablePtr>( 7699 *this, IRPosition::argument(*Arg), DepClassTy::REQUIRED); 7700 if (PrivArgAA && PrivArgAA->isAssumedPrivatizablePtr()) 7701 return PrivArgAA->getPrivatizableType(); 7702 } 7703 7704 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid " 7705 "alloca nor privatizable argument: " 7706 << *Obj << "!\n"); 7707 return nullptr; 7708 } 7709 7710 /// See AbstractAttribute::trackStatistics() 7711 void trackStatistics() const override { 7712 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr); 7713 } 7714 }; 7715 7716 struct AAPrivatizablePtrCallSiteArgument final 7717 : public AAPrivatizablePtrFloating { 7718 AAPrivatizablePtrCallSiteArgument(const IRPosition &IRP, Attributor &A) 7719 : AAPrivatizablePtrFloating(IRP, A) {} 7720 7721 /// See AbstractAttribute::initialize(...). 7722 void initialize(Attributor &A) override { 7723 if (A.hasAttr(getIRPosition(), Attribute::ByVal)) 7724 indicateOptimisticFixpoint(); 7725 } 7726 7727 /// See AbstractAttribute::updateImpl(...). 7728 ChangeStatus updateImpl(Attributor &A) override { 7729 PrivatizableType = identifyPrivatizableType(A); 7730 if (!PrivatizableType) 7731 return ChangeStatus::UNCHANGED; 7732 if (!*PrivatizableType) 7733 return indicatePessimisticFixpoint(); 7734 7735 const IRPosition &IRP = getIRPosition(); 7736 bool IsKnownNoCapture; 7737 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>( 7738 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoCapture); 7739 if (!IsAssumedNoCapture) { 7740 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n"); 7741 return indicatePessimisticFixpoint(); 7742 } 7743 7744 bool IsKnownNoAlias; 7745 if (!AA::hasAssumedIRAttr<Attribute::NoAlias>( 7746 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoAlias)) { 7747 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n"); 7748 return indicatePessimisticFixpoint(); 7749 } 7750 7751 bool IsKnown; 7752 if (!AA::isAssumedReadOnly(A, IRP, *this, IsKnown)) { 7753 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n"); 7754 return indicatePessimisticFixpoint(); 7755 } 7756 7757 return ChangeStatus::UNCHANGED; 7758 } 7759 7760 /// See AbstractAttribute::trackStatistics() 7761 void trackStatistics() const override { 7762 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr); 7763 } 7764 }; 7765 7766 struct AAPrivatizablePtrCallSiteReturned final 7767 : public AAPrivatizablePtrFloating { 7768 AAPrivatizablePtrCallSiteReturned(const IRPosition &IRP, Attributor &A) 7769 : AAPrivatizablePtrFloating(IRP, A) {} 7770 7771 /// See AbstractAttribute::initialize(...). 7772 void initialize(Attributor &A) override { 7773 // TODO: We can privatize more than arguments. 7774 indicatePessimisticFixpoint(); 7775 } 7776 7777 /// See AbstractAttribute::trackStatistics() 7778 void trackStatistics() const override { 7779 STATS_DECLTRACK_CSRET_ATTR(privatizable_ptr); 7780 } 7781 }; 7782 7783 struct AAPrivatizablePtrReturned final : public AAPrivatizablePtrFloating { 7784 AAPrivatizablePtrReturned(const IRPosition &IRP, Attributor &A) 7785 : AAPrivatizablePtrFloating(IRP, A) {} 7786 7787 /// See AbstractAttribute::initialize(...). 7788 void initialize(Attributor &A) override { 7789 // TODO: We can privatize more than arguments. 7790 indicatePessimisticFixpoint(); 7791 } 7792 7793 /// See AbstractAttribute::trackStatistics() 7794 void trackStatistics() const override { 7795 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr); 7796 } 7797 }; 7798 } // namespace 7799 7800 /// -------------------- Memory Behavior Attributes ---------------------------- 7801 /// Includes read-none, read-only, and write-only. 7802 /// ---------------------------------------------------------------------------- 7803 namespace { 7804 struct AAMemoryBehaviorImpl : public AAMemoryBehavior { 7805 AAMemoryBehaviorImpl(const IRPosition &IRP, Attributor &A) 7806 : AAMemoryBehavior(IRP, A) {} 7807 7808 /// See AbstractAttribute::initialize(...). 7809 void initialize(Attributor &A) override { 7810 intersectAssumedBits(BEST_STATE); 7811 getKnownStateFromValue(A, getIRPosition(), getState()); 7812 AAMemoryBehavior::initialize(A); 7813 } 7814 7815 /// Return the memory behavior information encoded in the IR for \p IRP. 7816 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP, 7817 BitIntegerState &State, 7818 bool IgnoreSubsumingPositions = false) { 7819 SmallVector<Attribute, 2> Attrs; 7820 A.getAttrs(IRP, AttrKinds, Attrs, IgnoreSubsumingPositions); 7821 for (const Attribute &Attr : Attrs) { 7822 switch (Attr.getKindAsEnum()) { 7823 case Attribute::ReadNone: 7824 State.addKnownBits(NO_ACCESSES); 7825 break; 7826 case Attribute::ReadOnly: 7827 State.addKnownBits(NO_WRITES); 7828 break; 7829 case Attribute::WriteOnly: 7830 State.addKnownBits(NO_READS); 7831 break; 7832 default: 7833 llvm_unreachable("Unexpected attribute!"); 7834 } 7835 } 7836 7837 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) { 7838 if (!I->mayReadFromMemory()) 7839 State.addKnownBits(NO_READS); 7840 if (!I->mayWriteToMemory()) 7841 State.addKnownBits(NO_WRITES); 7842 } 7843 } 7844 7845 /// See AbstractAttribute::getDeducedAttributes(...). 7846 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, 7847 SmallVectorImpl<Attribute> &Attrs) const override { 7848 assert(Attrs.size() == 0); 7849 if (isAssumedReadNone()) 7850 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone)); 7851 else if (isAssumedReadOnly()) 7852 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly)); 7853 else if (isAssumedWriteOnly()) 7854 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly)); 7855 assert(Attrs.size() <= 1); 7856 } 7857 7858 /// See AbstractAttribute::manifest(...). 7859 ChangeStatus manifest(Attributor &A) override { 7860 const IRPosition &IRP = getIRPosition(); 7861 7862 if (A.hasAttr(IRP, Attribute::ReadNone, 7863 /* IgnoreSubsumingPositions */ true)) 7864 return ChangeStatus::UNCHANGED; 7865 7866 // Check if we would improve the existing attributes first. 7867 SmallVector<Attribute, 4> DeducedAttrs; 7868 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs); 7869 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) { 7870 return A.hasAttr(IRP, Attr.getKindAsEnum(), 7871 /* IgnoreSubsumingPositions */ true); 7872 })) 7873 return ChangeStatus::UNCHANGED; 7874 7875 // Clear existing attributes. 7876 A.removeAttrs(IRP, AttrKinds); 7877 // Clear conflicting writable attribute. 7878 if (isAssumedReadOnly()) 7879 A.removeAttrs(IRP, Attribute::Writable); 7880 7881 // Use the generic manifest method. 7882 return IRAttribute::manifest(A); 7883 } 7884 7885 /// See AbstractState::getAsStr(). 7886 const std::string getAsStr(Attributor *A) const override { 7887 if (isAssumedReadNone()) 7888 return "readnone"; 7889 if (isAssumedReadOnly()) 7890 return "readonly"; 7891 if (isAssumedWriteOnly()) 7892 return "writeonly"; 7893 return "may-read/write"; 7894 } 7895 7896 /// The set of IR attributes AAMemoryBehavior deals with. 7897 static const Attribute::AttrKind AttrKinds[3]; 7898 }; 7899 7900 const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = { 7901 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly}; 7902 7903 /// Memory behavior attribute for a floating value. 7904 struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl { 7905 AAMemoryBehaviorFloating(const IRPosition &IRP, Attributor &A) 7906 : AAMemoryBehaviorImpl(IRP, A) {} 7907 7908 /// See AbstractAttribute::updateImpl(...). 7909 ChangeStatus updateImpl(Attributor &A) override; 7910 7911 /// See AbstractAttribute::trackStatistics() 7912 void trackStatistics() const override { 7913 if (isAssumedReadNone()) 7914 STATS_DECLTRACK_FLOATING_ATTR(readnone) 7915 else if (isAssumedReadOnly()) 7916 STATS_DECLTRACK_FLOATING_ATTR(readonly) 7917 else if (isAssumedWriteOnly()) 7918 STATS_DECLTRACK_FLOATING_ATTR(writeonly) 7919 } 7920 7921 private: 7922 /// Return true if users of \p UserI might access the underlying 7923 /// variable/location described by \p U and should therefore be analyzed. 7924 bool followUsersOfUseIn(Attributor &A, const Use &U, 7925 const Instruction *UserI); 7926 7927 /// Update the state according to the effect of use \p U in \p UserI. 7928 void analyzeUseIn(Attributor &A, const Use &U, const Instruction *UserI); 7929 }; 7930 7931 /// Memory behavior attribute for function argument. 7932 struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating { 7933 AAMemoryBehaviorArgument(const IRPosition &IRP, Attributor &A) 7934 : AAMemoryBehaviorFloating(IRP, A) {} 7935 7936 /// See AbstractAttribute::initialize(...). 7937 void initialize(Attributor &A) override { 7938 intersectAssumedBits(BEST_STATE); 7939 const IRPosition &IRP = getIRPosition(); 7940 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we 7941 // can query it when we use has/getAttr. That would allow us to reuse the 7942 // initialize of the base class here. 7943 bool HasByVal = A.hasAttr(IRP, {Attribute::ByVal}, 7944 /* IgnoreSubsumingPositions */ true); 7945 getKnownStateFromValue(A, IRP, getState(), 7946 /* IgnoreSubsumingPositions */ HasByVal); 7947 } 7948 7949 ChangeStatus manifest(Attributor &A) override { 7950 // TODO: Pointer arguments are not supported on vectors of pointers yet. 7951 if (!getAssociatedValue().getType()->isPointerTy()) 7952 return ChangeStatus::UNCHANGED; 7953 7954 // TODO: From readattrs.ll: "inalloca parameters are always 7955 // considered written" 7956 if (A.hasAttr(getIRPosition(), 7957 {Attribute::InAlloca, Attribute::Preallocated})) { 7958 removeKnownBits(NO_WRITES); 7959 removeAssumedBits(NO_WRITES); 7960 } 7961 A.removeAttrs(getIRPosition(), AttrKinds); 7962 return AAMemoryBehaviorFloating::manifest(A); 7963 } 7964 7965 /// See AbstractAttribute::trackStatistics() 7966 void trackStatistics() const override { 7967 if (isAssumedReadNone()) 7968 STATS_DECLTRACK_ARG_ATTR(readnone) 7969 else if (isAssumedReadOnly()) 7970 STATS_DECLTRACK_ARG_ATTR(readonly) 7971 else if (isAssumedWriteOnly()) 7972 STATS_DECLTRACK_ARG_ATTR(writeonly) 7973 } 7974 }; 7975 7976 struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument { 7977 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP, Attributor &A) 7978 : AAMemoryBehaviorArgument(IRP, A) {} 7979 7980 /// See AbstractAttribute::initialize(...). 7981 void initialize(Attributor &A) override { 7982 // If we don't have an associated attribute this is either a variadic call 7983 // or an indirect call, either way, nothing to do here. 7984 Argument *Arg = getAssociatedArgument(); 7985 if (!Arg) { 7986 indicatePessimisticFixpoint(); 7987 return; 7988 } 7989 if (Arg->hasByValAttr()) { 7990 addKnownBits(NO_WRITES); 7991 removeKnownBits(NO_READS); 7992 removeAssumedBits(NO_READS); 7993 } 7994 AAMemoryBehaviorArgument::initialize(A); 7995 if (getAssociatedFunction()->isDeclaration()) 7996 indicatePessimisticFixpoint(); 7997 } 7998 7999 /// See AbstractAttribute::updateImpl(...). 8000 ChangeStatus updateImpl(Attributor &A) override { 8001 // TODO: Once we have call site specific value information we can provide 8002 // call site specific liveness liveness information and then it makes 8003 // sense to specialize attributes for call sites arguments instead of 8004 // redirecting requests to the callee argument. 8005 Argument *Arg = getAssociatedArgument(); 8006 const IRPosition &ArgPos = IRPosition::argument(*Arg); 8007 auto *ArgAA = 8008 A.getAAFor<AAMemoryBehavior>(*this, ArgPos, DepClassTy::REQUIRED); 8009 if (!ArgAA) 8010 return indicatePessimisticFixpoint(); 8011 return clampStateAndIndicateChange(getState(), ArgAA->getState()); 8012 } 8013 8014 /// See AbstractAttribute::trackStatistics() 8015 void trackStatistics() const override { 8016 if (isAssumedReadNone()) 8017 STATS_DECLTRACK_CSARG_ATTR(readnone) 8018 else if (isAssumedReadOnly()) 8019 STATS_DECLTRACK_CSARG_ATTR(readonly) 8020 else if (isAssumedWriteOnly()) 8021 STATS_DECLTRACK_CSARG_ATTR(writeonly) 8022 } 8023 }; 8024 8025 /// Memory behavior attribute for a call site return position. 8026 struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating { 8027 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP, Attributor &A) 8028 : AAMemoryBehaviorFloating(IRP, A) {} 8029 8030 /// See AbstractAttribute::initialize(...). 8031 void initialize(Attributor &A) override { 8032 AAMemoryBehaviorImpl::initialize(A); 8033 } 8034 /// See AbstractAttribute::manifest(...). 8035 ChangeStatus manifest(Attributor &A) override { 8036 // We do not annotate returned values. 8037 return ChangeStatus::UNCHANGED; 8038 } 8039 8040 /// See AbstractAttribute::trackStatistics() 8041 void trackStatistics() const override {} 8042 }; 8043 8044 /// An AA to represent the memory behavior function attributes. 8045 struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl { 8046 AAMemoryBehaviorFunction(const IRPosition &IRP, Attributor &A) 8047 : AAMemoryBehaviorImpl(IRP, A) {} 8048 8049 /// See AbstractAttribute::updateImpl(Attributor &A). 8050 ChangeStatus updateImpl(Attributor &A) override; 8051 8052 /// See AbstractAttribute::manifest(...). 8053 ChangeStatus manifest(Attributor &A) override { 8054 // TODO: It would be better to merge this with AAMemoryLocation, so that 8055 // we could determine read/write per location. This would also have the 8056 // benefit of only one place trying to manifest the memory attribute. 8057 Function &F = cast<Function>(getAnchorValue()); 8058 MemoryEffects ME = MemoryEffects::unknown(); 8059 if (isAssumedReadNone()) 8060 ME = MemoryEffects::none(); 8061 else if (isAssumedReadOnly()) 8062 ME = MemoryEffects::readOnly(); 8063 else if (isAssumedWriteOnly()) 8064 ME = MemoryEffects::writeOnly(); 8065 8066 A.removeAttrs(getIRPosition(), AttrKinds); 8067 // Clear conflicting writable attribute. 8068 if (ME.onlyReadsMemory()) 8069 for (Argument &Arg : F.args()) 8070 A.removeAttrs(IRPosition::argument(Arg), Attribute::Writable); 8071 return A.manifestAttrs(getIRPosition(), 8072 Attribute::getWithMemoryEffects(F.getContext(), ME)); 8073 } 8074 8075 /// See AbstractAttribute::trackStatistics() 8076 void trackStatistics() const override { 8077 if (isAssumedReadNone()) 8078 STATS_DECLTRACK_FN_ATTR(readnone) 8079 else if (isAssumedReadOnly()) 8080 STATS_DECLTRACK_FN_ATTR(readonly) 8081 else if (isAssumedWriteOnly()) 8082 STATS_DECLTRACK_FN_ATTR(writeonly) 8083 } 8084 }; 8085 8086 /// AAMemoryBehavior attribute for call sites. 8087 struct AAMemoryBehaviorCallSite final 8088 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl> { 8089 AAMemoryBehaviorCallSite(const IRPosition &IRP, Attributor &A) 8090 : AACalleeToCallSite<AAMemoryBehavior, AAMemoryBehaviorImpl>(IRP, A) {} 8091 8092 /// See AbstractAttribute::manifest(...). 8093 ChangeStatus manifest(Attributor &A) override { 8094 // TODO: Deduplicate this with AAMemoryBehaviorFunction. 8095 CallBase &CB = cast<CallBase>(getAnchorValue()); 8096 MemoryEffects ME = MemoryEffects::unknown(); 8097 if (isAssumedReadNone()) 8098 ME = MemoryEffects::none(); 8099 else if (isAssumedReadOnly()) 8100 ME = MemoryEffects::readOnly(); 8101 else if (isAssumedWriteOnly()) 8102 ME = MemoryEffects::writeOnly(); 8103 8104 A.removeAttrs(getIRPosition(), AttrKinds); 8105 // Clear conflicting writable attribute. 8106 if (ME.onlyReadsMemory()) 8107 for (Use &U : CB.args()) 8108 A.removeAttrs(IRPosition::callsite_argument(CB, U.getOperandNo()), 8109 Attribute::Writable); 8110 return A.manifestAttrs( 8111 getIRPosition(), Attribute::getWithMemoryEffects(CB.getContext(), ME)); 8112 } 8113 8114 /// See AbstractAttribute::trackStatistics() 8115 void trackStatistics() const override { 8116 if (isAssumedReadNone()) 8117 STATS_DECLTRACK_CS_ATTR(readnone) 8118 else if (isAssumedReadOnly()) 8119 STATS_DECLTRACK_CS_ATTR(readonly) 8120 else if (isAssumedWriteOnly()) 8121 STATS_DECLTRACK_CS_ATTR(writeonly) 8122 } 8123 }; 8124 8125 ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) { 8126 8127 // The current assumed state used to determine a change. 8128 auto AssumedState = getAssumed(); 8129 8130 auto CheckRWInst = [&](Instruction &I) { 8131 // If the instruction has an own memory behavior state, use it to restrict 8132 // the local state. No further analysis is required as the other memory 8133 // state is as optimistic as it gets. 8134 if (const auto *CB = dyn_cast<CallBase>(&I)) { 8135 const auto *MemBehaviorAA = A.getAAFor<AAMemoryBehavior>( 8136 *this, IRPosition::callsite_function(*CB), DepClassTy::REQUIRED); 8137 if (MemBehaviorAA) { 8138 intersectAssumedBits(MemBehaviorAA->getAssumed()); 8139 return !isAtFixpoint(); 8140 } 8141 } 8142 8143 // Remove access kind modifiers if necessary. 8144 if (I.mayReadFromMemory()) 8145 removeAssumedBits(NO_READS); 8146 if (I.mayWriteToMemory()) 8147 removeAssumedBits(NO_WRITES); 8148 return !isAtFixpoint(); 8149 }; 8150 8151 bool UsedAssumedInformation = false; 8152 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this, 8153 UsedAssumedInformation)) 8154 return indicatePessimisticFixpoint(); 8155 8156 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED 8157 : ChangeStatus::UNCHANGED; 8158 } 8159 8160 ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) { 8161 8162 const IRPosition &IRP = getIRPosition(); 8163 const IRPosition &FnPos = IRPosition::function_scope(IRP); 8164 AAMemoryBehavior::StateType &S = getState(); 8165 8166 // First, check the function scope. We take the known information and we avoid 8167 // work if the assumed information implies the current assumed information for 8168 // this attribute. This is a valid for all but byval arguments. 8169 Argument *Arg = IRP.getAssociatedArgument(); 8170 AAMemoryBehavior::base_t FnMemAssumedState = 8171 AAMemoryBehavior::StateType::getWorstState(); 8172 if (!Arg || !Arg->hasByValAttr()) { 8173 const auto *FnMemAA = 8174 A.getAAFor<AAMemoryBehavior>(*this, FnPos, DepClassTy::OPTIONAL); 8175 if (FnMemAA) { 8176 FnMemAssumedState = FnMemAA->getAssumed(); 8177 S.addKnownBits(FnMemAA->getKnown()); 8178 if ((S.getAssumed() & FnMemAA->getAssumed()) == S.getAssumed()) 8179 return ChangeStatus::UNCHANGED; 8180 } 8181 } 8182 8183 // The current assumed state used to determine a change. 8184 auto AssumedState = S.getAssumed(); 8185 8186 // Make sure the value is not captured (except through "return"), if 8187 // it is, any information derived would be irrelevant anyway as we cannot 8188 // check the potential aliases introduced by the capture. However, no need 8189 // to fall back to anythign less optimistic than the function state. 8190 bool IsKnownNoCapture; 8191 const AANoCapture *ArgNoCaptureAA = nullptr; 8192 bool IsAssumedNoCapture = AA::hasAssumedIRAttr<Attribute::Captures>( 8193 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture, false, 8194 &ArgNoCaptureAA); 8195 8196 if (!IsAssumedNoCapture && 8197 (!ArgNoCaptureAA || !ArgNoCaptureAA->isAssumedNoCaptureMaybeReturned())) { 8198 S.intersectAssumedBits(FnMemAssumedState); 8199 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED 8200 : ChangeStatus::UNCHANGED; 8201 } 8202 8203 // Visit and expand uses until all are analyzed or a fixpoint is reached. 8204 auto UsePred = [&](const Use &U, bool &Follow) -> bool { 8205 Instruction *UserI = cast<Instruction>(U.getUser()); 8206 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << *U << " in " << *UserI 8207 << " \n"); 8208 8209 // Droppable users, e.g., llvm::assume does not actually perform any action. 8210 if (UserI->isDroppable()) 8211 return true; 8212 8213 // Check if the users of UserI should also be visited. 8214 Follow = followUsersOfUseIn(A, U, UserI); 8215 8216 // If UserI might touch memory we analyze the use in detail. 8217 if (UserI->mayReadOrWriteMemory()) 8218 analyzeUseIn(A, U, UserI); 8219 8220 return !isAtFixpoint(); 8221 }; 8222 8223 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue())) 8224 return indicatePessimisticFixpoint(); 8225 8226 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED 8227 : ChangeStatus::UNCHANGED; 8228 } 8229 8230 bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use &U, 8231 const Instruction *UserI) { 8232 // The loaded value is unrelated to the pointer argument, no need to 8233 // follow the users of the load. 8234 if (isa<LoadInst>(UserI) || isa<ReturnInst>(UserI)) 8235 return false; 8236 8237 // By default we follow all uses assuming UserI might leak information on U, 8238 // we have special handling for call sites operands though. 8239 const auto *CB = dyn_cast<CallBase>(UserI); 8240 if (!CB || !CB->isArgOperand(&U)) 8241 return true; 8242 8243 // If the use is a call argument known not to be captured, the users of 8244 // the call do not need to be visited because they have to be unrelated to 8245 // the input. Note that this check is not trivial even though we disallow 8246 // general capturing of the underlying argument. The reason is that the 8247 // call might the argument "through return", which we allow and for which we 8248 // need to check call users. 8249 if (U.get()->getType()->isPointerTy()) { 8250 unsigned ArgNo = CB->getArgOperandNo(&U); 8251 bool IsKnownNoCapture; 8252 return !AA::hasAssumedIRAttr<Attribute::Captures>( 8253 A, this, IRPosition::callsite_argument(*CB, ArgNo), 8254 DepClassTy::OPTIONAL, IsKnownNoCapture); 8255 } 8256 8257 return true; 8258 } 8259 8260 void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use &U, 8261 const Instruction *UserI) { 8262 assert(UserI->mayReadOrWriteMemory()); 8263 8264 switch (UserI->getOpcode()) { 8265 default: 8266 // TODO: Handle all atomics and other side-effect operations we know of. 8267 break; 8268 case Instruction::Load: 8269 // Loads cause the NO_READS property to disappear. 8270 removeAssumedBits(NO_READS); 8271 return; 8272 8273 case Instruction::Store: 8274 // Stores cause the NO_WRITES property to disappear if the use is the 8275 // pointer operand. Note that while capturing was taken care of somewhere 8276 // else we need to deal with stores of the value that is not looked through. 8277 if (cast<StoreInst>(UserI)->getPointerOperand() == U.get()) 8278 removeAssumedBits(NO_WRITES); 8279 else 8280 indicatePessimisticFixpoint(); 8281 return; 8282 8283 case Instruction::Call: 8284 case Instruction::CallBr: 8285 case Instruction::Invoke: { 8286 // For call sites we look at the argument memory behavior attribute (this 8287 // could be recursive!) in order to restrict our own state. 8288 const auto *CB = cast<CallBase>(UserI); 8289 8290 // Give up on operand bundles. 8291 if (CB->isBundleOperand(&U)) { 8292 indicatePessimisticFixpoint(); 8293 return; 8294 } 8295 8296 // Calling a function does read the function pointer, maybe write it if the 8297 // function is self-modifying. 8298 if (CB->isCallee(&U)) { 8299 removeAssumedBits(NO_READS); 8300 break; 8301 } 8302 8303 // Adjust the possible access behavior based on the information on the 8304 // argument. 8305 IRPosition Pos; 8306 if (U.get()->getType()->isPointerTy()) 8307 Pos = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U)); 8308 else 8309 Pos = IRPosition::callsite_function(*CB); 8310 const auto *MemBehaviorAA = 8311 A.getAAFor<AAMemoryBehavior>(*this, Pos, DepClassTy::OPTIONAL); 8312 if (!MemBehaviorAA) 8313 break; 8314 // "assumed" has at most the same bits as the MemBehaviorAA assumed 8315 // and at least "known". 8316 intersectAssumedBits(MemBehaviorAA->getAssumed()); 8317 return; 8318 } 8319 }; 8320 8321 // Generally, look at the "may-properties" and adjust the assumed state if we 8322 // did not trigger special handling before. 8323 if (UserI->mayReadFromMemory()) 8324 removeAssumedBits(NO_READS); 8325 if (UserI->mayWriteToMemory()) 8326 removeAssumedBits(NO_WRITES); 8327 } 8328 } // namespace 8329 8330 /// -------------------- Memory Locations Attributes --------------------------- 8331 /// Includes read-none, argmemonly, inaccessiblememonly, 8332 /// inaccessiblememorargmemonly 8333 /// ---------------------------------------------------------------------------- 8334 8335 std::string AAMemoryLocation::getMemoryLocationsAsStr( 8336 AAMemoryLocation::MemoryLocationsKind MLK) { 8337 if (0 == (MLK & AAMemoryLocation::NO_LOCATIONS)) 8338 return "all memory"; 8339 if (MLK == AAMemoryLocation::NO_LOCATIONS) 8340 return "no memory"; 8341 std::string S = "memory:"; 8342 if (0 == (MLK & AAMemoryLocation::NO_LOCAL_MEM)) 8343 S += "stack,"; 8344 if (0 == (MLK & AAMemoryLocation::NO_CONST_MEM)) 8345 S += "constant,"; 8346 if (0 == (MLK & AAMemoryLocation::NO_GLOBAL_INTERNAL_MEM)) 8347 S += "internal global,"; 8348 if (0 == (MLK & AAMemoryLocation::NO_GLOBAL_EXTERNAL_MEM)) 8349 S += "external global,"; 8350 if (0 == (MLK & AAMemoryLocation::NO_ARGUMENT_MEM)) 8351 S += "argument,"; 8352 if (0 == (MLK & AAMemoryLocation::NO_INACCESSIBLE_MEM)) 8353 S += "inaccessible,"; 8354 if (0 == (MLK & AAMemoryLocation::NO_MALLOCED_MEM)) 8355 S += "malloced,"; 8356 if (0 == (MLK & AAMemoryLocation::NO_UNKOWN_MEM)) 8357 S += "unknown,"; 8358 S.pop_back(); 8359 return S; 8360 } 8361 8362 namespace { 8363 struct AAMemoryLocationImpl : public AAMemoryLocation { 8364 8365 AAMemoryLocationImpl(const IRPosition &IRP, Attributor &A) 8366 : AAMemoryLocation(IRP, A), Allocator(A.Allocator) { 8367 AccessKind2Accesses.fill(nullptr); 8368 } 8369 8370 ~AAMemoryLocationImpl() { 8371 // The AccessSets are allocated via a BumpPtrAllocator, we call 8372 // the destructor manually. 8373 for (AccessSet *AS : AccessKind2Accesses) 8374 if (AS) 8375 AS->~AccessSet(); 8376 } 8377 8378 /// See AbstractAttribute::initialize(...). 8379 void initialize(Attributor &A) override { 8380 intersectAssumedBits(BEST_STATE); 8381 getKnownStateFromValue(A, getIRPosition(), getState()); 8382 AAMemoryLocation::initialize(A); 8383 } 8384 8385 /// Return the memory behavior information encoded in the IR for \p IRP. 8386 static void getKnownStateFromValue(Attributor &A, const IRPosition &IRP, 8387 BitIntegerState &State, 8388 bool IgnoreSubsumingPositions = false) { 8389 // For internal functions we ignore `argmemonly` and 8390 // `inaccessiblememorargmemonly` as we might break it via interprocedural 8391 // constant propagation. It is unclear if this is the best way but it is 8392 // unlikely this will cause real performance problems. If we are deriving 8393 // attributes for the anchor function we even remove the attribute in 8394 // addition to ignoring it. 8395 // TODO: A better way to handle this would be to add ~NO_GLOBAL_MEM / 8396 // MemoryEffects::Other as a possible location. 8397 bool UseArgMemOnly = true; 8398 Function *AnchorFn = IRP.getAnchorScope(); 8399 if (AnchorFn && A.isRunOn(*AnchorFn)) 8400 UseArgMemOnly = !AnchorFn->hasLocalLinkage(); 8401 8402 SmallVector<Attribute, 2> Attrs; 8403 A.getAttrs(IRP, {Attribute::Memory}, Attrs, IgnoreSubsumingPositions); 8404 for (const Attribute &Attr : Attrs) { 8405 // TODO: We can map MemoryEffects to Attributor locations more precisely. 8406 MemoryEffects ME = Attr.getMemoryEffects(); 8407 if (ME.doesNotAccessMemory()) { 8408 State.addKnownBits(NO_LOCAL_MEM | NO_CONST_MEM); 8409 continue; 8410 } 8411 if (ME.onlyAccessesInaccessibleMem()) { 8412 State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true)); 8413 continue; 8414 } 8415 if (ME.onlyAccessesArgPointees()) { 8416 if (UseArgMemOnly) 8417 State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true)); 8418 else { 8419 // Remove location information, only keep read/write info. 8420 ME = MemoryEffects(ME.getModRef()); 8421 A.manifestAttrs(IRP, 8422 Attribute::getWithMemoryEffects( 8423 IRP.getAnchorValue().getContext(), ME), 8424 /*ForceReplace*/ true); 8425 } 8426 continue; 8427 } 8428 if (ME.onlyAccessesInaccessibleOrArgMem()) { 8429 if (UseArgMemOnly) 8430 State.addKnownBits(inverseLocation( 8431 NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true)); 8432 else { 8433 // Remove location information, only keep read/write info. 8434 ME = MemoryEffects(ME.getModRef()); 8435 A.manifestAttrs(IRP, 8436 Attribute::getWithMemoryEffects( 8437 IRP.getAnchorValue().getContext(), ME), 8438 /*ForceReplace*/ true); 8439 } 8440 continue; 8441 } 8442 } 8443 } 8444 8445 /// See AbstractAttribute::getDeducedAttributes(...). 8446 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, 8447 SmallVectorImpl<Attribute> &Attrs) const override { 8448 // TODO: We can map Attributor locations to MemoryEffects more precisely. 8449 assert(Attrs.size() == 0); 8450 if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION) { 8451 if (isAssumedReadNone()) 8452 Attrs.push_back( 8453 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::none())); 8454 else if (isAssumedInaccessibleMemOnly()) 8455 Attrs.push_back(Attribute::getWithMemoryEffects( 8456 Ctx, MemoryEffects::inaccessibleMemOnly())); 8457 else if (isAssumedArgMemOnly()) 8458 Attrs.push_back( 8459 Attribute::getWithMemoryEffects(Ctx, MemoryEffects::argMemOnly())); 8460 else if (isAssumedInaccessibleOrArgMemOnly()) 8461 Attrs.push_back(Attribute::getWithMemoryEffects( 8462 Ctx, MemoryEffects::inaccessibleOrArgMemOnly())); 8463 } 8464 assert(Attrs.size() <= 1); 8465 } 8466 8467 /// See AbstractAttribute::manifest(...). 8468 ChangeStatus manifest(Attributor &A) override { 8469 // TODO: If AAMemoryLocation and AAMemoryBehavior are merged, we could 8470 // provide per-location modref information here. 8471 const IRPosition &IRP = getIRPosition(); 8472 8473 SmallVector<Attribute, 1> DeducedAttrs; 8474 getDeducedAttributes(A, IRP.getAnchorValue().getContext(), DeducedAttrs); 8475 if (DeducedAttrs.size() != 1) 8476 return ChangeStatus::UNCHANGED; 8477 MemoryEffects ME = DeducedAttrs[0].getMemoryEffects(); 8478 8479 return A.manifestAttrs(IRP, Attribute::getWithMemoryEffects( 8480 IRP.getAnchorValue().getContext(), ME)); 8481 } 8482 8483 /// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...). 8484 bool checkForAllAccessesToMemoryKind( 8485 function_ref<bool(const Instruction *, const Value *, AccessKind, 8486 MemoryLocationsKind)> 8487 Pred, 8488 MemoryLocationsKind RequestedMLK) const override { 8489 if (!isValidState()) 8490 return false; 8491 8492 MemoryLocationsKind AssumedMLK = getAssumedNotAccessedLocation(); 8493 if (AssumedMLK == NO_LOCATIONS) 8494 return true; 8495 8496 unsigned Idx = 0; 8497 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; 8498 CurMLK *= 2, ++Idx) { 8499 if (CurMLK & RequestedMLK) 8500 continue; 8501 8502 if (const AccessSet *Accesses = AccessKind2Accesses[Idx]) 8503 for (const AccessInfo &AI : *Accesses) 8504 if (!Pred(AI.I, AI.Ptr, AI.Kind, CurMLK)) 8505 return false; 8506 } 8507 8508 return true; 8509 } 8510 8511 ChangeStatus indicatePessimisticFixpoint() override { 8512 // If we give up and indicate a pessimistic fixpoint this instruction will 8513 // become an access for all potential access kinds: 8514 // TODO: Add pointers for argmemonly and globals to improve the results of 8515 // checkForAllAccessesToMemoryKind. 8516 bool Changed = false; 8517 MemoryLocationsKind KnownMLK = getKnown(); 8518 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()); 8519 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) 8520 if (!(CurMLK & KnownMLK)) 8521 updateStateAndAccessesMap(getState(), CurMLK, I, nullptr, Changed, 8522 getAccessKindFromInst(I)); 8523 return AAMemoryLocation::indicatePessimisticFixpoint(); 8524 } 8525 8526 protected: 8527 /// Helper struct to tie together an instruction that has a read or write 8528 /// effect with the pointer it accesses (if any). 8529 struct AccessInfo { 8530 8531 /// The instruction that caused the access. 8532 const Instruction *I; 8533 8534 /// The base pointer that is accessed, or null if unknown. 8535 const Value *Ptr; 8536 8537 /// The kind of access (read/write/read+write). 8538 AccessKind Kind; 8539 8540 bool operator==(const AccessInfo &RHS) const { 8541 return I == RHS.I && Ptr == RHS.Ptr && Kind == RHS.Kind; 8542 } 8543 bool operator()(const AccessInfo &LHS, const AccessInfo &RHS) const { 8544 if (LHS.I != RHS.I) 8545 return LHS.I < RHS.I; 8546 if (LHS.Ptr != RHS.Ptr) 8547 return LHS.Ptr < RHS.Ptr; 8548 if (LHS.Kind != RHS.Kind) 8549 return LHS.Kind < RHS.Kind; 8550 return false; 8551 } 8552 }; 8553 8554 /// Mapping from *single* memory location kinds, e.g., LOCAL_MEM with the 8555 /// value of NO_LOCAL_MEM, to the accesses encountered for this memory kind. 8556 using AccessSet = SmallSet<AccessInfo, 2, AccessInfo>; 8557 std::array<AccessSet *, llvm::CTLog2<VALID_STATE>()> AccessKind2Accesses; 8558 8559 /// Categorize the pointer arguments of CB that might access memory in 8560 /// AccessedLoc and update the state and access map accordingly. 8561 void 8562 categorizeArgumentPointerLocations(Attributor &A, CallBase &CB, 8563 AAMemoryLocation::StateType &AccessedLocs, 8564 bool &Changed); 8565 8566 /// Return the kind(s) of location that may be accessed by \p V. 8567 AAMemoryLocation::MemoryLocationsKind 8568 categorizeAccessedLocations(Attributor &A, Instruction &I, bool &Changed); 8569 8570 /// Return the access kind as determined by \p I. 8571 AccessKind getAccessKindFromInst(const Instruction *I) { 8572 AccessKind AK = READ_WRITE; 8573 if (I) { 8574 AK = I->mayReadFromMemory() ? READ : NONE; 8575 AK = AccessKind(AK | (I->mayWriteToMemory() ? WRITE : NONE)); 8576 } 8577 return AK; 8578 } 8579 8580 /// Update the state \p State and the AccessKind2Accesses given that \p I is 8581 /// an access of kind \p AK to a \p MLK memory location with the access 8582 /// pointer \p Ptr. 8583 void updateStateAndAccessesMap(AAMemoryLocation::StateType &State, 8584 MemoryLocationsKind MLK, const Instruction *I, 8585 const Value *Ptr, bool &Changed, 8586 AccessKind AK = READ_WRITE) { 8587 8588 assert(isPowerOf2_32(MLK) && "Expected a single location set!"); 8589 auto *&Accesses = AccessKind2Accesses[llvm::Log2_32(MLK)]; 8590 if (!Accesses) 8591 Accesses = new (Allocator) AccessSet(); 8592 Changed |= Accesses->insert(AccessInfo{I, Ptr, AK}).second; 8593 if (MLK == NO_UNKOWN_MEM) 8594 MLK = NO_LOCATIONS; 8595 State.removeAssumedBits(MLK); 8596 } 8597 8598 /// Determine the underlying locations kinds for \p Ptr, e.g., globals or 8599 /// arguments, and update the state and access map accordingly. 8600 void categorizePtrValue(Attributor &A, const Instruction &I, const Value &Ptr, 8601 AAMemoryLocation::StateType &State, bool &Changed, 8602 unsigned AccessAS = 0); 8603 8604 /// Used to allocate access sets. 8605 BumpPtrAllocator &Allocator; 8606 }; 8607 8608 void AAMemoryLocationImpl::categorizePtrValue( 8609 Attributor &A, const Instruction &I, const Value &Ptr, 8610 AAMemoryLocation::StateType &State, bool &Changed, unsigned AccessAS) { 8611 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize pointer locations for " 8612 << Ptr << " [" 8613 << getMemoryLocationsAsStr(State.getAssumed()) << "]\n"); 8614 8615 auto Pred = [&](Value &Obj) { 8616 unsigned ObjectAS = Obj.getType()->getPointerAddressSpace(); 8617 // TODO: recognize the TBAA used for constant accesses. 8618 MemoryLocationsKind MLK = NO_LOCATIONS; 8619 8620 // Filter accesses to constant (GPU) memory if we have an AS at the access 8621 // site or the object is known to actually have the associated AS. 8622 if ((AccessAS == (unsigned)AA::GPUAddressSpace::Constant || 8623 (ObjectAS == (unsigned)AA::GPUAddressSpace::Constant && 8624 isIdentifiedObject(&Obj))) && 8625 AA::isGPU(*I.getModule())) 8626 return true; 8627 8628 if (isa<UndefValue>(&Obj)) 8629 return true; 8630 if (isa<Argument>(&Obj)) { 8631 // TODO: For now we do not treat byval arguments as local copies performed 8632 // on the call edge, though, we should. To make that happen we need to 8633 // teach various passes, e.g., DSE, about the copy effect of a byval. That 8634 // would also allow us to mark functions only accessing byval arguments as 8635 // readnone again, arguably their accesses have no effect outside of the 8636 // function, like accesses to allocas. 8637 MLK = NO_ARGUMENT_MEM; 8638 } else if (auto *GV = dyn_cast<GlobalValue>(&Obj)) { 8639 // Reading constant memory is not treated as a read "effect" by the 8640 // function attr pass so we won't neither. Constants defined by TBAA are 8641 // similar. (We know we do not write it because it is constant.) 8642 if (auto *GVar = dyn_cast<GlobalVariable>(GV)) 8643 if (GVar->isConstant()) 8644 return true; 8645 8646 if (GV->hasLocalLinkage()) 8647 MLK = NO_GLOBAL_INTERNAL_MEM; 8648 else 8649 MLK = NO_GLOBAL_EXTERNAL_MEM; 8650 } else if (isa<ConstantPointerNull>(&Obj) && 8651 (!NullPointerIsDefined(getAssociatedFunction(), AccessAS) || 8652 !NullPointerIsDefined(getAssociatedFunction(), ObjectAS))) { 8653 return true; 8654 } else if (isa<AllocaInst>(&Obj)) { 8655 MLK = NO_LOCAL_MEM; 8656 } else if (const auto *CB = dyn_cast<CallBase>(&Obj)) { 8657 bool IsKnownNoAlias; 8658 if (AA::hasAssumedIRAttr<Attribute::NoAlias>( 8659 A, this, IRPosition::callsite_returned(*CB), DepClassTy::OPTIONAL, 8660 IsKnownNoAlias)) 8661 MLK = NO_MALLOCED_MEM; 8662 else 8663 MLK = NO_UNKOWN_MEM; 8664 } else { 8665 MLK = NO_UNKOWN_MEM; 8666 } 8667 8668 assert(MLK != NO_LOCATIONS && "No location specified!"); 8669 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Ptr value can be categorized: " 8670 << Obj << " -> " << getMemoryLocationsAsStr(MLK) << "\n"); 8671 updateStateAndAccessesMap(State, MLK, &I, &Obj, Changed, 8672 getAccessKindFromInst(&I)); 8673 8674 return true; 8675 }; 8676 8677 const auto *AA = A.getAAFor<AAUnderlyingObjects>( 8678 *this, IRPosition::value(Ptr), DepClassTy::OPTIONAL); 8679 if (!AA || !AA->forallUnderlyingObjects(Pred, AA::Intraprocedural)) { 8680 LLVM_DEBUG( 8681 dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n"); 8682 updateStateAndAccessesMap(State, NO_UNKOWN_MEM, &I, nullptr, Changed, 8683 getAccessKindFromInst(&I)); 8684 return; 8685 } 8686 8687 LLVM_DEBUG( 8688 dbgs() << "[AAMemoryLocation] Accessed locations with pointer locations: " 8689 << getMemoryLocationsAsStr(State.getAssumed()) << "\n"); 8690 } 8691 8692 void AAMemoryLocationImpl::categorizeArgumentPointerLocations( 8693 Attributor &A, CallBase &CB, AAMemoryLocation::StateType &AccessedLocs, 8694 bool &Changed) { 8695 for (unsigned ArgNo = 0, E = CB.arg_size(); ArgNo < E; ++ArgNo) { 8696 8697 // Skip non-pointer arguments. 8698 const Value *ArgOp = CB.getArgOperand(ArgNo); 8699 if (!ArgOp->getType()->isPtrOrPtrVectorTy()) 8700 continue; 8701 8702 // Skip readnone arguments. 8703 const IRPosition &ArgOpIRP = IRPosition::callsite_argument(CB, ArgNo); 8704 const auto *ArgOpMemLocationAA = 8705 A.getAAFor<AAMemoryBehavior>(*this, ArgOpIRP, DepClassTy::OPTIONAL); 8706 8707 if (ArgOpMemLocationAA && ArgOpMemLocationAA->isAssumedReadNone()) 8708 continue; 8709 8710 // Categorize potentially accessed pointer arguments as if there was an 8711 // access instruction with them as pointer. 8712 categorizePtrValue(A, CB, *ArgOp, AccessedLocs, Changed); 8713 } 8714 } 8715 8716 AAMemoryLocation::MemoryLocationsKind 8717 AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I, 8718 bool &Changed) { 8719 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize accessed locations for " 8720 << I << "\n"); 8721 8722 AAMemoryLocation::StateType AccessedLocs; 8723 AccessedLocs.intersectAssumedBits(NO_LOCATIONS); 8724 8725 if (auto *CB = dyn_cast<CallBase>(&I)) { 8726 8727 // First check if we assume any memory is access is visible. 8728 const auto *CBMemLocationAA = A.getAAFor<AAMemoryLocation>( 8729 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL); 8730 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I 8731 << " [" << CBMemLocationAA << "]\n"); 8732 if (!CBMemLocationAA) { 8733 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr, 8734 Changed, getAccessKindFromInst(&I)); 8735 return NO_UNKOWN_MEM; 8736 } 8737 8738 if (CBMemLocationAA->isAssumedReadNone()) 8739 return NO_LOCATIONS; 8740 8741 if (CBMemLocationAA->isAssumedInaccessibleMemOnly()) { 8742 updateStateAndAccessesMap(AccessedLocs, NO_INACCESSIBLE_MEM, &I, nullptr, 8743 Changed, getAccessKindFromInst(&I)); 8744 return AccessedLocs.getAssumed(); 8745 } 8746 8747 uint32_t CBAssumedNotAccessedLocs = 8748 CBMemLocationAA->getAssumedNotAccessedLocation(); 8749 8750 // Set the argmemonly and global bit as we handle them separately below. 8751 uint32_t CBAssumedNotAccessedLocsNoArgMem = 8752 CBAssumedNotAccessedLocs | NO_ARGUMENT_MEM | NO_GLOBAL_MEM; 8753 8754 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) { 8755 if (CBAssumedNotAccessedLocsNoArgMem & CurMLK) 8756 continue; 8757 updateStateAndAccessesMap(AccessedLocs, CurMLK, &I, nullptr, Changed, 8758 getAccessKindFromInst(&I)); 8759 } 8760 8761 // Now handle global memory if it might be accessed. This is slightly tricky 8762 // as NO_GLOBAL_MEM has multiple bits set. 8763 bool HasGlobalAccesses = ((~CBAssumedNotAccessedLocs) & NO_GLOBAL_MEM); 8764 if (HasGlobalAccesses) { 8765 auto AccessPred = [&](const Instruction *, const Value *Ptr, 8766 AccessKind Kind, MemoryLocationsKind MLK) { 8767 updateStateAndAccessesMap(AccessedLocs, MLK, &I, Ptr, Changed, 8768 getAccessKindFromInst(&I)); 8769 return true; 8770 }; 8771 if (!CBMemLocationAA->checkForAllAccessesToMemoryKind( 8772 AccessPred, inverseLocation(NO_GLOBAL_MEM, false, false))) 8773 return AccessedLocs.getWorstState(); 8774 } 8775 8776 LLVM_DEBUG( 8777 dbgs() << "[AAMemoryLocation] Accessed state before argument handling: " 8778 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n"); 8779 8780 // Now handle argument memory if it might be accessed. 8781 bool HasArgAccesses = ((~CBAssumedNotAccessedLocs) & NO_ARGUMENT_MEM); 8782 if (HasArgAccesses) 8783 categorizeArgumentPointerLocations(A, *CB, AccessedLocs, Changed); 8784 8785 LLVM_DEBUG( 8786 dbgs() << "[AAMemoryLocation] Accessed state after argument handling: " 8787 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n"); 8788 8789 return AccessedLocs.getAssumed(); 8790 } 8791 8792 if (const Value *Ptr = getPointerOperand(&I, /* AllowVolatile */ true)) { 8793 LLVM_DEBUG( 8794 dbgs() << "[AAMemoryLocation] Categorize memory access with pointer: " 8795 << I << " [" << *Ptr << "]\n"); 8796 categorizePtrValue(A, I, *Ptr, AccessedLocs, Changed, 8797 Ptr->getType()->getPointerAddressSpace()); 8798 return AccessedLocs.getAssumed(); 8799 } 8800 8801 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Failed to categorize instruction: " 8802 << I << "\n"); 8803 updateStateAndAccessesMap(AccessedLocs, NO_UNKOWN_MEM, &I, nullptr, Changed, 8804 getAccessKindFromInst(&I)); 8805 return AccessedLocs.getAssumed(); 8806 } 8807 8808 /// An AA to represent the memory behavior function attributes. 8809 struct AAMemoryLocationFunction final : public AAMemoryLocationImpl { 8810 AAMemoryLocationFunction(const IRPosition &IRP, Attributor &A) 8811 : AAMemoryLocationImpl(IRP, A) {} 8812 8813 /// See AbstractAttribute::updateImpl(Attributor &A). 8814 ChangeStatus updateImpl(Attributor &A) override { 8815 8816 const auto *MemBehaviorAA = 8817 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(), DepClassTy::NONE); 8818 if (MemBehaviorAA && MemBehaviorAA->isAssumedReadNone()) { 8819 if (MemBehaviorAA->isKnownReadNone()) 8820 return indicateOptimisticFixpoint(); 8821 assert(isAssumedReadNone() && 8822 "AAMemoryLocation was not read-none but AAMemoryBehavior was!"); 8823 A.recordDependence(*MemBehaviorAA, *this, DepClassTy::OPTIONAL); 8824 return ChangeStatus::UNCHANGED; 8825 } 8826 8827 // The current assumed state used to determine a change. 8828 auto AssumedState = getAssumed(); 8829 bool Changed = false; 8830 8831 auto CheckRWInst = [&](Instruction &I) { 8832 MemoryLocationsKind MLK = categorizeAccessedLocations(A, I, Changed); 8833 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I 8834 << ": " << getMemoryLocationsAsStr(MLK) << "\n"); 8835 removeAssumedBits(inverseLocation(MLK, false, false)); 8836 // Stop once only the valid bit set in the *not assumed location*, thus 8837 // once we don't actually exclude any memory locations in the state. 8838 return getAssumedNotAccessedLocation() != VALID_STATE; 8839 }; 8840 8841 bool UsedAssumedInformation = false; 8842 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this, 8843 UsedAssumedInformation)) 8844 return indicatePessimisticFixpoint(); 8845 8846 Changed |= AssumedState != getAssumed(); 8847 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 8848 } 8849 8850 /// See AbstractAttribute::trackStatistics() 8851 void trackStatistics() const override { 8852 if (isAssumedReadNone()) 8853 STATS_DECLTRACK_FN_ATTR(readnone) 8854 else if (isAssumedArgMemOnly()) 8855 STATS_DECLTRACK_FN_ATTR(argmemonly) 8856 else if (isAssumedInaccessibleMemOnly()) 8857 STATS_DECLTRACK_FN_ATTR(inaccessiblememonly) 8858 else if (isAssumedInaccessibleOrArgMemOnly()) 8859 STATS_DECLTRACK_FN_ATTR(inaccessiblememorargmemonly) 8860 } 8861 }; 8862 8863 /// AAMemoryLocation attribute for call sites. 8864 struct AAMemoryLocationCallSite final : AAMemoryLocationImpl { 8865 AAMemoryLocationCallSite(const IRPosition &IRP, Attributor &A) 8866 : AAMemoryLocationImpl(IRP, A) {} 8867 8868 /// See AbstractAttribute::updateImpl(...). 8869 ChangeStatus updateImpl(Attributor &A) override { 8870 // TODO: Once we have call site specific value information we can provide 8871 // call site specific liveness liveness information and then it makes 8872 // sense to specialize attributes for call sites arguments instead of 8873 // redirecting requests to the callee argument. 8874 Function *F = getAssociatedFunction(); 8875 const IRPosition &FnPos = IRPosition::function(*F); 8876 auto *FnAA = 8877 A.getAAFor<AAMemoryLocation>(*this, FnPos, DepClassTy::REQUIRED); 8878 if (!FnAA) 8879 return indicatePessimisticFixpoint(); 8880 bool Changed = false; 8881 auto AccessPred = [&](const Instruction *I, const Value *Ptr, 8882 AccessKind Kind, MemoryLocationsKind MLK) { 8883 updateStateAndAccessesMap(getState(), MLK, I, Ptr, Changed, 8884 getAccessKindFromInst(I)); 8885 return true; 8886 }; 8887 if (!FnAA->checkForAllAccessesToMemoryKind(AccessPred, ALL_LOCATIONS)) 8888 return indicatePessimisticFixpoint(); 8889 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 8890 } 8891 8892 /// See AbstractAttribute::trackStatistics() 8893 void trackStatistics() const override { 8894 if (isAssumedReadNone()) 8895 STATS_DECLTRACK_CS_ATTR(readnone) 8896 } 8897 }; 8898 } // namespace 8899 8900 /// ------------------ denormal-fp-math Attribute ------------------------- 8901 8902 namespace { 8903 struct AADenormalFPMathImpl : public AADenormalFPMath { 8904 AADenormalFPMathImpl(const IRPosition &IRP, Attributor &A) 8905 : AADenormalFPMath(IRP, A) {} 8906 8907 const std::string getAsStr(Attributor *A) const override { 8908 std::string Str("AADenormalFPMath["); 8909 raw_string_ostream OS(Str); 8910 8911 DenormalState Known = getKnown(); 8912 if (Known.Mode.isValid()) 8913 OS << "denormal-fp-math=" << Known.Mode; 8914 else 8915 OS << "invalid"; 8916 8917 if (Known.ModeF32.isValid()) 8918 OS << " denormal-fp-math-f32=" << Known.ModeF32; 8919 OS << ']'; 8920 return Str; 8921 } 8922 }; 8923 8924 struct AADenormalFPMathFunction final : AADenormalFPMathImpl { 8925 AADenormalFPMathFunction(const IRPosition &IRP, Attributor &A) 8926 : AADenormalFPMathImpl(IRP, A) {} 8927 8928 void initialize(Attributor &A) override { 8929 const Function *F = getAnchorScope(); 8930 DenormalMode Mode = F->getDenormalModeRaw(); 8931 DenormalMode ModeF32 = F->getDenormalModeF32Raw(); 8932 8933 // TODO: Handling this here prevents handling the case where a callee has a 8934 // fixed denormal-fp-math with dynamic denormal-fp-math-f32, but called from 8935 // a function with a fully fixed mode. 8936 if (ModeF32 == DenormalMode::getInvalid()) 8937 ModeF32 = Mode; 8938 Known = DenormalState{Mode, ModeF32}; 8939 if (isModeFixed()) 8940 indicateFixpoint(); 8941 } 8942 8943 ChangeStatus updateImpl(Attributor &A) override { 8944 ChangeStatus Change = ChangeStatus::UNCHANGED; 8945 8946 auto CheckCallSite = [=, &Change, &A](AbstractCallSite CS) { 8947 Function *Caller = CS.getInstruction()->getFunction(); 8948 LLVM_DEBUG(dbgs() << "[AADenormalFPMath] Call " << Caller->getName() 8949 << "->" << getAssociatedFunction()->getName() << '\n'); 8950 8951 const auto *CallerInfo = A.getAAFor<AADenormalFPMath>( 8952 *this, IRPosition::function(*Caller), DepClassTy::REQUIRED); 8953 if (!CallerInfo) 8954 return false; 8955 8956 Change = Change | clampStateAndIndicateChange(this->getState(), 8957 CallerInfo->getState()); 8958 return true; 8959 }; 8960 8961 bool AllCallSitesKnown = true; 8962 if (!A.checkForAllCallSites(CheckCallSite, *this, true, AllCallSitesKnown)) 8963 return indicatePessimisticFixpoint(); 8964 8965 if (Change == ChangeStatus::CHANGED && isModeFixed()) 8966 indicateFixpoint(); 8967 return Change; 8968 } 8969 8970 ChangeStatus manifest(Attributor &A) override { 8971 LLVMContext &Ctx = getAssociatedFunction()->getContext(); 8972 8973 SmallVector<Attribute, 2> AttrToAdd; 8974 SmallVector<StringRef, 2> AttrToRemove; 8975 if (Known.Mode == DenormalMode::getDefault()) { 8976 AttrToRemove.push_back("denormal-fp-math"); 8977 } else { 8978 AttrToAdd.push_back( 8979 Attribute::get(Ctx, "denormal-fp-math", Known.Mode.str())); 8980 } 8981 8982 if (Known.ModeF32 != Known.Mode) { 8983 AttrToAdd.push_back( 8984 Attribute::get(Ctx, "denormal-fp-math-f32", Known.ModeF32.str())); 8985 } else { 8986 AttrToRemove.push_back("denormal-fp-math-f32"); 8987 } 8988 8989 auto &IRP = getIRPosition(); 8990 8991 // TODO: There should be a combined add and remove API. 8992 return A.removeAttrs(IRP, AttrToRemove) | 8993 A.manifestAttrs(IRP, AttrToAdd, /*ForceReplace=*/true); 8994 } 8995 8996 void trackStatistics() const override { 8997 STATS_DECLTRACK_FN_ATTR(denormal_fp_math) 8998 } 8999 }; 9000 } // namespace 9001 9002 /// ------------------ Value Constant Range Attribute ------------------------- 9003 9004 namespace { 9005 struct AAValueConstantRangeImpl : AAValueConstantRange { 9006 using StateType = IntegerRangeState; 9007 AAValueConstantRangeImpl(const IRPosition &IRP, Attributor &A) 9008 : AAValueConstantRange(IRP, A) {} 9009 9010 /// See AbstractAttribute::initialize(..). 9011 void initialize(Attributor &A) override { 9012 if (A.hasSimplificationCallback(getIRPosition())) { 9013 indicatePessimisticFixpoint(); 9014 return; 9015 } 9016 9017 // Intersect a range given by SCEV. 9018 intersectKnown(getConstantRangeFromSCEV(A, getCtxI())); 9019 9020 // Intersect a range given by LVI. 9021 intersectKnown(getConstantRangeFromLVI(A, getCtxI())); 9022 } 9023 9024 /// See AbstractAttribute::getAsStr(). 9025 const std::string getAsStr(Attributor *A) const override { 9026 std::string Str; 9027 llvm::raw_string_ostream OS(Str); 9028 OS << "range(" << getBitWidth() << ")<"; 9029 getKnown().print(OS); 9030 OS << " / "; 9031 getAssumed().print(OS); 9032 OS << ">"; 9033 return Str; 9034 } 9035 9036 /// Helper function to get a SCEV expr for the associated value at program 9037 /// point \p I. 9038 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const { 9039 if (!getAnchorScope()) 9040 return nullptr; 9041 9042 ScalarEvolution *SE = 9043 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>( 9044 *getAnchorScope()); 9045 9046 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>( 9047 *getAnchorScope()); 9048 9049 if (!SE || !LI) 9050 return nullptr; 9051 9052 const SCEV *S = SE->getSCEV(&getAssociatedValue()); 9053 if (!I) 9054 return S; 9055 9056 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent())); 9057 } 9058 9059 /// Helper function to get a range from SCEV for the associated value at 9060 /// program point \p I. 9061 ConstantRange getConstantRangeFromSCEV(Attributor &A, 9062 const Instruction *I = nullptr) const { 9063 if (!getAnchorScope()) 9064 return getWorstState(getBitWidth()); 9065 9066 ScalarEvolution *SE = 9067 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>( 9068 *getAnchorScope()); 9069 9070 const SCEV *S = getSCEV(A, I); 9071 if (!SE || !S) 9072 return getWorstState(getBitWidth()); 9073 9074 return SE->getUnsignedRange(S); 9075 } 9076 9077 /// Helper function to get a range from LVI for the associated value at 9078 /// program point \p I. 9079 ConstantRange 9080 getConstantRangeFromLVI(Attributor &A, 9081 const Instruction *CtxI = nullptr) const { 9082 if (!getAnchorScope()) 9083 return getWorstState(getBitWidth()); 9084 9085 LazyValueInfo *LVI = 9086 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>( 9087 *getAnchorScope()); 9088 9089 if (!LVI || !CtxI) 9090 return getWorstState(getBitWidth()); 9091 return LVI->getConstantRange(&getAssociatedValue(), 9092 const_cast<Instruction *>(CtxI), 9093 /*UndefAllowed*/ false); 9094 } 9095 9096 /// Return true if \p CtxI is valid for querying outside analyses. 9097 /// This basically makes sure we do not ask intra-procedural analysis 9098 /// about a context in the wrong function or a context that violates 9099 /// dominance assumptions they might have. The \p AllowAACtxI flag indicates 9100 /// if the original context of this AA is OK or should be considered invalid. 9101 bool isValidCtxInstructionForOutsideAnalysis(Attributor &A, 9102 const Instruction *CtxI, 9103 bool AllowAACtxI) const { 9104 if (!CtxI || (!AllowAACtxI && CtxI == getCtxI())) 9105 return false; 9106 9107 // Our context might be in a different function, neither intra-procedural 9108 // analysis (ScalarEvolution nor LazyValueInfo) can handle that. 9109 if (!AA::isValidInScope(getAssociatedValue(), CtxI->getFunction())) 9110 return false; 9111 9112 // If the context is not dominated by the value there are paths to the 9113 // context that do not define the value. This cannot be handled by 9114 // LazyValueInfo so we need to bail. 9115 if (auto *I = dyn_cast<Instruction>(&getAssociatedValue())) { 9116 InformationCache &InfoCache = A.getInfoCache(); 9117 const DominatorTree *DT = 9118 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>( 9119 *I->getFunction()); 9120 return DT && DT->dominates(I, CtxI); 9121 } 9122 9123 return true; 9124 } 9125 9126 /// See AAValueConstantRange::getKnownConstantRange(..). 9127 ConstantRange 9128 getKnownConstantRange(Attributor &A, 9129 const Instruction *CtxI = nullptr) const override { 9130 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI, 9131 /* AllowAACtxI */ false)) 9132 return getKnown(); 9133 9134 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI); 9135 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI); 9136 return getKnown().intersectWith(SCEVR).intersectWith(LVIR); 9137 } 9138 9139 /// See AAValueConstantRange::getAssumedConstantRange(..). 9140 ConstantRange 9141 getAssumedConstantRange(Attributor &A, 9142 const Instruction *CtxI = nullptr) const override { 9143 // TODO: Make SCEV use Attributor assumption. 9144 // We may be able to bound a variable range via assumptions in 9145 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to 9146 // evolve to x^2 + x, then we can say that y is in [2, 12]. 9147 if (!isValidCtxInstructionForOutsideAnalysis(A, CtxI, 9148 /* AllowAACtxI */ false)) 9149 return getAssumed(); 9150 9151 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI); 9152 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI); 9153 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR); 9154 } 9155 9156 /// Helper function to create MDNode for range metadata. 9157 static MDNode * 9158 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx, 9159 const ConstantRange &AssumedConstantRange) { 9160 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get( 9161 Ty, AssumedConstantRange.getLower())), 9162 ConstantAsMetadata::get(ConstantInt::get( 9163 Ty, AssumedConstantRange.getUpper()))}; 9164 return MDNode::get(Ctx, LowAndHigh); 9165 } 9166 9167 /// Return true if \p Assumed is included in \p KnownRanges. 9168 static bool isBetterRange(const ConstantRange &Assumed, MDNode *KnownRanges) { 9169 9170 if (Assumed.isFullSet()) 9171 return false; 9172 9173 if (!KnownRanges) 9174 return true; 9175 9176 // If multiple ranges are annotated in IR, we give up to annotate assumed 9177 // range for now. 9178 9179 // TODO: If there exists a known range which containts assumed range, we 9180 // can say assumed range is better. 9181 if (KnownRanges->getNumOperands() > 2) 9182 return false; 9183 9184 ConstantInt *Lower = 9185 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0)); 9186 ConstantInt *Upper = 9187 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1)); 9188 9189 ConstantRange Known(Lower->getValue(), Upper->getValue()); 9190 return Known.contains(Assumed) && Known != Assumed; 9191 } 9192 9193 /// Helper function to set range metadata. 9194 static bool 9195 setRangeMetadataIfisBetterRange(Instruction *I, 9196 const ConstantRange &AssumedConstantRange) { 9197 auto *OldRangeMD = I->getMetadata(LLVMContext::MD_range); 9198 if (isBetterRange(AssumedConstantRange, OldRangeMD)) { 9199 if (!AssumedConstantRange.isEmptySet()) { 9200 I->setMetadata(LLVMContext::MD_range, 9201 getMDNodeForConstantRange(I->getType(), I->getContext(), 9202 AssumedConstantRange)); 9203 return true; 9204 } 9205 } 9206 return false; 9207 } 9208 9209 /// See AbstractAttribute::manifest() 9210 ChangeStatus manifest(Attributor &A) override { 9211 ChangeStatus Changed = ChangeStatus::UNCHANGED; 9212 ConstantRange AssumedConstantRange = getAssumedConstantRange(A); 9213 assert(!AssumedConstantRange.isFullSet() && "Invalid state"); 9214 9215 auto &V = getAssociatedValue(); 9216 if (!AssumedConstantRange.isEmptySet() && 9217 !AssumedConstantRange.isSingleElement()) { 9218 if (Instruction *I = dyn_cast<Instruction>(&V)) { 9219 assert(I == getCtxI() && "Should not annotate an instruction which is " 9220 "not the context instruction"); 9221 if (isa<CallInst>(I) || isa<LoadInst>(I)) 9222 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange)) 9223 Changed = ChangeStatus::CHANGED; 9224 } 9225 } 9226 9227 return Changed; 9228 } 9229 }; 9230 9231 struct AAValueConstantRangeArgument final 9232 : AAArgumentFromCallSiteArguments< 9233 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState, 9234 true /* BridgeCallBaseContext */> { 9235 using Base = AAArgumentFromCallSiteArguments< 9236 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState, 9237 true /* BridgeCallBaseContext */>; 9238 AAValueConstantRangeArgument(const IRPosition &IRP, Attributor &A) 9239 : Base(IRP, A) {} 9240 9241 /// See AbstractAttribute::trackStatistics() 9242 void trackStatistics() const override { 9243 STATS_DECLTRACK_ARG_ATTR(value_range) 9244 } 9245 }; 9246 9247 struct AAValueConstantRangeReturned 9248 : AAReturnedFromReturnedValues<AAValueConstantRange, 9249 AAValueConstantRangeImpl, 9250 AAValueConstantRangeImpl::StateType, 9251 /* PropagateCallBaseContext */ true> { 9252 using Base = 9253 AAReturnedFromReturnedValues<AAValueConstantRange, 9254 AAValueConstantRangeImpl, 9255 AAValueConstantRangeImpl::StateType, 9256 /* PropagateCallBaseContext */ true>; 9257 AAValueConstantRangeReturned(const IRPosition &IRP, Attributor &A) 9258 : Base(IRP, A) {} 9259 9260 /// See AbstractAttribute::initialize(...). 9261 void initialize(Attributor &A) override { 9262 if (!A.isFunctionIPOAmendable(*getAssociatedFunction())) 9263 indicatePessimisticFixpoint(); 9264 } 9265 9266 /// See AbstractAttribute::trackStatistics() 9267 void trackStatistics() const override { 9268 STATS_DECLTRACK_FNRET_ATTR(value_range) 9269 } 9270 }; 9271 9272 struct AAValueConstantRangeFloating : AAValueConstantRangeImpl { 9273 AAValueConstantRangeFloating(const IRPosition &IRP, Attributor &A) 9274 : AAValueConstantRangeImpl(IRP, A) {} 9275 9276 /// See AbstractAttribute::initialize(...). 9277 void initialize(Attributor &A) override { 9278 AAValueConstantRangeImpl::initialize(A); 9279 if (isAtFixpoint()) 9280 return; 9281 9282 Value &V = getAssociatedValue(); 9283 9284 if (auto *C = dyn_cast<ConstantInt>(&V)) { 9285 unionAssumed(ConstantRange(C->getValue())); 9286 indicateOptimisticFixpoint(); 9287 return; 9288 } 9289 9290 if (isa<UndefValue>(&V)) { 9291 // Collapse the undef state to 0. 9292 unionAssumed(ConstantRange(APInt(getBitWidth(), 0))); 9293 indicateOptimisticFixpoint(); 9294 return; 9295 } 9296 9297 if (isa<CallBase>(&V)) 9298 return; 9299 9300 if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V)) 9301 return; 9302 9303 // If it is a load instruction with range metadata, use it. 9304 if (LoadInst *LI = dyn_cast<LoadInst>(&V)) 9305 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) { 9306 intersectKnown(getConstantRangeFromMetadata(*RangeMD)); 9307 return; 9308 } 9309 9310 // We can work with PHI and select instruction as we traverse their operands 9311 // during update. 9312 if (isa<SelectInst>(V) || isa<PHINode>(V)) 9313 return; 9314 9315 // Otherwise we give up. 9316 indicatePessimisticFixpoint(); 9317 9318 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: " 9319 << getAssociatedValue() << "\n"); 9320 } 9321 9322 bool calculateBinaryOperator( 9323 Attributor &A, BinaryOperator *BinOp, IntegerRangeState &T, 9324 const Instruction *CtxI, 9325 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) { 9326 Value *LHS = BinOp->getOperand(0); 9327 Value *RHS = BinOp->getOperand(1); 9328 9329 // Simplify the operands first. 9330 bool UsedAssumedInformation = false; 9331 const auto &SimplifiedLHS = A.getAssumedSimplified( 9332 IRPosition::value(*LHS, getCallBaseContext()), *this, 9333 UsedAssumedInformation, AA::Interprocedural); 9334 if (!SimplifiedLHS.has_value()) 9335 return true; 9336 if (!*SimplifiedLHS) 9337 return false; 9338 LHS = *SimplifiedLHS; 9339 9340 const auto &SimplifiedRHS = A.getAssumedSimplified( 9341 IRPosition::value(*RHS, getCallBaseContext()), *this, 9342 UsedAssumedInformation, AA::Interprocedural); 9343 if (!SimplifiedRHS.has_value()) 9344 return true; 9345 if (!*SimplifiedRHS) 9346 return false; 9347 RHS = *SimplifiedRHS; 9348 9349 // TODO: Allow non integers as well. 9350 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy()) 9351 return false; 9352 9353 auto *LHSAA = A.getAAFor<AAValueConstantRange>( 9354 *this, IRPosition::value(*LHS, getCallBaseContext()), 9355 DepClassTy::REQUIRED); 9356 if (!LHSAA) 9357 return false; 9358 QuerriedAAs.push_back(LHSAA); 9359 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI); 9360 9361 auto *RHSAA = A.getAAFor<AAValueConstantRange>( 9362 *this, IRPosition::value(*RHS, getCallBaseContext()), 9363 DepClassTy::REQUIRED); 9364 if (!RHSAA) 9365 return false; 9366 QuerriedAAs.push_back(RHSAA); 9367 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI); 9368 9369 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange); 9370 9371 T.unionAssumed(AssumedRange); 9372 9373 // TODO: Track a known state too. 9374 9375 return T.isValidState(); 9376 } 9377 9378 bool calculateCastInst( 9379 Attributor &A, CastInst *CastI, IntegerRangeState &T, 9380 const Instruction *CtxI, 9381 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) { 9382 assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!"); 9383 // TODO: Allow non integers as well. 9384 Value *OpV = CastI->getOperand(0); 9385 9386 // Simplify the operand first. 9387 bool UsedAssumedInformation = false; 9388 const auto &SimplifiedOpV = A.getAssumedSimplified( 9389 IRPosition::value(*OpV, getCallBaseContext()), *this, 9390 UsedAssumedInformation, AA::Interprocedural); 9391 if (!SimplifiedOpV.has_value()) 9392 return true; 9393 if (!*SimplifiedOpV) 9394 return false; 9395 OpV = *SimplifiedOpV; 9396 9397 if (!OpV->getType()->isIntegerTy()) 9398 return false; 9399 9400 auto *OpAA = A.getAAFor<AAValueConstantRange>( 9401 *this, IRPosition::value(*OpV, getCallBaseContext()), 9402 DepClassTy::REQUIRED); 9403 if (!OpAA) 9404 return false; 9405 QuerriedAAs.push_back(OpAA); 9406 T.unionAssumed(OpAA->getAssumed().castOp(CastI->getOpcode(), 9407 getState().getBitWidth())); 9408 return T.isValidState(); 9409 } 9410 9411 bool 9412 calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T, 9413 const Instruction *CtxI, 9414 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) { 9415 Value *LHS = CmpI->getOperand(0); 9416 Value *RHS = CmpI->getOperand(1); 9417 9418 // Simplify the operands first. 9419 bool UsedAssumedInformation = false; 9420 const auto &SimplifiedLHS = A.getAssumedSimplified( 9421 IRPosition::value(*LHS, getCallBaseContext()), *this, 9422 UsedAssumedInformation, AA::Interprocedural); 9423 if (!SimplifiedLHS.has_value()) 9424 return true; 9425 if (!*SimplifiedLHS) 9426 return false; 9427 LHS = *SimplifiedLHS; 9428 9429 const auto &SimplifiedRHS = A.getAssumedSimplified( 9430 IRPosition::value(*RHS, getCallBaseContext()), *this, 9431 UsedAssumedInformation, AA::Interprocedural); 9432 if (!SimplifiedRHS.has_value()) 9433 return true; 9434 if (!*SimplifiedRHS) 9435 return false; 9436 RHS = *SimplifiedRHS; 9437 9438 // TODO: Allow non integers as well. 9439 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy()) 9440 return false; 9441 9442 auto *LHSAA = A.getAAFor<AAValueConstantRange>( 9443 *this, IRPosition::value(*LHS, getCallBaseContext()), 9444 DepClassTy::REQUIRED); 9445 if (!LHSAA) 9446 return false; 9447 QuerriedAAs.push_back(LHSAA); 9448 auto *RHSAA = A.getAAFor<AAValueConstantRange>( 9449 *this, IRPosition::value(*RHS, getCallBaseContext()), 9450 DepClassTy::REQUIRED); 9451 if (!RHSAA) 9452 return false; 9453 QuerriedAAs.push_back(RHSAA); 9454 auto LHSAARange = LHSAA->getAssumedConstantRange(A, CtxI); 9455 auto RHSAARange = RHSAA->getAssumedConstantRange(A, CtxI); 9456 9457 // If one of them is empty set, we can't decide. 9458 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet()) 9459 return true; 9460 9461 bool MustTrue = false, MustFalse = false; 9462 9463 auto AllowedRegion = 9464 ConstantRange::makeAllowedICmpRegion(CmpI->getPredicate(), RHSAARange); 9465 9466 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet()) 9467 MustFalse = true; 9468 9469 if (LHSAARange.icmp(CmpI->getPredicate(), RHSAARange)) 9470 MustTrue = true; 9471 9472 assert((!MustTrue || !MustFalse) && 9473 "Either MustTrue or MustFalse should be false!"); 9474 9475 if (MustTrue) 9476 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1))); 9477 else if (MustFalse) 9478 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0))); 9479 else 9480 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true)); 9481 9482 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " after " 9483 << (MustTrue ? "true" : (MustFalse ? "false" : "unknown")) 9484 << ": " << T << "\n\t" << *LHSAA << "\t<op>\n\t" 9485 << *RHSAA); 9486 9487 // TODO: Track a known state too. 9488 return T.isValidState(); 9489 } 9490 9491 /// See AbstractAttribute::updateImpl(...). 9492 ChangeStatus updateImpl(Attributor &A) override { 9493 9494 IntegerRangeState T(getBitWidth()); 9495 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool { 9496 Instruction *I = dyn_cast<Instruction>(&V); 9497 if (!I || isa<CallBase>(I)) { 9498 9499 // Simplify the operand first. 9500 bool UsedAssumedInformation = false; 9501 const auto &SimplifiedOpV = A.getAssumedSimplified( 9502 IRPosition::value(V, getCallBaseContext()), *this, 9503 UsedAssumedInformation, AA::Interprocedural); 9504 if (!SimplifiedOpV.has_value()) 9505 return true; 9506 if (!*SimplifiedOpV) 9507 return false; 9508 Value *VPtr = *SimplifiedOpV; 9509 9510 // If the value is not instruction, we query AA to Attributor. 9511 const auto *AA = A.getAAFor<AAValueConstantRange>( 9512 *this, IRPosition::value(*VPtr, getCallBaseContext()), 9513 DepClassTy::REQUIRED); 9514 9515 // Clamp operator is not used to utilize a program point CtxI. 9516 if (AA) 9517 T.unionAssumed(AA->getAssumedConstantRange(A, CtxI)); 9518 else 9519 return false; 9520 9521 return T.isValidState(); 9522 } 9523 9524 SmallVector<const AAValueConstantRange *, 4> QuerriedAAs; 9525 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) { 9526 if (!calculateBinaryOperator(A, BinOp, T, CtxI, QuerriedAAs)) 9527 return false; 9528 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) { 9529 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs)) 9530 return false; 9531 } else if (auto *CastI = dyn_cast<CastInst>(I)) { 9532 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs)) 9533 return false; 9534 } else { 9535 // Give up with other instructions. 9536 // TODO: Add other instructions 9537 9538 T.indicatePessimisticFixpoint(); 9539 return false; 9540 } 9541 9542 // Catch circular reasoning in a pessimistic way for now. 9543 // TODO: Check how the range evolves and if we stripped anything, see also 9544 // AADereferenceable or AAAlign for similar situations. 9545 for (const AAValueConstantRange *QueriedAA : QuerriedAAs) { 9546 if (QueriedAA != this) 9547 continue; 9548 // If we are in a stady state we do not need to worry. 9549 if (T.getAssumed() == getState().getAssumed()) 9550 continue; 9551 T.indicatePessimisticFixpoint(); 9552 } 9553 9554 return T.isValidState(); 9555 }; 9556 9557 if (!VisitValueCB(getAssociatedValue(), getCtxI())) 9558 return indicatePessimisticFixpoint(); 9559 9560 // Ensure that long def-use chains can't cause circular reasoning either by 9561 // introducing a cutoff below. 9562 if (clampStateAndIndicateChange(getState(), T) == ChangeStatus::UNCHANGED) 9563 return ChangeStatus::UNCHANGED; 9564 if (++NumChanges > MaxNumChanges) { 9565 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] performed " << NumChanges 9566 << " but only " << MaxNumChanges 9567 << " are allowed to avoid cyclic reasoning."); 9568 return indicatePessimisticFixpoint(); 9569 } 9570 return ChangeStatus::CHANGED; 9571 } 9572 9573 /// See AbstractAttribute::trackStatistics() 9574 void trackStatistics() const override { 9575 STATS_DECLTRACK_FLOATING_ATTR(value_range) 9576 } 9577 9578 /// Tracker to bail after too many widening steps of the constant range. 9579 int NumChanges = 0; 9580 9581 /// Upper bound for the number of allowed changes (=widening steps) for the 9582 /// constant range before we give up. 9583 static constexpr int MaxNumChanges = 5; 9584 }; 9585 9586 struct AAValueConstantRangeFunction : AAValueConstantRangeImpl { 9587 AAValueConstantRangeFunction(const IRPosition &IRP, Attributor &A) 9588 : AAValueConstantRangeImpl(IRP, A) {} 9589 9590 /// See AbstractAttribute::initialize(...). 9591 ChangeStatus updateImpl(Attributor &A) override { 9592 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will " 9593 "not be called"); 9594 } 9595 9596 /// See AbstractAttribute::trackStatistics() 9597 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) } 9598 }; 9599 9600 struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction { 9601 AAValueConstantRangeCallSite(const IRPosition &IRP, Attributor &A) 9602 : AAValueConstantRangeFunction(IRP, A) {} 9603 9604 /// See AbstractAttribute::trackStatistics() 9605 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) } 9606 }; 9607 9608 struct AAValueConstantRangeCallSiteReturned 9609 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl, 9610 AAValueConstantRangeImpl::StateType, 9611 /* IntroduceCallBaseContext */ true> { 9612 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP, Attributor &A) 9613 : AACalleeToCallSite<AAValueConstantRange, AAValueConstantRangeImpl, 9614 AAValueConstantRangeImpl::StateType, 9615 /* IntroduceCallBaseContext */ true>(IRP, A) {} 9616 9617 /// See AbstractAttribute::initialize(...). 9618 void initialize(Attributor &A) override { 9619 // If it is a load instruction with range metadata, use the metadata. 9620 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue())) 9621 if (auto *RangeMD = CI->getMetadata(LLVMContext::MD_range)) 9622 intersectKnown(getConstantRangeFromMetadata(*RangeMD)); 9623 9624 AAValueConstantRangeImpl::initialize(A); 9625 } 9626 9627 /// See AbstractAttribute::trackStatistics() 9628 void trackStatistics() const override { 9629 STATS_DECLTRACK_CSRET_ATTR(value_range) 9630 } 9631 }; 9632 struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating { 9633 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP, Attributor &A) 9634 : AAValueConstantRangeFloating(IRP, A) {} 9635 9636 /// See AbstractAttribute::manifest() 9637 ChangeStatus manifest(Attributor &A) override { 9638 return ChangeStatus::UNCHANGED; 9639 } 9640 9641 /// See AbstractAttribute::trackStatistics() 9642 void trackStatistics() const override { 9643 STATS_DECLTRACK_CSARG_ATTR(value_range) 9644 } 9645 }; 9646 } // namespace 9647 9648 /// ------------------ Potential Values Attribute ------------------------- 9649 9650 namespace { 9651 struct AAPotentialConstantValuesImpl : AAPotentialConstantValues { 9652 using StateType = PotentialConstantIntValuesState; 9653 9654 AAPotentialConstantValuesImpl(const IRPosition &IRP, Attributor &A) 9655 : AAPotentialConstantValues(IRP, A) {} 9656 9657 /// See AbstractAttribute::initialize(..). 9658 void initialize(Attributor &A) override { 9659 if (A.hasSimplificationCallback(getIRPosition())) 9660 indicatePessimisticFixpoint(); 9661 else 9662 AAPotentialConstantValues::initialize(A); 9663 } 9664 9665 bool fillSetWithConstantValues(Attributor &A, const IRPosition &IRP, SetTy &S, 9666 bool &ContainsUndef, bool ForSelf) { 9667 SmallVector<AA::ValueAndContext> Values; 9668 bool UsedAssumedInformation = false; 9669 if (!A.getAssumedSimplifiedValues(IRP, *this, Values, AA::Interprocedural, 9670 UsedAssumedInformation)) { 9671 // Avoid recursion when the caller is computing constant values for this 9672 // IRP itself. 9673 if (ForSelf) 9674 return false; 9675 if (!IRP.getAssociatedType()->isIntegerTy()) 9676 return false; 9677 auto *PotentialValuesAA = A.getAAFor<AAPotentialConstantValues>( 9678 *this, IRP, DepClassTy::REQUIRED); 9679 if (!PotentialValuesAA || !PotentialValuesAA->getState().isValidState()) 9680 return false; 9681 ContainsUndef = PotentialValuesAA->getState().undefIsContained(); 9682 S = PotentialValuesAA->getState().getAssumedSet(); 9683 return true; 9684 } 9685 9686 // Copy all the constant values, except UndefValue. ContainsUndef is true 9687 // iff Values contains only UndefValue instances. If there are other known 9688 // constants, then UndefValue is dropped. 9689 ContainsUndef = false; 9690 for (auto &It : Values) { 9691 if (isa<UndefValue>(It.getValue())) { 9692 ContainsUndef = true; 9693 continue; 9694 } 9695 auto *CI = dyn_cast<ConstantInt>(It.getValue()); 9696 if (!CI) 9697 return false; 9698 S.insert(CI->getValue()); 9699 } 9700 ContainsUndef &= S.empty(); 9701 9702 return true; 9703 } 9704 9705 /// See AbstractAttribute::getAsStr(). 9706 const std::string getAsStr(Attributor *A) const override { 9707 std::string Str; 9708 llvm::raw_string_ostream OS(Str); 9709 OS << getState(); 9710 return Str; 9711 } 9712 9713 /// See AbstractAttribute::updateImpl(...). 9714 ChangeStatus updateImpl(Attributor &A) override { 9715 return indicatePessimisticFixpoint(); 9716 } 9717 }; 9718 9719 struct AAPotentialConstantValuesArgument final 9720 : AAArgumentFromCallSiteArguments<AAPotentialConstantValues, 9721 AAPotentialConstantValuesImpl, 9722 PotentialConstantIntValuesState> { 9723 using Base = AAArgumentFromCallSiteArguments<AAPotentialConstantValues, 9724 AAPotentialConstantValuesImpl, 9725 PotentialConstantIntValuesState>; 9726 AAPotentialConstantValuesArgument(const IRPosition &IRP, Attributor &A) 9727 : Base(IRP, A) {} 9728 9729 /// See AbstractAttribute::trackStatistics() 9730 void trackStatistics() const override { 9731 STATS_DECLTRACK_ARG_ATTR(potential_values) 9732 } 9733 }; 9734 9735 struct AAPotentialConstantValuesReturned 9736 : AAReturnedFromReturnedValues<AAPotentialConstantValues, 9737 AAPotentialConstantValuesImpl> { 9738 using Base = AAReturnedFromReturnedValues<AAPotentialConstantValues, 9739 AAPotentialConstantValuesImpl>; 9740 AAPotentialConstantValuesReturned(const IRPosition &IRP, Attributor &A) 9741 : Base(IRP, A) {} 9742 9743 void initialize(Attributor &A) override { 9744 if (!A.isFunctionIPOAmendable(*getAssociatedFunction())) 9745 indicatePessimisticFixpoint(); 9746 Base::initialize(A); 9747 } 9748 9749 /// See AbstractAttribute::trackStatistics() 9750 void trackStatistics() const override { 9751 STATS_DECLTRACK_FNRET_ATTR(potential_values) 9752 } 9753 }; 9754 9755 struct AAPotentialConstantValuesFloating : AAPotentialConstantValuesImpl { 9756 AAPotentialConstantValuesFloating(const IRPosition &IRP, Attributor &A) 9757 : AAPotentialConstantValuesImpl(IRP, A) {} 9758 9759 /// See AbstractAttribute::initialize(..). 9760 void initialize(Attributor &A) override { 9761 AAPotentialConstantValuesImpl::initialize(A); 9762 if (isAtFixpoint()) 9763 return; 9764 9765 Value &V = getAssociatedValue(); 9766 9767 if (auto *C = dyn_cast<ConstantInt>(&V)) { 9768 unionAssumed(C->getValue()); 9769 indicateOptimisticFixpoint(); 9770 return; 9771 } 9772 9773 if (isa<UndefValue>(&V)) { 9774 unionAssumedWithUndef(); 9775 indicateOptimisticFixpoint(); 9776 return; 9777 } 9778 9779 if (isa<BinaryOperator>(&V) || isa<ICmpInst>(&V) || isa<CastInst>(&V)) 9780 return; 9781 9782 if (isa<SelectInst>(V) || isa<PHINode>(V) || isa<LoadInst>(V)) 9783 return; 9784 9785 indicatePessimisticFixpoint(); 9786 9787 LLVM_DEBUG(dbgs() << "[AAPotentialConstantValues] We give up: " 9788 << getAssociatedValue() << "\n"); 9789 } 9790 9791 static bool calculateICmpInst(const ICmpInst *ICI, const APInt &LHS, 9792 const APInt &RHS) { 9793 return ICmpInst::compare(LHS, RHS, ICI->getPredicate()); 9794 } 9795 9796 static APInt calculateCastInst(const CastInst *CI, const APInt &Src, 9797 uint32_t ResultBitWidth) { 9798 Instruction::CastOps CastOp = CI->getOpcode(); 9799 switch (CastOp) { 9800 default: 9801 llvm_unreachable("unsupported or not integer cast"); 9802 case Instruction::Trunc: 9803 return Src.trunc(ResultBitWidth); 9804 case Instruction::SExt: 9805 return Src.sext(ResultBitWidth); 9806 case Instruction::ZExt: 9807 return Src.zext(ResultBitWidth); 9808 case Instruction::BitCast: 9809 return Src; 9810 } 9811 } 9812 9813 static APInt calculateBinaryOperator(const BinaryOperator *BinOp, 9814 const APInt &LHS, const APInt &RHS, 9815 bool &SkipOperation, bool &Unsupported) { 9816 Instruction::BinaryOps BinOpcode = BinOp->getOpcode(); 9817 // Unsupported is set to true when the binary operator is not supported. 9818 // SkipOperation is set to true when UB occur with the given operand pair 9819 // (LHS, RHS). 9820 // TODO: we should look at nsw and nuw keywords to handle operations 9821 // that create poison or undef value. 9822 switch (BinOpcode) { 9823 default: 9824 Unsupported = true; 9825 return LHS; 9826 case Instruction::Add: 9827 return LHS + RHS; 9828 case Instruction::Sub: 9829 return LHS - RHS; 9830 case Instruction::Mul: 9831 return LHS * RHS; 9832 case Instruction::UDiv: 9833 if (RHS.isZero()) { 9834 SkipOperation = true; 9835 return LHS; 9836 } 9837 return LHS.udiv(RHS); 9838 case Instruction::SDiv: 9839 if (RHS.isZero()) { 9840 SkipOperation = true; 9841 return LHS; 9842 } 9843 return LHS.sdiv(RHS); 9844 case Instruction::URem: 9845 if (RHS.isZero()) { 9846 SkipOperation = true; 9847 return LHS; 9848 } 9849 return LHS.urem(RHS); 9850 case Instruction::SRem: 9851 if (RHS.isZero()) { 9852 SkipOperation = true; 9853 return LHS; 9854 } 9855 return LHS.srem(RHS); 9856 case Instruction::Shl: 9857 return LHS.shl(RHS); 9858 case Instruction::LShr: 9859 return LHS.lshr(RHS); 9860 case Instruction::AShr: 9861 return LHS.ashr(RHS); 9862 case Instruction::And: 9863 return LHS & RHS; 9864 case Instruction::Or: 9865 return LHS | RHS; 9866 case Instruction::Xor: 9867 return LHS ^ RHS; 9868 } 9869 } 9870 9871 bool calculateBinaryOperatorAndTakeUnion(const BinaryOperator *BinOp, 9872 const APInt &LHS, const APInt &RHS) { 9873 bool SkipOperation = false; 9874 bool Unsupported = false; 9875 APInt Result = 9876 calculateBinaryOperator(BinOp, LHS, RHS, SkipOperation, Unsupported); 9877 if (Unsupported) 9878 return false; 9879 // If SkipOperation is true, we can ignore this operand pair (L, R). 9880 if (!SkipOperation) 9881 unionAssumed(Result); 9882 return isValidState(); 9883 } 9884 9885 ChangeStatus updateWithICmpInst(Attributor &A, ICmpInst *ICI) { 9886 auto AssumedBefore = getAssumed(); 9887 Value *LHS = ICI->getOperand(0); 9888 Value *RHS = ICI->getOperand(1); 9889 9890 bool LHSContainsUndef = false, RHSContainsUndef = false; 9891 SetTy LHSAAPVS, RHSAAPVS; 9892 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS, 9893 LHSContainsUndef, /* ForSelf */ false) || 9894 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS, 9895 RHSContainsUndef, /* ForSelf */ false)) 9896 return indicatePessimisticFixpoint(); 9897 9898 // TODO: make use of undef flag to limit potential values aggressively. 9899 bool MaybeTrue = false, MaybeFalse = false; 9900 const APInt Zero(RHS->getType()->getIntegerBitWidth(), 0); 9901 if (LHSContainsUndef && RHSContainsUndef) { 9902 // The result of any comparison between undefs can be soundly replaced 9903 // with undef. 9904 unionAssumedWithUndef(); 9905 } else if (LHSContainsUndef) { 9906 for (const APInt &R : RHSAAPVS) { 9907 bool CmpResult = calculateICmpInst(ICI, Zero, R); 9908 MaybeTrue |= CmpResult; 9909 MaybeFalse |= !CmpResult; 9910 if (MaybeTrue & MaybeFalse) 9911 return indicatePessimisticFixpoint(); 9912 } 9913 } else if (RHSContainsUndef) { 9914 for (const APInt &L : LHSAAPVS) { 9915 bool CmpResult = calculateICmpInst(ICI, L, Zero); 9916 MaybeTrue |= CmpResult; 9917 MaybeFalse |= !CmpResult; 9918 if (MaybeTrue & MaybeFalse) 9919 return indicatePessimisticFixpoint(); 9920 } 9921 } else { 9922 for (const APInt &L : LHSAAPVS) { 9923 for (const APInt &R : RHSAAPVS) { 9924 bool CmpResult = calculateICmpInst(ICI, L, R); 9925 MaybeTrue |= CmpResult; 9926 MaybeFalse |= !CmpResult; 9927 if (MaybeTrue & MaybeFalse) 9928 return indicatePessimisticFixpoint(); 9929 } 9930 } 9931 } 9932 if (MaybeTrue) 9933 unionAssumed(APInt(/* numBits */ 1, /* val */ 1)); 9934 if (MaybeFalse) 9935 unionAssumed(APInt(/* numBits */ 1, /* val */ 0)); 9936 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 9937 : ChangeStatus::CHANGED; 9938 } 9939 9940 ChangeStatus updateWithSelectInst(Attributor &A, SelectInst *SI) { 9941 auto AssumedBefore = getAssumed(); 9942 Value *LHS = SI->getTrueValue(); 9943 Value *RHS = SI->getFalseValue(); 9944 9945 bool UsedAssumedInformation = false; 9946 std::optional<Constant *> C = A.getAssumedConstant( 9947 *SI->getCondition(), *this, UsedAssumedInformation); 9948 9949 // Check if we only need one operand. 9950 bool OnlyLeft = false, OnlyRight = false; 9951 if (C && *C && (*C)->isOneValue()) 9952 OnlyLeft = true; 9953 else if (C && *C && (*C)->isZeroValue()) 9954 OnlyRight = true; 9955 9956 bool LHSContainsUndef = false, RHSContainsUndef = false; 9957 SetTy LHSAAPVS, RHSAAPVS; 9958 if (!OnlyRight && 9959 !fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS, 9960 LHSContainsUndef, /* ForSelf */ false)) 9961 return indicatePessimisticFixpoint(); 9962 9963 if (!OnlyLeft && 9964 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS, 9965 RHSContainsUndef, /* ForSelf */ false)) 9966 return indicatePessimisticFixpoint(); 9967 9968 if (OnlyLeft || OnlyRight) { 9969 // select (true/false), lhs, rhs 9970 auto *OpAA = OnlyLeft ? &LHSAAPVS : &RHSAAPVS; 9971 auto Undef = OnlyLeft ? LHSContainsUndef : RHSContainsUndef; 9972 9973 if (Undef) 9974 unionAssumedWithUndef(); 9975 else { 9976 for (const auto &It : *OpAA) 9977 unionAssumed(It); 9978 } 9979 9980 } else if (LHSContainsUndef && RHSContainsUndef) { 9981 // select i1 *, undef , undef => undef 9982 unionAssumedWithUndef(); 9983 } else { 9984 for (const auto &It : LHSAAPVS) 9985 unionAssumed(It); 9986 for (const auto &It : RHSAAPVS) 9987 unionAssumed(It); 9988 } 9989 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 9990 : ChangeStatus::CHANGED; 9991 } 9992 9993 ChangeStatus updateWithCastInst(Attributor &A, CastInst *CI) { 9994 auto AssumedBefore = getAssumed(); 9995 if (!CI->isIntegerCast()) 9996 return indicatePessimisticFixpoint(); 9997 assert(CI->getNumOperands() == 1 && "Expected cast to be unary!"); 9998 uint32_t ResultBitWidth = CI->getDestTy()->getIntegerBitWidth(); 9999 Value *Src = CI->getOperand(0); 10000 10001 bool SrcContainsUndef = false; 10002 SetTy SrcPVS; 10003 if (!fillSetWithConstantValues(A, IRPosition::value(*Src), SrcPVS, 10004 SrcContainsUndef, /* ForSelf */ false)) 10005 return indicatePessimisticFixpoint(); 10006 10007 if (SrcContainsUndef) 10008 unionAssumedWithUndef(); 10009 else { 10010 for (const APInt &S : SrcPVS) { 10011 APInt T = calculateCastInst(CI, S, ResultBitWidth); 10012 unionAssumed(T); 10013 } 10014 } 10015 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 10016 : ChangeStatus::CHANGED; 10017 } 10018 10019 ChangeStatus updateWithBinaryOperator(Attributor &A, BinaryOperator *BinOp) { 10020 auto AssumedBefore = getAssumed(); 10021 Value *LHS = BinOp->getOperand(0); 10022 Value *RHS = BinOp->getOperand(1); 10023 10024 bool LHSContainsUndef = false, RHSContainsUndef = false; 10025 SetTy LHSAAPVS, RHSAAPVS; 10026 if (!fillSetWithConstantValues(A, IRPosition::value(*LHS), LHSAAPVS, 10027 LHSContainsUndef, /* ForSelf */ false) || 10028 !fillSetWithConstantValues(A, IRPosition::value(*RHS), RHSAAPVS, 10029 RHSContainsUndef, /* ForSelf */ false)) 10030 return indicatePessimisticFixpoint(); 10031 10032 const APInt Zero = APInt(LHS->getType()->getIntegerBitWidth(), 0); 10033 10034 // TODO: make use of undef flag to limit potential values aggressively. 10035 if (LHSContainsUndef && RHSContainsUndef) { 10036 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, Zero)) 10037 return indicatePessimisticFixpoint(); 10038 } else if (LHSContainsUndef) { 10039 for (const APInt &R : RHSAAPVS) { 10040 if (!calculateBinaryOperatorAndTakeUnion(BinOp, Zero, R)) 10041 return indicatePessimisticFixpoint(); 10042 } 10043 } else if (RHSContainsUndef) { 10044 for (const APInt &L : LHSAAPVS) { 10045 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, Zero)) 10046 return indicatePessimisticFixpoint(); 10047 } 10048 } else { 10049 for (const APInt &L : LHSAAPVS) { 10050 for (const APInt &R : RHSAAPVS) { 10051 if (!calculateBinaryOperatorAndTakeUnion(BinOp, L, R)) 10052 return indicatePessimisticFixpoint(); 10053 } 10054 } 10055 } 10056 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 10057 : ChangeStatus::CHANGED; 10058 } 10059 10060 ChangeStatus updateWithInstruction(Attributor &A, Instruction *Inst) { 10061 auto AssumedBefore = getAssumed(); 10062 SetTy Incoming; 10063 bool ContainsUndef; 10064 if (!fillSetWithConstantValues(A, IRPosition::value(*Inst), Incoming, 10065 ContainsUndef, /* ForSelf */ true)) 10066 return indicatePessimisticFixpoint(); 10067 if (ContainsUndef) { 10068 unionAssumedWithUndef(); 10069 } else { 10070 for (const auto &It : Incoming) 10071 unionAssumed(It); 10072 } 10073 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 10074 : ChangeStatus::CHANGED; 10075 } 10076 10077 /// See AbstractAttribute::updateImpl(...). 10078 ChangeStatus updateImpl(Attributor &A) override { 10079 Value &V = getAssociatedValue(); 10080 Instruction *I = dyn_cast<Instruction>(&V); 10081 10082 if (auto *ICI = dyn_cast<ICmpInst>(I)) 10083 return updateWithICmpInst(A, ICI); 10084 10085 if (auto *SI = dyn_cast<SelectInst>(I)) 10086 return updateWithSelectInst(A, SI); 10087 10088 if (auto *CI = dyn_cast<CastInst>(I)) 10089 return updateWithCastInst(A, CI); 10090 10091 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) 10092 return updateWithBinaryOperator(A, BinOp); 10093 10094 if (isa<PHINode>(I) || isa<LoadInst>(I)) 10095 return updateWithInstruction(A, I); 10096 10097 return indicatePessimisticFixpoint(); 10098 } 10099 10100 /// See AbstractAttribute::trackStatistics() 10101 void trackStatistics() const override { 10102 STATS_DECLTRACK_FLOATING_ATTR(potential_values) 10103 } 10104 }; 10105 10106 struct AAPotentialConstantValuesFunction : AAPotentialConstantValuesImpl { 10107 AAPotentialConstantValuesFunction(const IRPosition &IRP, Attributor &A) 10108 : AAPotentialConstantValuesImpl(IRP, A) {} 10109 10110 /// See AbstractAttribute::initialize(...). 10111 ChangeStatus updateImpl(Attributor &A) override { 10112 llvm_unreachable( 10113 "AAPotentialConstantValues(Function|CallSite)::updateImpl will " 10114 "not be called"); 10115 } 10116 10117 /// See AbstractAttribute::trackStatistics() 10118 void trackStatistics() const override { 10119 STATS_DECLTRACK_FN_ATTR(potential_values) 10120 } 10121 }; 10122 10123 struct AAPotentialConstantValuesCallSite : AAPotentialConstantValuesFunction { 10124 AAPotentialConstantValuesCallSite(const IRPosition &IRP, Attributor &A) 10125 : AAPotentialConstantValuesFunction(IRP, A) {} 10126 10127 /// See AbstractAttribute::trackStatistics() 10128 void trackStatistics() const override { 10129 STATS_DECLTRACK_CS_ATTR(potential_values) 10130 } 10131 }; 10132 10133 struct AAPotentialConstantValuesCallSiteReturned 10134 : AACalleeToCallSite<AAPotentialConstantValues, 10135 AAPotentialConstantValuesImpl> { 10136 AAPotentialConstantValuesCallSiteReturned(const IRPosition &IRP, 10137 Attributor &A) 10138 : AACalleeToCallSite<AAPotentialConstantValues, 10139 AAPotentialConstantValuesImpl>(IRP, A) {} 10140 10141 /// See AbstractAttribute::trackStatistics() 10142 void trackStatistics() const override { 10143 STATS_DECLTRACK_CSRET_ATTR(potential_values) 10144 } 10145 }; 10146 10147 struct AAPotentialConstantValuesCallSiteArgument 10148 : AAPotentialConstantValuesFloating { 10149 AAPotentialConstantValuesCallSiteArgument(const IRPosition &IRP, 10150 Attributor &A) 10151 : AAPotentialConstantValuesFloating(IRP, A) {} 10152 10153 /// See AbstractAttribute::initialize(..). 10154 void initialize(Attributor &A) override { 10155 AAPotentialConstantValuesImpl::initialize(A); 10156 if (isAtFixpoint()) 10157 return; 10158 10159 Value &V = getAssociatedValue(); 10160 10161 if (auto *C = dyn_cast<ConstantInt>(&V)) { 10162 unionAssumed(C->getValue()); 10163 indicateOptimisticFixpoint(); 10164 return; 10165 } 10166 10167 if (isa<UndefValue>(&V)) { 10168 unionAssumedWithUndef(); 10169 indicateOptimisticFixpoint(); 10170 return; 10171 } 10172 } 10173 10174 /// See AbstractAttribute::updateImpl(...). 10175 ChangeStatus updateImpl(Attributor &A) override { 10176 Value &V = getAssociatedValue(); 10177 auto AssumedBefore = getAssumed(); 10178 auto *AA = A.getAAFor<AAPotentialConstantValues>( 10179 *this, IRPosition::value(V), DepClassTy::REQUIRED); 10180 if (!AA) 10181 return indicatePessimisticFixpoint(); 10182 const auto &S = AA->getAssumed(); 10183 unionAssumed(S); 10184 return AssumedBefore == getAssumed() ? ChangeStatus::UNCHANGED 10185 : ChangeStatus::CHANGED; 10186 } 10187 10188 /// See AbstractAttribute::trackStatistics() 10189 void trackStatistics() const override { 10190 STATS_DECLTRACK_CSARG_ATTR(potential_values) 10191 } 10192 }; 10193 } // namespace 10194 10195 /// ------------------------ NoUndef Attribute --------------------------------- 10196 bool AANoUndef::isImpliedByIR(Attributor &A, const IRPosition &IRP, 10197 Attribute::AttrKind ImpliedAttributeKind, 10198 bool IgnoreSubsumingPositions) { 10199 assert(ImpliedAttributeKind == Attribute::NoUndef && 10200 "Unexpected attribute kind"); 10201 if (A.hasAttr(IRP, {Attribute::NoUndef}, IgnoreSubsumingPositions, 10202 Attribute::NoUndef)) 10203 return true; 10204 10205 Value &Val = IRP.getAssociatedValue(); 10206 if (IRP.getPositionKind() != IRPosition::IRP_RETURNED && 10207 isGuaranteedNotToBeUndefOrPoison(&Val)) { 10208 LLVMContext &Ctx = Val.getContext(); 10209 A.manifestAttrs(IRP, Attribute::get(Ctx, Attribute::NoUndef)); 10210 return true; 10211 } 10212 10213 return false; 10214 } 10215 10216 namespace { 10217 struct AANoUndefImpl : AANoUndef { 10218 AANoUndefImpl(const IRPosition &IRP, Attributor &A) : AANoUndef(IRP, A) {} 10219 10220 /// See AbstractAttribute::initialize(...). 10221 void initialize(Attributor &A) override { 10222 Value &V = getAssociatedValue(); 10223 if (isa<UndefValue>(V)) 10224 indicatePessimisticFixpoint(); 10225 assert(!isImpliedByIR(A, getIRPosition(), Attribute::NoUndef)); 10226 } 10227 10228 /// See followUsesInMBEC 10229 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I, 10230 AANoUndef::StateType &State) { 10231 const Value *UseV = U->get(); 10232 const DominatorTree *DT = nullptr; 10233 AssumptionCache *AC = nullptr; 10234 InformationCache &InfoCache = A.getInfoCache(); 10235 if (Function *F = getAnchorScope()) { 10236 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F); 10237 AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F); 10238 } 10239 State.setKnown(isGuaranteedNotToBeUndefOrPoison(UseV, AC, I, DT)); 10240 bool TrackUse = false; 10241 // Track use for instructions which must produce undef or poison bits when 10242 // at least one operand contains such bits. 10243 if (isa<CastInst>(*I) || isa<GetElementPtrInst>(*I)) 10244 TrackUse = true; 10245 return TrackUse; 10246 } 10247 10248 /// See AbstractAttribute::getAsStr(). 10249 const std::string getAsStr(Attributor *A) const override { 10250 return getAssumed() ? "noundef" : "may-undef-or-poison"; 10251 } 10252 10253 ChangeStatus manifest(Attributor &A) override { 10254 // We don't manifest noundef attribute for dead positions because the 10255 // associated values with dead positions would be replaced with undef 10256 // values. 10257 bool UsedAssumedInformation = false; 10258 if (A.isAssumedDead(getIRPosition(), nullptr, nullptr, 10259 UsedAssumedInformation)) 10260 return ChangeStatus::UNCHANGED; 10261 // A position whose simplified value does not have any value is 10262 // considered to be dead. We don't manifest noundef in such positions for 10263 // the same reason above. 10264 if (!A.getAssumedSimplified(getIRPosition(), *this, UsedAssumedInformation, 10265 AA::Interprocedural) 10266 .has_value()) 10267 return ChangeStatus::UNCHANGED; 10268 return AANoUndef::manifest(A); 10269 } 10270 }; 10271 10272 struct AANoUndefFloating : public AANoUndefImpl { 10273 AANoUndefFloating(const IRPosition &IRP, Attributor &A) 10274 : AANoUndefImpl(IRP, A) {} 10275 10276 /// See AbstractAttribute::initialize(...). 10277 void initialize(Attributor &A) override { 10278 AANoUndefImpl::initialize(A); 10279 if (!getState().isAtFixpoint() && getAnchorScope() && 10280 !getAnchorScope()->isDeclaration()) 10281 if (Instruction *CtxI = getCtxI()) 10282 followUsesInMBEC(*this, A, getState(), *CtxI); 10283 } 10284 10285 /// See AbstractAttribute::updateImpl(...). 10286 ChangeStatus updateImpl(Attributor &A) override { 10287 auto VisitValueCB = [&](const IRPosition &IRP) -> bool { 10288 bool IsKnownNoUndef; 10289 return AA::hasAssumedIRAttr<Attribute::NoUndef>( 10290 A, this, IRP, DepClassTy::REQUIRED, IsKnownNoUndef); 10291 }; 10292 10293 bool Stripped; 10294 bool UsedAssumedInformation = false; 10295 Value *AssociatedValue = &getAssociatedValue(); 10296 SmallVector<AA::ValueAndContext> Values; 10297 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values, 10298 AA::AnyScope, UsedAssumedInformation)) 10299 Stripped = false; 10300 else 10301 Stripped = 10302 Values.size() != 1 || Values.front().getValue() != AssociatedValue; 10303 10304 if (!Stripped) { 10305 // If we haven't stripped anything we might still be able to use a 10306 // different AA, but only if the IRP changes. Effectively when we 10307 // interpret this not as a call site value but as a floating/argument 10308 // value. 10309 const IRPosition AVIRP = IRPosition::value(*AssociatedValue); 10310 if (AVIRP == getIRPosition() || !VisitValueCB(AVIRP)) 10311 return indicatePessimisticFixpoint(); 10312 return ChangeStatus::UNCHANGED; 10313 } 10314 10315 for (const auto &VAC : Values) 10316 if (!VisitValueCB(IRPosition::value(*VAC.getValue()))) 10317 return indicatePessimisticFixpoint(); 10318 10319 return ChangeStatus::UNCHANGED; 10320 } 10321 10322 /// See AbstractAttribute::trackStatistics() 10323 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) } 10324 }; 10325 10326 struct AANoUndefReturned final 10327 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl> { 10328 AANoUndefReturned(const IRPosition &IRP, Attributor &A) 10329 : AAReturnedFromReturnedValues<AANoUndef, AANoUndefImpl>(IRP, A) {} 10330 10331 /// See AbstractAttribute::trackStatistics() 10332 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noundef) } 10333 }; 10334 10335 struct AANoUndefArgument final 10336 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl> { 10337 AANoUndefArgument(const IRPosition &IRP, Attributor &A) 10338 : AAArgumentFromCallSiteArguments<AANoUndef, AANoUndefImpl>(IRP, A) {} 10339 10340 /// See AbstractAttribute::trackStatistics() 10341 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noundef) } 10342 }; 10343 10344 struct AANoUndefCallSiteArgument final : AANoUndefFloating { 10345 AANoUndefCallSiteArgument(const IRPosition &IRP, Attributor &A) 10346 : AANoUndefFloating(IRP, A) {} 10347 10348 /// See AbstractAttribute::trackStatistics() 10349 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noundef) } 10350 }; 10351 10352 struct AANoUndefCallSiteReturned final 10353 : AACalleeToCallSite<AANoUndef, AANoUndefImpl> { 10354 AANoUndefCallSiteReturned(const IRPosition &IRP, Attributor &A) 10355 : AACalleeToCallSite<AANoUndef, AANoUndefImpl>(IRP, A) {} 10356 10357 /// See AbstractAttribute::trackStatistics() 10358 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noundef) } 10359 }; 10360 10361 /// ------------------------ NoFPClass Attribute ------------------------------- 10362 10363 struct AANoFPClassImpl : AANoFPClass { 10364 AANoFPClassImpl(const IRPosition &IRP, Attributor &A) : AANoFPClass(IRP, A) {} 10365 10366 void initialize(Attributor &A) override { 10367 const IRPosition &IRP = getIRPosition(); 10368 10369 Value &V = IRP.getAssociatedValue(); 10370 if (isa<UndefValue>(V)) { 10371 indicateOptimisticFixpoint(); 10372 return; 10373 } 10374 10375 SmallVector<Attribute> Attrs; 10376 A.getAttrs(getIRPosition(), {Attribute::NoFPClass}, Attrs, false); 10377 for (const auto &Attr : Attrs) { 10378 addKnownBits(Attr.getNoFPClass()); 10379 } 10380 10381 const DataLayout &DL = A.getDataLayout(); 10382 if (getPositionKind() != IRPosition::IRP_RETURNED) { 10383 KnownFPClass KnownFPClass = computeKnownFPClass(&V, DL); 10384 addKnownBits(~KnownFPClass.KnownFPClasses); 10385 } 10386 10387 if (Instruction *CtxI = getCtxI()) 10388 followUsesInMBEC(*this, A, getState(), *CtxI); 10389 } 10390 10391 /// See followUsesInMBEC 10392 bool followUseInMBEC(Attributor &A, const Use *U, const Instruction *I, 10393 AANoFPClass::StateType &State) { 10394 // TODO: Determine what instructions can be looked through. 10395 auto *CB = dyn_cast<CallBase>(I); 10396 if (!CB) 10397 return false; 10398 10399 if (!CB->isArgOperand(U)) 10400 return false; 10401 10402 unsigned ArgNo = CB->getArgOperandNo(U); 10403 IRPosition IRP = IRPosition::callsite_argument(*CB, ArgNo); 10404 if (auto *NoFPAA = A.getAAFor<AANoFPClass>(*this, IRP, DepClassTy::NONE)) 10405 State.addKnownBits(NoFPAA->getState().getKnown()); 10406 return false; 10407 } 10408 10409 const std::string getAsStr(Attributor *A) const override { 10410 std::string Result = "nofpclass"; 10411 raw_string_ostream OS(Result); 10412 OS << getKnownNoFPClass() << '/' << getAssumedNoFPClass(); 10413 return Result; 10414 } 10415 10416 void getDeducedAttributes(Attributor &A, LLVMContext &Ctx, 10417 SmallVectorImpl<Attribute> &Attrs) const override { 10418 Attrs.emplace_back(Attribute::getWithNoFPClass(Ctx, getAssumedNoFPClass())); 10419 } 10420 }; 10421 10422 struct AANoFPClassFloating : public AANoFPClassImpl { 10423 AANoFPClassFloating(const IRPosition &IRP, Attributor &A) 10424 : AANoFPClassImpl(IRP, A) {} 10425 10426 /// See AbstractAttribute::updateImpl(...). 10427 ChangeStatus updateImpl(Attributor &A) override { 10428 SmallVector<AA::ValueAndContext> Values; 10429 bool UsedAssumedInformation = false; 10430 if (!A.getAssumedSimplifiedValues(getIRPosition(), *this, Values, 10431 AA::AnyScope, UsedAssumedInformation)) { 10432 Values.push_back({getAssociatedValue(), getCtxI()}); 10433 } 10434 10435 StateType T; 10436 auto VisitValueCB = [&](Value &V, const Instruction *CtxI) -> bool { 10437 const auto *AA = A.getAAFor<AANoFPClass>(*this, IRPosition::value(V), 10438 DepClassTy::REQUIRED); 10439 if (!AA || this == AA) { 10440 T.indicatePessimisticFixpoint(); 10441 } else { 10442 const AANoFPClass::StateType &S = 10443 static_cast<const AANoFPClass::StateType &>(AA->getState()); 10444 T ^= S; 10445 } 10446 return T.isValidState(); 10447 }; 10448 10449 for (const auto &VAC : Values) 10450 if (!VisitValueCB(*VAC.getValue(), VAC.getCtxI())) 10451 return indicatePessimisticFixpoint(); 10452 10453 return clampStateAndIndicateChange(getState(), T); 10454 } 10455 10456 /// See AbstractAttribute::trackStatistics() 10457 void trackStatistics() const override { 10458 STATS_DECLTRACK_FNRET_ATTR(nofpclass) 10459 } 10460 }; 10461 10462 struct AANoFPClassReturned final 10463 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl, 10464 AANoFPClassImpl::StateType, false, 10465 Attribute::None, false> { 10466 AANoFPClassReturned(const IRPosition &IRP, Attributor &A) 10467 : AAReturnedFromReturnedValues<AANoFPClass, AANoFPClassImpl, 10468 AANoFPClassImpl::StateType, false, 10469 Attribute::None, false>(IRP, A) {} 10470 10471 /// See AbstractAttribute::trackStatistics() 10472 void trackStatistics() const override { 10473 STATS_DECLTRACK_FNRET_ATTR(nofpclass) 10474 } 10475 }; 10476 10477 struct AANoFPClassArgument final 10478 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl> { 10479 AANoFPClassArgument(const IRPosition &IRP, Attributor &A) 10480 : AAArgumentFromCallSiteArguments<AANoFPClass, AANoFPClassImpl>(IRP, A) {} 10481 10482 /// See AbstractAttribute::trackStatistics() 10483 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofpclass) } 10484 }; 10485 10486 struct AANoFPClassCallSiteArgument final : AANoFPClassFloating { 10487 AANoFPClassCallSiteArgument(const IRPosition &IRP, Attributor &A) 10488 : AANoFPClassFloating(IRP, A) {} 10489 10490 /// See AbstractAttribute::trackStatistics() 10491 void trackStatistics() const override { 10492 STATS_DECLTRACK_CSARG_ATTR(nofpclass) 10493 } 10494 }; 10495 10496 struct AANoFPClassCallSiteReturned final 10497 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl> { 10498 AANoFPClassCallSiteReturned(const IRPosition &IRP, Attributor &A) 10499 : AACalleeToCallSite<AANoFPClass, AANoFPClassImpl>(IRP, A) {} 10500 10501 /// See AbstractAttribute::trackStatistics() 10502 void trackStatistics() const override { 10503 STATS_DECLTRACK_CSRET_ATTR(nofpclass) 10504 } 10505 }; 10506 10507 struct AACallEdgesImpl : public AACallEdges { 10508 AACallEdgesImpl(const IRPosition &IRP, Attributor &A) : AACallEdges(IRP, A) {} 10509 10510 const SetVector<Function *> &getOptimisticEdges() const override { 10511 return CalledFunctions; 10512 } 10513 10514 bool hasUnknownCallee() const override { return HasUnknownCallee; } 10515 10516 bool hasNonAsmUnknownCallee() const override { 10517 return HasUnknownCalleeNonAsm; 10518 } 10519 10520 const std::string getAsStr(Attributor *A) const override { 10521 return "CallEdges[" + std::to_string(HasUnknownCallee) + "," + 10522 std::to_string(CalledFunctions.size()) + "]"; 10523 } 10524 10525 void trackStatistics() const override {} 10526 10527 protected: 10528 void addCalledFunction(Function *Fn, ChangeStatus &Change) { 10529 if (CalledFunctions.insert(Fn)) { 10530 Change = ChangeStatus::CHANGED; 10531 LLVM_DEBUG(dbgs() << "[AACallEdges] New call edge: " << Fn->getName() 10532 << "\n"); 10533 } 10534 } 10535 10536 void setHasUnknownCallee(bool NonAsm, ChangeStatus &Change) { 10537 if (!HasUnknownCallee) 10538 Change = ChangeStatus::CHANGED; 10539 if (NonAsm && !HasUnknownCalleeNonAsm) 10540 Change = ChangeStatus::CHANGED; 10541 HasUnknownCalleeNonAsm |= NonAsm; 10542 HasUnknownCallee = true; 10543 } 10544 10545 private: 10546 /// Optimistic set of functions that might be called by this position. 10547 SetVector<Function *> CalledFunctions; 10548 10549 /// Is there any call with a unknown callee. 10550 bool HasUnknownCallee = false; 10551 10552 /// Is there any call with a unknown callee, excluding any inline asm. 10553 bool HasUnknownCalleeNonAsm = false; 10554 }; 10555 10556 struct AACallEdgesCallSite : public AACallEdgesImpl { 10557 AACallEdgesCallSite(const IRPosition &IRP, Attributor &A) 10558 : AACallEdgesImpl(IRP, A) {} 10559 /// See AbstractAttribute::updateImpl(...). 10560 ChangeStatus updateImpl(Attributor &A) override { 10561 ChangeStatus Change = ChangeStatus::UNCHANGED; 10562 10563 auto VisitValue = [&](Value &V, const Instruction *CtxI) -> bool { 10564 if (Function *Fn = dyn_cast<Function>(&V)) { 10565 addCalledFunction(Fn, Change); 10566 } else { 10567 LLVM_DEBUG(dbgs() << "[AACallEdges] Unrecognized value: " << V << "\n"); 10568 setHasUnknownCallee(true, Change); 10569 } 10570 10571 // Explore all values. 10572 return true; 10573 }; 10574 10575 SmallVector<AA::ValueAndContext> Values; 10576 // Process any value that we might call. 10577 auto ProcessCalledOperand = [&](Value *V, Instruction *CtxI) { 10578 if (isa<Constant>(V)) { 10579 VisitValue(*V, CtxI); 10580 return; 10581 } 10582 10583 bool UsedAssumedInformation = false; 10584 Values.clear(); 10585 if (!A.getAssumedSimplifiedValues(IRPosition::value(*V), *this, Values, 10586 AA::AnyScope, UsedAssumedInformation)) { 10587 Values.push_back({*V, CtxI}); 10588 } 10589 for (auto &VAC : Values) 10590 VisitValue(*VAC.getValue(), VAC.getCtxI()); 10591 }; 10592 10593 CallBase *CB = cast<CallBase>(getCtxI()); 10594 10595 if (auto *IA = dyn_cast<InlineAsm>(CB->getCalledOperand())) { 10596 if (IA->hasSideEffects() && 10597 !hasAssumption(*CB->getCaller(), "ompx_no_call_asm") && 10598 !hasAssumption(*CB, "ompx_no_call_asm")) { 10599 setHasUnknownCallee(false, Change); 10600 } 10601 return Change; 10602 } 10603 10604 if (CB->isIndirectCall()) 10605 if (auto *IndirectCallAA = A.getAAFor<AAIndirectCallInfo>( 10606 *this, getIRPosition(), DepClassTy::OPTIONAL)) 10607 if (IndirectCallAA->foreachCallee( 10608 [&](Function *Fn) { return VisitValue(*Fn, CB); })) 10609 return Change; 10610 10611 // The most simple case. 10612 ProcessCalledOperand(CB->getCalledOperand(), CB); 10613 10614 // Process callback functions. 10615 SmallVector<const Use *, 4u> CallbackUses; 10616 AbstractCallSite::getCallbackUses(*CB, CallbackUses); 10617 for (const Use *U : CallbackUses) 10618 ProcessCalledOperand(U->get(), CB); 10619 10620 return Change; 10621 } 10622 }; 10623 10624 struct AACallEdgesFunction : public AACallEdgesImpl { 10625 AACallEdgesFunction(const IRPosition &IRP, Attributor &A) 10626 : AACallEdgesImpl(IRP, A) {} 10627 10628 /// See AbstractAttribute::updateImpl(...). 10629 ChangeStatus updateImpl(Attributor &A) override { 10630 ChangeStatus Change = ChangeStatus::UNCHANGED; 10631 10632 auto ProcessCallInst = [&](Instruction &Inst) { 10633 CallBase &CB = cast<CallBase>(Inst); 10634 10635 auto *CBEdges = A.getAAFor<AACallEdges>( 10636 *this, IRPosition::callsite_function(CB), DepClassTy::REQUIRED); 10637 if (!CBEdges) 10638 return false; 10639 if (CBEdges->hasNonAsmUnknownCallee()) 10640 setHasUnknownCallee(true, Change); 10641 if (CBEdges->hasUnknownCallee()) 10642 setHasUnknownCallee(false, Change); 10643 10644 for (Function *F : CBEdges->getOptimisticEdges()) 10645 addCalledFunction(F, Change); 10646 10647 return true; 10648 }; 10649 10650 // Visit all callable instructions. 10651 bool UsedAssumedInformation = false; 10652 if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this, 10653 UsedAssumedInformation, 10654 /* CheckBBLivenessOnly */ true)) { 10655 // If we haven't looked at all call like instructions, assume that there 10656 // are unknown callees. 10657 setHasUnknownCallee(true, Change); 10658 } 10659 10660 return Change; 10661 } 10662 }; 10663 10664 /// -------------------AAInterFnReachability Attribute-------------------------- 10665 10666 struct AAInterFnReachabilityFunction 10667 : public CachedReachabilityAA<AAInterFnReachability, Function> { 10668 using Base = CachedReachabilityAA<AAInterFnReachability, Function>; 10669 AAInterFnReachabilityFunction(const IRPosition &IRP, Attributor &A) 10670 : Base(IRP, A) {} 10671 10672 bool instructionCanReach( 10673 Attributor &A, const Instruction &From, const Function &To, 10674 const AA::InstExclusionSetTy *ExclusionSet) const override { 10675 assert(From.getFunction() == getAnchorScope() && "Queried the wrong AA!"); 10676 auto *NonConstThis = const_cast<AAInterFnReachabilityFunction *>(this); 10677 10678 RQITy StackRQI(A, From, To, ExclusionSet, false); 10679 typename RQITy::Reachable Result; 10680 if (!NonConstThis->checkQueryCache(A, StackRQI, Result)) 10681 return NonConstThis->isReachableImpl(A, StackRQI, 10682 /*IsTemporaryRQI=*/true); 10683 return Result == RQITy::Reachable::Yes; 10684 } 10685 10686 bool isReachableImpl(Attributor &A, RQITy &RQI, 10687 bool IsTemporaryRQI) override { 10688 const Instruction *EntryI = 10689 &RQI.From->getFunction()->getEntryBlock().front(); 10690 if (EntryI != RQI.From && 10691 !instructionCanReach(A, *EntryI, *RQI.To, nullptr)) 10692 return rememberResult(A, RQITy::Reachable::No, RQI, false, 10693 IsTemporaryRQI); 10694 10695 auto CheckReachableCallBase = [&](CallBase *CB) { 10696 auto *CBEdges = A.getAAFor<AACallEdges>( 10697 *this, IRPosition::callsite_function(*CB), DepClassTy::OPTIONAL); 10698 if (!CBEdges || !CBEdges->getState().isValidState()) 10699 return false; 10700 // TODO Check To backwards in this case. 10701 if (CBEdges->hasUnknownCallee()) 10702 return false; 10703 10704 for (Function *Fn : CBEdges->getOptimisticEdges()) { 10705 if (Fn == RQI.To) 10706 return false; 10707 10708 if (Fn->isDeclaration()) { 10709 if (Fn->hasFnAttribute(Attribute::NoCallback)) 10710 continue; 10711 // TODO Check To backwards in this case. 10712 return false; 10713 } 10714 10715 if (Fn == getAnchorScope()) { 10716 if (EntryI == RQI.From) 10717 continue; 10718 return false; 10719 } 10720 10721 const AAInterFnReachability *InterFnReachability = 10722 A.getAAFor<AAInterFnReachability>(*this, IRPosition::function(*Fn), 10723 DepClassTy::OPTIONAL); 10724 10725 const Instruction &FnFirstInst = Fn->getEntryBlock().front(); 10726 if (!InterFnReachability || 10727 InterFnReachability->instructionCanReach(A, FnFirstInst, *RQI.To, 10728 RQI.ExclusionSet)) 10729 return false; 10730 } 10731 return true; 10732 }; 10733 10734 const auto *IntraFnReachability = A.getAAFor<AAIntraFnReachability>( 10735 *this, IRPosition::function(*RQI.From->getFunction()), 10736 DepClassTy::OPTIONAL); 10737 10738 // Determine call like instructions that we can reach from the inst. 10739 auto CheckCallBase = [&](Instruction &CBInst) { 10740 // There are usually less nodes in the call graph, check inter function 10741 // reachability first. 10742 if (CheckReachableCallBase(cast<CallBase>(&CBInst))) 10743 return true; 10744 return IntraFnReachability && !IntraFnReachability->isAssumedReachable( 10745 A, *RQI.From, CBInst, RQI.ExclusionSet); 10746 }; 10747 10748 bool UsedExclusionSet = /* conservative */ true; 10749 bool UsedAssumedInformation = false; 10750 if (!A.checkForAllCallLikeInstructions(CheckCallBase, *this, 10751 UsedAssumedInformation, 10752 /* CheckBBLivenessOnly */ true)) 10753 return rememberResult(A, RQITy::Reachable::Yes, RQI, UsedExclusionSet, 10754 IsTemporaryRQI); 10755 10756 return rememberResult(A, RQITy::Reachable::No, RQI, UsedExclusionSet, 10757 IsTemporaryRQI); 10758 } 10759 10760 void trackStatistics() const override {} 10761 }; 10762 } // namespace 10763 10764 template <typename AAType> 10765 static std::optional<Constant *> 10766 askForAssumedConstant(Attributor &A, const AbstractAttribute &QueryingAA, 10767 const IRPosition &IRP, Type &Ty) { 10768 if (!Ty.isIntegerTy()) 10769 return nullptr; 10770 10771 // This will also pass the call base context. 10772 const auto *AA = A.getAAFor<AAType>(QueryingAA, IRP, DepClassTy::NONE); 10773 if (!AA) 10774 return nullptr; 10775 10776 std::optional<Constant *> COpt = AA->getAssumedConstant(A); 10777 10778 if (!COpt.has_value()) { 10779 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL); 10780 return std::nullopt; 10781 } 10782 if (auto *C = *COpt) { 10783 A.recordDependence(*AA, QueryingAA, DepClassTy::OPTIONAL); 10784 return C; 10785 } 10786 return nullptr; 10787 } 10788 10789 Value *AAPotentialValues::getSingleValue( 10790 Attributor &A, const AbstractAttribute &AA, const IRPosition &IRP, 10791 SmallVectorImpl<AA::ValueAndContext> &Values) { 10792 Type &Ty = *IRP.getAssociatedType(); 10793 std::optional<Value *> V; 10794 for (auto &It : Values) { 10795 V = AA::combineOptionalValuesInAAValueLatice(V, It.getValue(), &Ty); 10796 if (V.has_value() && !*V) 10797 break; 10798 } 10799 if (!V.has_value()) 10800 return UndefValue::get(&Ty); 10801 return *V; 10802 } 10803 10804 namespace { 10805 struct AAPotentialValuesImpl : AAPotentialValues { 10806 using StateType = PotentialLLVMValuesState; 10807 10808 AAPotentialValuesImpl(const IRPosition &IRP, Attributor &A) 10809 : AAPotentialValues(IRP, A) {} 10810 10811 /// See AbstractAttribute::initialize(..). 10812 void initialize(Attributor &A) override { 10813 if (A.hasSimplificationCallback(getIRPosition())) { 10814 indicatePessimisticFixpoint(); 10815 return; 10816 } 10817 Value *Stripped = getAssociatedValue().stripPointerCasts(); 10818 if (isa<Constant>(Stripped) && !isa<ConstantExpr>(Stripped)) { 10819 addValue(A, getState(), *Stripped, getCtxI(), AA::AnyScope, 10820 getAnchorScope()); 10821 indicateOptimisticFixpoint(); 10822 return; 10823 } 10824 AAPotentialValues::initialize(A); 10825 } 10826 10827 /// See AbstractAttribute::getAsStr(). 10828 const std::string getAsStr(Attributor *A) const override { 10829 std::string Str; 10830 llvm::raw_string_ostream OS(Str); 10831 OS << getState(); 10832 return Str; 10833 } 10834 10835 template <typename AAType> 10836 static std::optional<Value *> askOtherAA(Attributor &A, 10837 const AbstractAttribute &AA, 10838 const IRPosition &IRP, Type &Ty) { 10839 if (isa<Constant>(IRP.getAssociatedValue())) 10840 return &IRP.getAssociatedValue(); 10841 std::optional<Constant *> C = askForAssumedConstant<AAType>(A, AA, IRP, Ty); 10842 if (!C) 10843 return std::nullopt; 10844 if (*C) 10845 if (auto *CC = AA::getWithType(**C, Ty)) 10846 return CC; 10847 return nullptr; 10848 } 10849 10850 virtual void addValue(Attributor &A, StateType &State, Value &V, 10851 const Instruction *CtxI, AA::ValueScope S, 10852 Function *AnchorScope) const { 10853 10854 IRPosition ValIRP = IRPosition::value(V); 10855 if (auto *CB = dyn_cast_or_null<CallBase>(CtxI)) { 10856 for (const auto &U : CB->args()) { 10857 if (U.get() != &V) 10858 continue; 10859 ValIRP = IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U)); 10860 break; 10861 } 10862 } 10863 10864 Value *VPtr = &V; 10865 if (ValIRP.getAssociatedType()->isIntegerTy()) { 10866 Type &Ty = *getAssociatedType(); 10867 std::optional<Value *> SimpleV = 10868 askOtherAA<AAValueConstantRange>(A, *this, ValIRP, Ty); 10869 if (SimpleV.has_value() && !*SimpleV) { 10870 auto *PotentialConstantsAA = A.getAAFor<AAPotentialConstantValues>( 10871 *this, ValIRP, DepClassTy::OPTIONAL); 10872 if (PotentialConstantsAA && PotentialConstantsAA->isValidState()) { 10873 for (const auto &It : PotentialConstantsAA->getAssumedSet()) 10874 State.unionAssumed({{*ConstantInt::get(&Ty, It), nullptr}, S}); 10875 if (PotentialConstantsAA->undefIsContained()) 10876 State.unionAssumed({{*UndefValue::get(&Ty), nullptr}, S}); 10877 return; 10878 } 10879 } 10880 if (!SimpleV.has_value()) 10881 return; 10882 10883 if (*SimpleV) 10884 VPtr = *SimpleV; 10885 } 10886 10887 if (isa<ConstantInt>(VPtr)) 10888 CtxI = nullptr; 10889 if (!AA::isValidInScope(*VPtr, AnchorScope)) 10890 S = AA::ValueScope(S | AA::Interprocedural); 10891 10892 State.unionAssumed({{*VPtr, CtxI}, S}); 10893 } 10894 10895 /// Helper struct to tie a value+context pair together with the scope for 10896 /// which this is the simplified version. 10897 struct ItemInfo { 10898 AA::ValueAndContext I; 10899 AA::ValueScope S; 10900 10901 bool operator==(const ItemInfo &II) const { 10902 return II.I == I && II.S == S; 10903 }; 10904 bool operator<(const ItemInfo &II) const { 10905 if (I == II.I) 10906 return S < II.S; 10907 return I < II.I; 10908 }; 10909 }; 10910 10911 bool recurseForValue(Attributor &A, const IRPosition &IRP, AA::ValueScope S) { 10912 SmallMapVector<AA::ValueAndContext, int, 8> ValueScopeMap; 10913 for (auto CS : {AA::Intraprocedural, AA::Interprocedural}) { 10914 if (!(CS & S)) 10915 continue; 10916 10917 bool UsedAssumedInformation = false; 10918 SmallVector<AA::ValueAndContext> Values; 10919 if (!A.getAssumedSimplifiedValues(IRP, this, Values, CS, 10920 UsedAssumedInformation)) 10921 return false; 10922 10923 for (auto &It : Values) 10924 ValueScopeMap[It] += CS; 10925 } 10926 for (auto &It : ValueScopeMap) 10927 addValue(A, getState(), *It.first.getValue(), It.first.getCtxI(), 10928 AA::ValueScope(It.second), getAnchorScope()); 10929 10930 return true; 10931 } 10932 10933 void giveUpOnIntraprocedural(Attributor &A) { 10934 auto NewS = StateType::getBestState(getState()); 10935 for (const auto &It : getAssumedSet()) { 10936 if (It.second == AA::Intraprocedural) 10937 continue; 10938 addValue(A, NewS, *It.first.getValue(), It.first.getCtxI(), 10939 AA::Interprocedural, getAnchorScope()); 10940 } 10941 assert(!undefIsContained() && "Undef should be an explicit value!"); 10942 addValue(A, NewS, getAssociatedValue(), getCtxI(), AA::Intraprocedural, 10943 getAnchorScope()); 10944 getState() = NewS; 10945 } 10946 10947 /// See AbstractState::indicatePessimisticFixpoint(...). 10948 ChangeStatus indicatePessimisticFixpoint() override { 10949 getState() = StateType::getBestState(getState()); 10950 getState().unionAssumed({{getAssociatedValue(), getCtxI()}, AA::AnyScope}); 10951 AAPotentialValues::indicateOptimisticFixpoint(); 10952 return ChangeStatus::CHANGED; 10953 } 10954 10955 /// See AbstractAttribute::updateImpl(...). 10956 ChangeStatus updateImpl(Attributor &A) override { 10957 return indicatePessimisticFixpoint(); 10958 } 10959 10960 /// See AbstractAttribute::manifest(...). 10961 ChangeStatus manifest(Attributor &A) override { 10962 SmallVector<AA::ValueAndContext> Values; 10963 for (AA::ValueScope S : {AA::Interprocedural, AA::Intraprocedural}) { 10964 Values.clear(); 10965 if (!getAssumedSimplifiedValues(A, Values, S)) 10966 continue; 10967 Value &OldV = getAssociatedValue(); 10968 if (isa<UndefValue>(OldV)) 10969 continue; 10970 Value *NewV = getSingleValue(A, *this, getIRPosition(), Values); 10971 if (!NewV || NewV == &OldV) 10972 continue; 10973 if (getCtxI() && 10974 !AA::isValidAtPosition({*NewV, *getCtxI()}, A.getInfoCache())) 10975 continue; 10976 if (A.changeAfterManifest(getIRPosition(), *NewV)) 10977 return ChangeStatus::CHANGED; 10978 } 10979 return ChangeStatus::UNCHANGED; 10980 } 10981 10982 bool getAssumedSimplifiedValues( 10983 Attributor &A, SmallVectorImpl<AA::ValueAndContext> &Values, 10984 AA::ValueScope S, bool RecurseForSelectAndPHI = false) const override { 10985 if (!isValidState()) 10986 return false; 10987 bool UsedAssumedInformation = false; 10988 for (const auto &It : getAssumedSet()) 10989 if (It.second & S) { 10990 if (RecurseForSelectAndPHI && (isa<PHINode>(It.first.getValue()) || 10991 isa<SelectInst>(It.first.getValue()))) { 10992 if (A.getAssumedSimplifiedValues( 10993 IRPosition::inst(*cast<Instruction>(It.first.getValue())), 10994 this, Values, S, UsedAssumedInformation)) 10995 continue; 10996 } 10997 Values.push_back(It.first); 10998 } 10999 assert(!undefIsContained() && "Undef should be an explicit value!"); 11000 return true; 11001 } 11002 }; 11003 11004 struct AAPotentialValuesFloating : AAPotentialValuesImpl { 11005 AAPotentialValuesFloating(const IRPosition &IRP, Attributor &A) 11006 : AAPotentialValuesImpl(IRP, A) {} 11007 11008 /// See AbstractAttribute::updateImpl(...). 11009 ChangeStatus updateImpl(Attributor &A) override { 11010 auto AssumedBefore = getAssumed(); 11011 11012 genericValueTraversal(A, &getAssociatedValue()); 11013 11014 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED 11015 : ChangeStatus::CHANGED; 11016 } 11017 11018 /// Helper struct to remember which AAIsDead instances we actually used. 11019 struct LivenessInfo { 11020 const AAIsDead *LivenessAA = nullptr; 11021 bool AnyDead = false; 11022 }; 11023 11024 /// Check if \p Cmp is a comparison we can simplify. 11025 /// 11026 /// We handle multiple cases, one in which at least one operand is an 11027 /// (assumed) nullptr. If so, try to simplify it using AANonNull on the other 11028 /// operand. Return true if successful, in that case Worklist will be updated. 11029 bool handleCmp(Attributor &A, Value &Cmp, Value *LHS, Value *RHS, 11030 CmpInst::Predicate Pred, ItemInfo II, 11031 SmallVectorImpl<ItemInfo> &Worklist) { 11032 11033 // Simplify the operands first. 11034 bool UsedAssumedInformation = false; 11035 SmallVector<AA::ValueAndContext> LHSValues, RHSValues; 11036 auto GetSimplifiedValues = [&](Value &V, 11037 SmallVector<AA::ValueAndContext> &Values) { 11038 if (!A.getAssumedSimplifiedValues( 11039 IRPosition::value(V, getCallBaseContext()), this, Values, 11040 AA::Intraprocedural, UsedAssumedInformation)) { 11041 Values.clear(); 11042 Values.push_back(AA::ValueAndContext{V, II.I.getCtxI()}); 11043 } 11044 return Values.empty(); 11045 }; 11046 if (GetSimplifiedValues(*LHS, LHSValues)) 11047 return true; 11048 if (GetSimplifiedValues(*RHS, RHSValues)) 11049 return true; 11050 11051 LLVMContext &Ctx = LHS->getContext(); 11052 11053 InformationCache &InfoCache = A.getInfoCache(); 11054 Instruction *CmpI = dyn_cast<Instruction>(&Cmp); 11055 Function *F = CmpI ? CmpI->getFunction() : nullptr; 11056 const auto *DT = 11057 F ? InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F) 11058 : nullptr; 11059 const auto *TLI = 11060 F ? A.getInfoCache().getTargetLibraryInfoForFunction(*F) : nullptr; 11061 auto *AC = 11062 F ? InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F) 11063 : nullptr; 11064 11065 const DataLayout &DL = A.getDataLayout(); 11066 SimplifyQuery Q(DL, TLI, DT, AC, CmpI); 11067 11068 auto CheckPair = [&](Value &LHSV, Value &RHSV) { 11069 if (isa<UndefValue>(LHSV) || isa<UndefValue>(RHSV)) { 11070 addValue(A, getState(), *UndefValue::get(Cmp.getType()), 11071 /* CtxI */ nullptr, II.S, getAnchorScope()); 11072 return true; 11073 } 11074 11075 // Handle the trivial case first in which we don't even need to think 11076 // about null or non-null. 11077 if (&LHSV == &RHSV && 11078 (CmpInst::isTrueWhenEqual(Pred) || CmpInst::isFalseWhenEqual(Pred))) { 11079 Constant *NewV = ConstantInt::get(Type::getInt1Ty(Ctx), 11080 CmpInst::isTrueWhenEqual(Pred)); 11081 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S, 11082 getAnchorScope()); 11083 return true; 11084 } 11085 11086 auto *TypedLHS = AA::getWithType(LHSV, *LHS->getType()); 11087 auto *TypedRHS = AA::getWithType(RHSV, *RHS->getType()); 11088 if (TypedLHS && TypedRHS) { 11089 Value *NewV = simplifyCmpInst(Pred, TypedLHS, TypedRHS, Q); 11090 if (NewV && NewV != &Cmp) { 11091 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S, 11092 getAnchorScope()); 11093 return true; 11094 } 11095 } 11096 11097 // From now on we only handle equalities (==, !=). 11098 if (!CmpInst::isEquality(Pred)) 11099 return false; 11100 11101 bool LHSIsNull = isa<ConstantPointerNull>(LHSV); 11102 bool RHSIsNull = isa<ConstantPointerNull>(RHSV); 11103 if (!LHSIsNull && !RHSIsNull) 11104 return false; 11105 11106 // Left is the nullptr ==/!= non-nullptr case. We'll use AANonNull on the 11107 // non-nullptr operand and if we assume it's non-null we can conclude the 11108 // result of the comparison. 11109 assert((LHSIsNull || RHSIsNull) && 11110 "Expected nullptr versus non-nullptr comparison at this point"); 11111 11112 // The index is the operand that we assume is not null. 11113 unsigned PtrIdx = LHSIsNull; 11114 bool IsKnownNonNull; 11115 bool IsAssumedNonNull = AA::hasAssumedIRAttr<Attribute::NonNull>( 11116 A, this, IRPosition::value(*(PtrIdx ? &RHSV : &LHSV)), 11117 DepClassTy::REQUIRED, IsKnownNonNull); 11118 if (!IsAssumedNonNull) 11119 return false; 11120 11121 // The new value depends on the predicate, true for != and false for ==. 11122 Constant *NewV = 11123 ConstantInt::get(Type::getInt1Ty(Ctx), Pred == CmpInst::ICMP_NE); 11124 addValue(A, getState(), *NewV, /* CtxI */ nullptr, II.S, 11125 getAnchorScope()); 11126 return true; 11127 }; 11128 11129 for (auto &LHSValue : LHSValues) 11130 for (auto &RHSValue : RHSValues) 11131 if (!CheckPair(*LHSValue.getValue(), *RHSValue.getValue())) 11132 return false; 11133 return true; 11134 } 11135 11136 bool handleSelectInst(Attributor &A, SelectInst &SI, ItemInfo II, 11137 SmallVectorImpl<ItemInfo> &Worklist) { 11138 const Instruction *CtxI = II.I.getCtxI(); 11139 bool UsedAssumedInformation = false; 11140 11141 std::optional<Constant *> C = 11142 A.getAssumedConstant(*SI.getCondition(), *this, UsedAssumedInformation); 11143 bool NoValueYet = !C.has_value(); 11144 if (NoValueYet || isa_and_nonnull<UndefValue>(*C)) 11145 return true; 11146 if (auto *CI = dyn_cast_or_null<ConstantInt>(*C)) { 11147 if (CI->isZero()) 11148 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S}); 11149 else 11150 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S}); 11151 } else if (&SI == &getAssociatedValue()) { 11152 // We could not simplify the condition, assume both values. 11153 Worklist.push_back({{*SI.getTrueValue(), CtxI}, II.S}); 11154 Worklist.push_back({{*SI.getFalseValue(), CtxI}, II.S}); 11155 } else { 11156 std::optional<Value *> SimpleV = A.getAssumedSimplified( 11157 IRPosition::inst(SI), *this, UsedAssumedInformation, II.S); 11158 if (!SimpleV.has_value()) 11159 return true; 11160 if (*SimpleV) { 11161 addValue(A, getState(), **SimpleV, CtxI, II.S, getAnchorScope()); 11162 return true; 11163 } 11164 return false; 11165 } 11166 return true; 11167 } 11168 11169 bool handleLoadInst(Attributor &A, LoadInst &LI, ItemInfo II, 11170 SmallVectorImpl<ItemInfo> &Worklist) { 11171 SmallSetVector<Value *, 4> PotentialCopies; 11172 SmallSetVector<Instruction *, 4> PotentialValueOrigins; 11173 bool UsedAssumedInformation = false; 11174 if (!AA::getPotentiallyLoadedValues(A, LI, PotentialCopies, 11175 PotentialValueOrigins, *this, 11176 UsedAssumedInformation, 11177 /* OnlyExact */ true)) { 11178 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Failed to get potentially " 11179 "loaded values for load instruction " 11180 << LI << "\n"); 11181 return false; 11182 } 11183 11184 // Do not simplify loads that are only used in llvm.assume if we cannot also 11185 // remove all stores that may feed into the load. The reason is that the 11186 // assume is probably worth something as long as the stores are around. 11187 InformationCache &InfoCache = A.getInfoCache(); 11188 if (InfoCache.isOnlyUsedByAssume(LI)) { 11189 if (!llvm::all_of(PotentialValueOrigins, [&](Instruction *I) { 11190 if (!I || isa<AssumeInst>(I)) 11191 return true; 11192 if (auto *SI = dyn_cast<StoreInst>(I)) 11193 return A.isAssumedDead(SI->getOperandUse(0), this, 11194 /* LivenessAA */ nullptr, 11195 UsedAssumedInformation, 11196 /* CheckBBLivenessOnly */ false); 11197 return A.isAssumedDead(*I, this, /* LivenessAA */ nullptr, 11198 UsedAssumedInformation, 11199 /* CheckBBLivenessOnly */ false); 11200 })) { 11201 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Load is onl used by assumes " 11202 "and we cannot delete all the stores: " 11203 << LI << "\n"); 11204 return false; 11205 } 11206 } 11207 11208 // Values have to be dynamically unique or we loose the fact that a 11209 // single llvm::Value might represent two runtime values (e.g., 11210 // stack locations in different recursive calls). 11211 const Instruction *CtxI = II.I.getCtxI(); 11212 bool ScopeIsLocal = (II.S & AA::Intraprocedural); 11213 bool AllLocal = ScopeIsLocal; 11214 bool DynamicallyUnique = llvm::all_of(PotentialCopies, [&](Value *PC) { 11215 AllLocal &= AA::isValidInScope(*PC, getAnchorScope()); 11216 return AA::isDynamicallyUnique(A, *this, *PC); 11217 }); 11218 if (!DynamicallyUnique) { 11219 LLVM_DEBUG(dbgs() << "[AAPotentialValues] Not all potentially loaded " 11220 "values are dynamically unique: " 11221 << LI << "\n"); 11222 return false; 11223 } 11224 11225 for (auto *PotentialCopy : PotentialCopies) { 11226 if (AllLocal) { 11227 Worklist.push_back({{*PotentialCopy, CtxI}, II.S}); 11228 } else { 11229 Worklist.push_back({{*PotentialCopy, CtxI}, AA::Interprocedural}); 11230 } 11231 } 11232 if (!AllLocal && ScopeIsLocal) 11233 addValue(A, getState(), LI, CtxI, AA::Intraprocedural, getAnchorScope()); 11234 return true; 11235 } 11236 11237 bool handlePHINode( 11238 Attributor &A, PHINode &PHI, ItemInfo II, 11239 SmallVectorImpl<ItemInfo> &Worklist, 11240 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) { 11241 auto GetLivenessInfo = [&](const Function &F) -> LivenessInfo & { 11242 LivenessInfo &LI = LivenessAAs[&F]; 11243 if (!LI.LivenessAA) 11244 LI.LivenessAA = A.getAAFor<AAIsDead>(*this, IRPosition::function(F), 11245 DepClassTy::NONE); 11246 return LI; 11247 }; 11248 11249 if (&PHI == &getAssociatedValue()) { 11250 LivenessInfo &LI = GetLivenessInfo(*PHI.getFunction()); 11251 const auto *CI = 11252 A.getInfoCache().getAnalysisResultForFunction<CycleAnalysis>( 11253 *PHI.getFunction()); 11254 11255 Cycle *C = nullptr; 11256 bool CyclePHI = mayBeInCycle(CI, &PHI, /* HeaderOnly */ true, &C); 11257 for (unsigned u = 0, e = PHI.getNumIncomingValues(); u < e; u++) { 11258 BasicBlock *IncomingBB = PHI.getIncomingBlock(u); 11259 if (LI.LivenessAA && 11260 LI.LivenessAA->isEdgeDead(IncomingBB, PHI.getParent())) { 11261 LI.AnyDead = true; 11262 continue; 11263 } 11264 Value *V = PHI.getIncomingValue(u); 11265 if (V == &PHI) 11266 continue; 11267 11268 // If the incoming value is not the PHI but an instruction in the same 11269 // cycle we might have multiple versions of it flying around. 11270 if (CyclePHI && isa<Instruction>(V) && 11271 (!C || C->contains(cast<Instruction>(V)->getParent()))) 11272 return false; 11273 11274 Worklist.push_back({{*V, IncomingBB->getTerminator()}, II.S}); 11275 } 11276 return true; 11277 } 11278 11279 bool UsedAssumedInformation = false; 11280 std::optional<Value *> SimpleV = A.getAssumedSimplified( 11281 IRPosition::inst(PHI), *this, UsedAssumedInformation, II.S); 11282 if (!SimpleV.has_value()) 11283 return true; 11284 if (!(*SimpleV)) 11285 return false; 11286 addValue(A, getState(), **SimpleV, &PHI, II.S, getAnchorScope()); 11287 return true; 11288 } 11289 11290 /// Use the generic, non-optimistic InstSimplfy functionality if we managed to 11291 /// simplify any operand of the instruction \p I. Return true if successful, 11292 /// in that case Worklist will be updated. 11293 bool handleGenericInst(Attributor &A, Instruction &I, ItemInfo II, 11294 SmallVectorImpl<ItemInfo> &Worklist) { 11295 bool SomeSimplified = false; 11296 bool UsedAssumedInformation = false; 11297 11298 SmallVector<Value *, 8> NewOps(I.getNumOperands()); 11299 int Idx = 0; 11300 for (Value *Op : I.operands()) { 11301 const auto &SimplifiedOp = A.getAssumedSimplified( 11302 IRPosition::value(*Op, getCallBaseContext()), *this, 11303 UsedAssumedInformation, AA::Intraprocedural); 11304 // If we are not sure about any operand we are not sure about the entire 11305 // instruction, we'll wait. 11306 if (!SimplifiedOp.has_value()) 11307 return true; 11308 11309 if (*SimplifiedOp) 11310 NewOps[Idx] = *SimplifiedOp; 11311 else 11312 NewOps[Idx] = Op; 11313 11314 SomeSimplified |= (NewOps[Idx] != Op); 11315 ++Idx; 11316 } 11317 11318 // We won't bother with the InstSimplify interface if we didn't simplify any 11319 // operand ourselves. 11320 if (!SomeSimplified) 11321 return false; 11322 11323 InformationCache &InfoCache = A.getInfoCache(); 11324 Function *F = I.getFunction(); 11325 const auto *DT = 11326 InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*F); 11327 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F); 11328 auto *AC = InfoCache.getAnalysisResultForFunction<AssumptionAnalysis>(*F); 11329 11330 const DataLayout &DL = I.getDataLayout(); 11331 SimplifyQuery Q(DL, TLI, DT, AC, &I); 11332 Value *NewV = simplifyInstructionWithOperands(&I, NewOps, Q); 11333 if (!NewV || NewV == &I) 11334 return false; 11335 11336 LLVM_DEBUG(dbgs() << "Generic inst " << I << " assumed simplified to " 11337 << *NewV << "\n"); 11338 Worklist.push_back({{*NewV, II.I.getCtxI()}, II.S}); 11339 return true; 11340 } 11341 11342 bool simplifyInstruction( 11343 Attributor &A, Instruction &I, ItemInfo II, 11344 SmallVectorImpl<ItemInfo> &Worklist, 11345 SmallMapVector<const Function *, LivenessInfo, 4> &LivenessAAs) { 11346 if (auto *CI = dyn_cast<CmpInst>(&I)) 11347 return handleCmp(A, *CI, CI->getOperand(0), CI->getOperand(1), 11348 CI->getPredicate(), II, Worklist); 11349 11350 switch (I.getOpcode()) { 11351 case Instruction::Select: 11352 return handleSelectInst(A, cast<SelectInst>(I), II, Worklist); 11353 case Instruction::PHI: 11354 return handlePHINode(A, cast<PHINode>(I), II, Worklist, LivenessAAs); 11355 case Instruction::Load: 11356 return handleLoadInst(A, cast<LoadInst>(I), II, Worklist); 11357 default: 11358 return handleGenericInst(A, I, II, Worklist); 11359 }; 11360 return false; 11361 } 11362 11363 void genericValueTraversal(Attributor &A, Value *InitialV) { 11364 SmallMapVector<const Function *, LivenessInfo, 4> LivenessAAs; 11365 11366 SmallSet<ItemInfo, 16> Visited; 11367 SmallVector<ItemInfo, 16> Worklist; 11368 Worklist.push_back({{*InitialV, getCtxI()}, AA::AnyScope}); 11369 11370 int Iteration = 0; 11371 do { 11372 ItemInfo II = Worklist.pop_back_val(); 11373 Value *V = II.I.getValue(); 11374 assert(V); 11375 const Instruction *CtxI = II.I.getCtxI(); 11376 AA::ValueScope S = II.S; 11377 11378 // Check if we should process the current value. To prevent endless 11379 // recursion keep a record of the values we followed! 11380 if (!Visited.insert(II).second) 11381 continue; 11382 11383 // Make sure we limit the compile time for complex expressions. 11384 if (Iteration++ >= MaxPotentialValuesIterations) { 11385 LLVM_DEBUG(dbgs() << "Generic value traversal reached iteration limit: " 11386 << Iteration << "!\n"); 11387 addValue(A, getState(), *V, CtxI, S, getAnchorScope()); 11388 continue; 11389 } 11390 11391 // Explicitly look through calls with a "returned" attribute if we do 11392 // not have a pointer as stripPointerCasts only works on them. 11393 Value *NewV = nullptr; 11394 if (V->getType()->isPointerTy()) { 11395 NewV = AA::getWithType(*V->stripPointerCasts(), *V->getType()); 11396 } else { 11397 if (auto *CB = dyn_cast<CallBase>(V)) 11398 if (auto *Callee = 11399 dyn_cast_if_present<Function>(CB->getCalledOperand())) { 11400 for (Argument &Arg : Callee->args()) 11401 if (Arg.hasReturnedAttr()) { 11402 NewV = CB->getArgOperand(Arg.getArgNo()); 11403 break; 11404 } 11405 } 11406 } 11407 if (NewV && NewV != V) { 11408 Worklist.push_back({{*NewV, CtxI}, S}); 11409 continue; 11410 } 11411 11412 if (auto *I = dyn_cast<Instruction>(V)) { 11413 if (simplifyInstruction(A, *I, II, Worklist, LivenessAAs)) 11414 continue; 11415 } 11416 11417 if (V != InitialV || isa<Argument>(V)) 11418 if (recurseForValue(A, IRPosition::value(*V), II.S)) 11419 continue; 11420 11421 // If we haven't stripped anything we give up. 11422 if (V == InitialV && CtxI == getCtxI()) { 11423 indicatePessimisticFixpoint(); 11424 return; 11425 } 11426 11427 addValue(A, getState(), *V, CtxI, S, getAnchorScope()); 11428 } while (!Worklist.empty()); 11429 11430 // If we actually used liveness information so we have to record a 11431 // dependence. 11432 for (auto &It : LivenessAAs) 11433 if (It.second.AnyDead) 11434 A.recordDependence(*It.second.LivenessAA, *this, DepClassTy::OPTIONAL); 11435 } 11436 11437 /// See AbstractAttribute::trackStatistics() 11438 void trackStatistics() const override { 11439 STATS_DECLTRACK_FLOATING_ATTR(potential_values) 11440 } 11441 }; 11442 11443 struct AAPotentialValuesArgument final : AAPotentialValuesImpl { 11444 using Base = AAPotentialValuesImpl; 11445 AAPotentialValuesArgument(const IRPosition &IRP, Attributor &A) 11446 : Base(IRP, A) {} 11447 11448 /// See AbstractAttribute::initialize(..). 11449 void initialize(Attributor &A) override { 11450 auto &Arg = cast<Argument>(getAssociatedValue()); 11451 if (Arg.hasPointeeInMemoryValueAttr()) 11452 indicatePessimisticFixpoint(); 11453 } 11454 11455 /// See AbstractAttribute::updateImpl(...). 11456 ChangeStatus updateImpl(Attributor &A) override { 11457 auto AssumedBefore = getAssumed(); 11458 11459 unsigned ArgNo = getCalleeArgNo(); 11460 11461 bool UsedAssumedInformation = false; 11462 SmallVector<AA::ValueAndContext> Values; 11463 auto CallSitePred = [&](AbstractCallSite ACS) { 11464 const auto CSArgIRP = IRPosition::callsite_argument(ACS, ArgNo); 11465 if (CSArgIRP.getPositionKind() == IRP_INVALID) 11466 return false; 11467 11468 if (!A.getAssumedSimplifiedValues(CSArgIRP, this, Values, 11469 AA::Interprocedural, 11470 UsedAssumedInformation)) 11471 return false; 11472 11473 return isValidState(); 11474 }; 11475 11476 if (!A.checkForAllCallSites(CallSitePred, *this, 11477 /* RequireAllCallSites */ true, 11478 UsedAssumedInformation)) 11479 return indicatePessimisticFixpoint(); 11480 11481 Function *Fn = getAssociatedFunction(); 11482 bool AnyNonLocal = false; 11483 for (auto &It : Values) { 11484 if (isa<Constant>(It.getValue())) { 11485 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope, 11486 getAnchorScope()); 11487 continue; 11488 } 11489 if (!AA::isDynamicallyUnique(A, *this, *It.getValue())) 11490 return indicatePessimisticFixpoint(); 11491 11492 if (auto *Arg = dyn_cast<Argument>(It.getValue())) 11493 if (Arg->getParent() == Fn) { 11494 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::AnyScope, 11495 getAnchorScope()); 11496 continue; 11497 } 11498 addValue(A, getState(), *It.getValue(), It.getCtxI(), AA::Interprocedural, 11499 getAnchorScope()); 11500 AnyNonLocal = true; 11501 } 11502 assert(!undefIsContained() && "Undef should be an explicit value!"); 11503 if (AnyNonLocal) 11504 giveUpOnIntraprocedural(A); 11505 11506 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED 11507 : ChangeStatus::CHANGED; 11508 } 11509 11510 /// See AbstractAttribute::trackStatistics() 11511 void trackStatistics() const override { 11512 STATS_DECLTRACK_ARG_ATTR(potential_values) 11513 } 11514 }; 11515 11516 struct AAPotentialValuesReturned : public AAPotentialValuesFloating { 11517 using Base = AAPotentialValuesFloating; 11518 AAPotentialValuesReturned(const IRPosition &IRP, Attributor &A) 11519 : Base(IRP, A) {} 11520 11521 /// See AbstractAttribute::initialize(..). 11522 void initialize(Attributor &A) override { 11523 Function *F = getAssociatedFunction(); 11524 if (!F || F->isDeclaration() || F->getReturnType()->isVoidTy()) { 11525 indicatePessimisticFixpoint(); 11526 return; 11527 } 11528 11529 for (Argument &Arg : F->args()) 11530 if (Arg.hasReturnedAttr()) { 11531 addValue(A, getState(), Arg, nullptr, AA::AnyScope, F); 11532 ReturnedArg = &Arg; 11533 break; 11534 } 11535 if (!A.isFunctionIPOAmendable(*F) || 11536 A.hasSimplificationCallback(getIRPosition())) { 11537 if (!ReturnedArg) 11538 indicatePessimisticFixpoint(); 11539 else 11540 indicateOptimisticFixpoint(); 11541 } 11542 } 11543 11544 /// See AbstractAttribute::updateImpl(...). 11545 ChangeStatus updateImpl(Attributor &A) override { 11546 auto AssumedBefore = getAssumed(); 11547 bool UsedAssumedInformation = false; 11548 11549 SmallVector<AA::ValueAndContext> Values; 11550 Function *AnchorScope = getAnchorScope(); 11551 auto HandleReturnedValue = [&](Value &V, Instruction *CtxI, 11552 bool AddValues) { 11553 for (AA::ValueScope S : {AA::Interprocedural, AA::Intraprocedural}) { 11554 Values.clear(); 11555 if (!A.getAssumedSimplifiedValues(IRPosition::value(V), this, Values, S, 11556 UsedAssumedInformation, 11557 /* RecurseForSelectAndPHI */ true)) 11558 return false; 11559 if (!AddValues) 11560 continue; 11561 11562 bool AllInterAreIntra = false; 11563 if (S == AA::Interprocedural) 11564 AllInterAreIntra = 11565 llvm::all_of(Values, [&](const AA::ValueAndContext &VAC) { 11566 return AA::isValidInScope(*VAC.getValue(), AnchorScope); 11567 }); 11568 11569 for (const AA::ValueAndContext &VAC : Values) { 11570 addValue(A, getState(), *VAC.getValue(), 11571 VAC.getCtxI() ? VAC.getCtxI() : CtxI, 11572 AllInterAreIntra ? AA::AnyScope : S, AnchorScope); 11573 } 11574 if (AllInterAreIntra) 11575 break; 11576 } 11577 return true; 11578 }; 11579 11580 if (ReturnedArg) { 11581 HandleReturnedValue(*ReturnedArg, nullptr, true); 11582 } else { 11583 auto RetInstPred = [&](Instruction &RetI) { 11584 bool AddValues = true; 11585 if (isa<PHINode>(RetI.getOperand(0)) || 11586 isa<SelectInst>(RetI.getOperand(0))) { 11587 addValue(A, getState(), *RetI.getOperand(0), &RetI, AA::AnyScope, 11588 AnchorScope); 11589 AddValues = false; 11590 } 11591 return HandleReturnedValue(*RetI.getOperand(0), &RetI, AddValues); 11592 }; 11593 11594 if (!A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret}, 11595 UsedAssumedInformation, 11596 /* CheckBBLivenessOnly */ true)) 11597 return indicatePessimisticFixpoint(); 11598 } 11599 11600 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED 11601 : ChangeStatus::CHANGED; 11602 } 11603 11604 ChangeStatus manifest(Attributor &A) override { 11605 if (ReturnedArg) 11606 return ChangeStatus::UNCHANGED; 11607 SmallVector<AA::ValueAndContext> Values; 11608 if (!getAssumedSimplifiedValues(A, Values, AA::ValueScope::Intraprocedural, 11609 /* RecurseForSelectAndPHI */ true)) 11610 return ChangeStatus::UNCHANGED; 11611 Value *NewVal = getSingleValue(A, *this, getIRPosition(), Values); 11612 if (!NewVal) 11613 return ChangeStatus::UNCHANGED; 11614 11615 ChangeStatus Changed = ChangeStatus::UNCHANGED; 11616 if (auto *Arg = dyn_cast<Argument>(NewVal)) { 11617 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn, 11618 "Number of function with unique return"); 11619 Changed |= A.manifestAttrs( 11620 IRPosition::argument(*Arg), 11621 {Attribute::get(Arg->getContext(), Attribute::Returned)}); 11622 STATS_DECLTRACK_ARG_ATTR(returned); 11623 } 11624 11625 auto RetInstPred = [&](Instruction &RetI) { 11626 Value *RetOp = RetI.getOperand(0); 11627 if (isa<UndefValue>(RetOp) || RetOp == NewVal) 11628 return true; 11629 if (AA::isValidAtPosition({*NewVal, RetI}, A.getInfoCache())) 11630 if (A.changeUseAfterManifest(RetI.getOperandUse(0), *NewVal)) 11631 Changed = ChangeStatus::CHANGED; 11632 return true; 11633 }; 11634 bool UsedAssumedInformation = false; 11635 (void)A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret}, 11636 UsedAssumedInformation, 11637 /* CheckBBLivenessOnly */ true); 11638 return Changed; 11639 } 11640 11641 ChangeStatus indicatePessimisticFixpoint() override { 11642 return AAPotentialValues::indicatePessimisticFixpoint(); 11643 } 11644 11645 /// See AbstractAttribute::trackStatistics() 11646 void trackStatistics() const override{ 11647 STATS_DECLTRACK_FNRET_ATTR(potential_values)} 11648 11649 /// The argumented with an existing `returned` attribute. 11650 Argument *ReturnedArg = nullptr; 11651 }; 11652 11653 struct AAPotentialValuesFunction : AAPotentialValuesImpl { 11654 AAPotentialValuesFunction(const IRPosition &IRP, Attributor &A) 11655 : AAPotentialValuesImpl(IRP, A) {} 11656 11657 /// See AbstractAttribute::updateImpl(...). 11658 ChangeStatus updateImpl(Attributor &A) override { 11659 llvm_unreachable("AAPotentialValues(Function|CallSite)::updateImpl will " 11660 "not be called"); 11661 } 11662 11663 /// See AbstractAttribute::trackStatistics() 11664 void trackStatistics() const override { 11665 STATS_DECLTRACK_FN_ATTR(potential_values) 11666 } 11667 }; 11668 11669 struct AAPotentialValuesCallSite : AAPotentialValuesFunction { 11670 AAPotentialValuesCallSite(const IRPosition &IRP, Attributor &A) 11671 : AAPotentialValuesFunction(IRP, A) {} 11672 11673 /// See AbstractAttribute::trackStatistics() 11674 void trackStatistics() const override { 11675 STATS_DECLTRACK_CS_ATTR(potential_values) 11676 } 11677 }; 11678 11679 struct AAPotentialValuesCallSiteReturned : AAPotentialValuesImpl { 11680 AAPotentialValuesCallSiteReturned(const IRPosition &IRP, Attributor &A) 11681 : AAPotentialValuesImpl(IRP, A) {} 11682 11683 /// See AbstractAttribute::updateImpl(...). 11684 ChangeStatus updateImpl(Attributor &A) override { 11685 auto AssumedBefore = getAssumed(); 11686 11687 Function *Callee = getAssociatedFunction(); 11688 if (!Callee) 11689 return indicatePessimisticFixpoint(); 11690 11691 bool UsedAssumedInformation = false; 11692 auto *CB = cast<CallBase>(getCtxI()); 11693 if (CB->isMustTailCall() && 11694 !A.isAssumedDead(IRPosition::inst(*CB), this, nullptr, 11695 UsedAssumedInformation)) 11696 return indicatePessimisticFixpoint(); 11697 11698 Function *Caller = CB->getCaller(); 11699 11700 auto AddScope = [&](AA::ValueScope S) { 11701 SmallVector<AA::ValueAndContext> Values; 11702 if (!A.getAssumedSimplifiedValues(IRPosition::returned(*Callee), this, 11703 Values, S, UsedAssumedInformation)) 11704 return false; 11705 11706 for (auto &It : Values) { 11707 Value *V = It.getValue(); 11708 std::optional<Value *> CallerV = A.translateArgumentToCallSiteContent( 11709 V, *CB, *this, UsedAssumedInformation); 11710 if (!CallerV.has_value()) { 11711 // Nothing to do as long as no value was determined. 11712 continue; 11713 } 11714 V = *CallerV ? *CallerV : V; 11715 if (*CallerV && AA::isDynamicallyUnique(A, *this, *V)) { 11716 if (recurseForValue(A, IRPosition::value(*V), S)) 11717 continue; 11718 } 11719 if (S == AA::Intraprocedural && !AA::isValidInScope(*V, Caller)) { 11720 giveUpOnIntraprocedural(A); 11721 return true; 11722 } 11723 addValue(A, getState(), *V, CB, S, getAnchorScope()); 11724 } 11725 return true; 11726 }; 11727 if (!AddScope(AA::Intraprocedural)) 11728 return indicatePessimisticFixpoint(); 11729 if (!AddScope(AA::Interprocedural)) 11730 return indicatePessimisticFixpoint(); 11731 return (AssumedBefore == getAssumed()) ? ChangeStatus::UNCHANGED 11732 : ChangeStatus::CHANGED; 11733 } 11734 11735 ChangeStatus indicatePessimisticFixpoint() override { 11736 return AAPotentialValues::indicatePessimisticFixpoint(); 11737 } 11738 11739 /// See AbstractAttribute::trackStatistics() 11740 void trackStatistics() const override { 11741 STATS_DECLTRACK_CSRET_ATTR(potential_values) 11742 } 11743 }; 11744 11745 struct AAPotentialValuesCallSiteArgument : AAPotentialValuesFloating { 11746 AAPotentialValuesCallSiteArgument(const IRPosition &IRP, Attributor &A) 11747 : AAPotentialValuesFloating(IRP, A) {} 11748 11749 /// See AbstractAttribute::trackStatistics() 11750 void trackStatistics() const override { 11751 STATS_DECLTRACK_CSARG_ATTR(potential_values) 11752 } 11753 }; 11754 } // namespace 11755 11756 /// ---------------------- Assumption Propagation ------------------------------ 11757 namespace { 11758 struct AAAssumptionInfoImpl : public AAAssumptionInfo { 11759 AAAssumptionInfoImpl(const IRPosition &IRP, Attributor &A, 11760 const DenseSet<StringRef> &Known) 11761 : AAAssumptionInfo(IRP, A, Known) {} 11762 11763 /// See AbstractAttribute::manifest(...). 11764 ChangeStatus manifest(Attributor &A) override { 11765 // Don't manifest a universal set if it somehow made it here. 11766 if (getKnown().isUniversal()) 11767 return ChangeStatus::UNCHANGED; 11768 11769 const IRPosition &IRP = getIRPosition(); 11770 SmallVector<StringRef, 0> Set(getAssumed().getSet().begin(), 11771 getAssumed().getSet().end()); 11772 llvm::sort(Set); 11773 return A.manifestAttrs(IRP, 11774 Attribute::get(IRP.getAnchorValue().getContext(), 11775 AssumptionAttrKey, 11776 llvm::join(Set, ",")), 11777 /*ForceReplace=*/true); 11778 } 11779 11780 bool hasAssumption(const StringRef Assumption) const override { 11781 return isValidState() && setContains(Assumption); 11782 } 11783 11784 /// See AbstractAttribute::getAsStr() 11785 const std::string getAsStr(Attributor *A) const override { 11786 const SetContents &Known = getKnown(); 11787 const SetContents &Assumed = getAssumed(); 11788 11789 SmallVector<StringRef, 0> Set(Known.getSet().begin(), Known.getSet().end()); 11790 llvm::sort(Set); 11791 const std::string KnownStr = llvm::join(Set, ","); 11792 11793 std::string AssumedStr = "Universal"; 11794 if (!Assumed.isUniversal()) { 11795 Set.assign(Assumed.getSet().begin(), Assumed.getSet().end()); 11796 AssumedStr = llvm::join(Set, ","); 11797 } 11798 return "Known [" + KnownStr + "]," + " Assumed [" + AssumedStr + "]"; 11799 } 11800 }; 11801 11802 /// Propagates assumption information from parent functions to all of their 11803 /// successors. An assumption can be propagated if the containing function 11804 /// dominates the called function. 11805 /// 11806 /// We start with a "known" set of assumptions already valid for the associated 11807 /// function and an "assumed" set that initially contains all possible 11808 /// assumptions. The assumed set is inter-procedurally updated by narrowing its 11809 /// contents as concrete values are known. The concrete values are seeded by the 11810 /// first nodes that are either entries into the call graph, or contains no 11811 /// assumptions. Each node is updated as the intersection of the assumed state 11812 /// with all of its predecessors. 11813 struct AAAssumptionInfoFunction final : AAAssumptionInfoImpl { 11814 AAAssumptionInfoFunction(const IRPosition &IRP, Attributor &A) 11815 : AAAssumptionInfoImpl(IRP, A, 11816 getAssumptions(*IRP.getAssociatedFunction())) {} 11817 11818 /// See AbstractAttribute::updateImpl(...). 11819 ChangeStatus updateImpl(Attributor &A) override { 11820 bool Changed = false; 11821 11822 auto CallSitePred = [&](AbstractCallSite ACS) { 11823 const auto *AssumptionAA = A.getAAFor<AAAssumptionInfo>( 11824 *this, IRPosition::callsite_function(*ACS.getInstruction()), 11825 DepClassTy::REQUIRED); 11826 if (!AssumptionAA) 11827 return false; 11828 // Get the set of assumptions shared by all of this function's callers. 11829 Changed |= getIntersection(AssumptionAA->getAssumed()); 11830 return !getAssumed().empty() || !getKnown().empty(); 11831 }; 11832 11833 bool UsedAssumedInformation = false; 11834 // Get the intersection of all assumptions held by this node's predecessors. 11835 // If we don't know all the call sites then this is either an entry into the 11836 // call graph or an empty node. This node is known to only contain its own 11837 // assumptions and can be propagated to its successors. 11838 if (!A.checkForAllCallSites(CallSitePred, *this, true, 11839 UsedAssumedInformation)) 11840 return indicatePessimisticFixpoint(); 11841 11842 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 11843 } 11844 11845 void trackStatistics() const override {} 11846 }; 11847 11848 /// Assumption Info defined for call sites. 11849 struct AAAssumptionInfoCallSite final : AAAssumptionInfoImpl { 11850 11851 AAAssumptionInfoCallSite(const IRPosition &IRP, Attributor &A) 11852 : AAAssumptionInfoImpl(IRP, A, getInitialAssumptions(IRP)) {} 11853 11854 /// See AbstractAttribute::initialize(...). 11855 void initialize(Attributor &A) override { 11856 const IRPosition &FnPos = IRPosition::function(*getAnchorScope()); 11857 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED); 11858 } 11859 11860 /// See AbstractAttribute::updateImpl(...). 11861 ChangeStatus updateImpl(Attributor &A) override { 11862 const IRPosition &FnPos = IRPosition::function(*getAnchorScope()); 11863 auto *AssumptionAA = 11864 A.getAAFor<AAAssumptionInfo>(*this, FnPos, DepClassTy::REQUIRED); 11865 if (!AssumptionAA) 11866 return indicatePessimisticFixpoint(); 11867 bool Changed = getIntersection(AssumptionAA->getAssumed()); 11868 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 11869 } 11870 11871 /// See AbstractAttribute::trackStatistics() 11872 void trackStatistics() const override {} 11873 11874 private: 11875 /// Helper to initialized the known set as all the assumptions this call and 11876 /// the callee contain. 11877 DenseSet<StringRef> getInitialAssumptions(const IRPosition &IRP) { 11878 const CallBase &CB = cast<CallBase>(IRP.getAssociatedValue()); 11879 auto Assumptions = getAssumptions(CB); 11880 if (const Function *F = CB.getCaller()) 11881 set_union(Assumptions, getAssumptions(*F)); 11882 if (Function *F = IRP.getAssociatedFunction()) 11883 set_union(Assumptions, getAssumptions(*F)); 11884 return Assumptions; 11885 } 11886 }; 11887 } // namespace 11888 11889 AACallGraphNode *AACallEdgeIterator::operator*() const { 11890 return static_cast<AACallGraphNode *>(const_cast<AACallEdges *>( 11891 A.getOrCreateAAFor<AACallEdges>(IRPosition::function(**I)))); 11892 } 11893 11894 void AttributorCallGraph::print() { llvm::WriteGraph(outs(), this); } 11895 11896 /// ------------------------ UnderlyingObjects --------------------------------- 11897 11898 namespace { 11899 struct AAUnderlyingObjectsImpl 11900 : StateWrapper<BooleanState, AAUnderlyingObjects> { 11901 using BaseTy = StateWrapper<BooleanState, AAUnderlyingObjects>; 11902 AAUnderlyingObjectsImpl(const IRPosition &IRP, Attributor &A) : BaseTy(IRP) {} 11903 11904 /// See AbstractAttribute::getAsStr(). 11905 const std::string getAsStr(Attributor *A) const override { 11906 if (!isValidState()) 11907 return "<invalid>"; 11908 std::string Str; 11909 llvm::raw_string_ostream OS(Str); 11910 OS << "underlying objects: inter " << InterAssumedUnderlyingObjects.size() 11911 << " objects, intra " << IntraAssumedUnderlyingObjects.size() 11912 << " objects.\n"; 11913 if (!InterAssumedUnderlyingObjects.empty()) { 11914 OS << "inter objects:\n"; 11915 for (auto *Obj : InterAssumedUnderlyingObjects) 11916 OS << *Obj << '\n'; 11917 } 11918 if (!IntraAssumedUnderlyingObjects.empty()) { 11919 OS << "intra objects:\n"; 11920 for (auto *Obj : IntraAssumedUnderlyingObjects) 11921 OS << *Obj << '\n'; 11922 } 11923 return Str; 11924 } 11925 11926 /// See AbstractAttribute::trackStatistics() 11927 void trackStatistics() const override {} 11928 11929 /// See AbstractAttribute::updateImpl(...). 11930 ChangeStatus updateImpl(Attributor &A) override { 11931 auto &Ptr = getAssociatedValue(); 11932 11933 bool UsedAssumedInformation = false; 11934 auto DoUpdate = [&](SmallSetVector<Value *, 8> &UnderlyingObjects, 11935 AA::ValueScope Scope) { 11936 SmallPtrSet<Value *, 8> SeenObjects; 11937 SmallVector<AA::ValueAndContext> Values; 11938 11939 if (!A.getAssumedSimplifiedValues(IRPosition::value(Ptr), *this, Values, 11940 Scope, UsedAssumedInformation)) 11941 return UnderlyingObjects.insert(&Ptr); 11942 11943 bool Changed = false; 11944 11945 for (unsigned I = 0; I < Values.size(); ++I) { 11946 auto &VAC = Values[I]; 11947 auto *Obj = VAC.getValue(); 11948 Value *UO = getUnderlyingObject(Obj); 11949 if (!SeenObjects.insert(UO ? UO : Obj).second) 11950 continue; 11951 if (UO && UO != Obj) { 11952 if (isa<AllocaInst>(UO) || isa<GlobalValue>(UO)) { 11953 Changed |= UnderlyingObjects.insert(UO); 11954 continue; 11955 } 11956 11957 const auto *OtherAA = A.getAAFor<AAUnderlyingObjects>( 11958 *this, IRPosition::value(*UO), DepClassTy::OPTIONAL); 11959 auto Pred = [&](Value &V) { 11960 if (&V == UO) 11961 Changed |= UnderlyingObjects.insert(UO); 11962 else 11963 Values.emplace_back(V, nullptr); 11964 return true; 11965 }; 11966 11967 if (!OtherAA || !OtherAA->forallUnderlyingObjects(Pred, Scope)) 11968 llvm_unreachable( 11969 "The forall call should not return false at this position"); 11970 UsedAssumedInformation |= !OtherAA->getState().isAtFixpoint(); 11971 continue; 11972 } 11973 11974 if (isa<SelectInst>(Obj)) { 11975 Changed |= handleIndirect(A, *Obj, UnderlyingObjects, Scope, 11976 UsedAssumedInformation); 11977 continue; 11978 } 11979 if (auto *PHI = dyn_cast<PHINode>(Obj)) { 11980 // Explicitly look through PHIs as we do not care about dynamically 11981 // uniqueness. 11982 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) { 11983 Changed |= 11984 handleIndirect(A, *PHI->getIncomingValue(u), UnderlyingObjects, 11985 Scope, UsedAssumedInformation); 11986 } 11987 continue; 11988 } 11989 11990 Changed |= UnderlyingObjects.insert(Obj); 11991 } 11992 11993 return Changed; 11994 }; 11995 11996 bool Changed = false; 11997 Changed |= DoUpdate(IntraAssumedUnderlyingObjects, AA::Intraprocedural); 11998 Changed |= DoUpdate(InterAssumedUnderlyingObjects, AA::Interprocedural); 11999 if (!UsedAssumedInformation) 12000 indicateOptimisticFixpoint(); 12001 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 12002 } 12003 12004 bool forallUnderlyingObjects( 12005 function_ref<bool(Value &)> Pred, 12006 AA::ValueScope Scope = AA::Interprocedural) const override { 12007 if (!isValidState()) 12008 return Pred(getAssociatedValue()); 12009 12010 auto &AssumedUnderlyingObjects = Scope == AA::Intraprocedural 12011 ? IntraAssumedUnderlyingObjects 12012 : InterAssumedUnderlyingObjects; 12013 for (Value *Obj : AssumedUnderlyingObjects) 12014 if (!Pred(*Obj)) 12015 return false; 12016 12017 return true; 12018 } 12019 12020 private: 12021 /// Handle the case where the value is not the actual underlying value, such 12022 /// as a phi node or a select instruction. 12023 bool handleIndirect(Attributor &A, Value &V, 12024 SmallSetVector<Value *, 8> &UnderlyingObjects, 12025 AA::ValueScope Scope, bool &UsedAssumedInformation) { 12026 bool Changed = false; 12027 const auto *AA = A.getAAFor<AAUnderlyingObjects>( 12028 *this, IRPosition::value(V), DepClassTy::OPTIONAL); 12029 auto Pred = [&](Value &V) { 12030 Changed |= UnderlyingObjects.insert(&V); 12031 return true; 12032 }; 12033 if (!AA || !AA->forallUnderlyingObjects(Pred, Scope)) 12034 llvm_unreachable( 12035 "The forall call should not return false at this position"); 12036 UsedAssumedInformation |= !AA->getState().isAtFixpoint(); 12037 return Changed; 12038 } 12039 12040 /// All the underlying objects collected so far via intra procedural scope. 12041 SmallSetVector<Value *, 8> IntraAssumedUnderlyingObjects; 12042 /// All the underlying objects collected so far via inter procedural scope. 12043 SmallSetVector<Value *, 8> InterAssumedUnderlyingObjects; 12044 }; 12045 12046 struct AAUnderlyingObjectsFloating final : AAUnderlyingObjectsImpl { 12047 AAUnderlyingObjectsFloating(const IRPosition &IRP, Attributor &A) 12048 : AAUnderlyingObjectsImpl(IRP, A) {} 12049 }; 12050 12051 struct AAUnderlyingObjectsArgument final : AAUnderlyingObjectsImpl { 12052 AAUnderlyingObjectsArgument(const IRPosition &IRP, Attributor &A) 12053 : AAUnderlyingObjectsImpl(IRP, A) {} 12054 }; 12055 12056 struct AAUnderlyingObjectsCallSite final : AAUnderlyingObjectsImpl { 12057 AAUnderlyingObjectsCallSite(const IRPosition &IRP, Attributor &A) 12058 : AAUnderlyingObjectsImpl(IRP, A) {} 12059 }; 12060 12061 struct AAUnderlyingObjectsCallSiteArgument final : AAUnderlyingObjectsImpl { 12062 AAUnderlyingObjectsCallSiteArgument(const IRPosition &IRP, Attributor &A) 12063 : AAUnderlyingObjectsImpl(IRP, A) {} 12064 }; 12065 12066 struct AAUnderlyingObjectsReturned final : AAUnderlyingObjectsImpl { 12067 AAUnderlyingObjectsReturned(const IRPosition &IRP, Attributor &A) 12068 : AAUnderlyingObjectsImpl(IRP, A) {} 12069 }; 12070 12071 struct AAUnderlyingObjectsCallSiteReturned final : AAUnderlyingObjectsImpl { 12072 AAUnderlyingObjectsCallSiteReturned(const IRPosition &IRP, Attributor &A) 12073 : AAUnderlyingObjectsImpl(IRP, A) {} 12074 }; 12075 12076 struct AAUnderlyingObjectsFunction final : AAUnderlyingObjectsImpl { 12077 AAUnderlyingObjectsFunction(const IRPosition &IRP, Attributor &A) 12078 : AAUnderlyingObjectsImpl(IRP, A) {} 12079 }; 12080 } // namespace 12081 12082 /// ------------------------ Global Value Info ------------------------------- 12083 namespace { 12084 struct AAGlobalValueInfoFloating : public AAGlobalValueInfo { 12085 AAGlobalValueInfoFloating(const IRPosition &IRP, Attributor &A) 12086 : AAGlobalValueInfo(IRP, A) {} 12087 12088 /// See AbstractAttribute::initialize(...). 12089 void initialize(Attributor &A) override {} 12090 12091 bool checkUse(Attributor &A, const Use &U, bool &Follow, 12092 SmallVectorImpl<const Value *> &Worklist) { 12093 Instruction *UInst = dyn_cast<Instruction>(U.getUser()); 12094 if (!UInst) { 12095 Follow = true; 12096 return true; 12097 } 12098 12099 LLVM_DEBUG(dbgs() << "[AAGlobalValueInfo] Check use: " << *U.get() << " in " 12100 << *UInst << "\n"); 12101 12102 if (auto *Cmp = dyn_cast<ICmpInst>(U.getUser())) { 12103 int Idx = &Cmp->getOperandUse(0) == &U; 12104 if (isa<Constant>(Cmp->getOperand(Idx))) 12105 return true; 12106 return U == &getAnchorValue(); 12107 } 12108 12109 // Explicitly catch return instructions. 12110 if (isa<ReturnInst>(UInst)) { 12111 auto CallSitePred = [&](AbstractCallSite ACS) { 12112 Worklist.push_back(ACS.getInstruction()); 12113 return true; 12114 }; 12115 bool UsedAssumedInformation = false; 12116 // TODO: We should traverse the uses or add a "non-call-site" CB. 12117 if (!A.checkForAllCallSites(CallSitePred, *UInst->getFunction(), 12118 /*RequireAllCallSites=*/true, this, 12119 UsedAssumedInformation)) 12120 return false; 12121 return true; 12122 } 12123 12124 // For now we only use special logic for call sites. However, the tracker 12125 // itself knows about a lot of other non-capturing cases already. 12126 auto *CB = dyn_cast<CallBase>(UInst); 12127 if (!CB) 12128 return false; 12129 // Direct calls are OK uses. 12130 if (CB->isCallee(&U)) 12131 return true; 12132 // Non-argument uses are scary. 12133 if (!CB->isArgOperand(&U)) 12134 return false; 12135 // TODO: Iterate callees. 12136 auto *Fn = dyn_cast<Function>(CB->getCalledOperand()); 12137 if (!Fn || !A.isFunctionIPOAmendable(*Fn)) 12138 return false; 12139 12140 unsigned ArgNo = CB->getArgOperandNo(&U); 12141 Worklist.push_back(Fn->getArg(ArgNo)); 12142 return true; 12143 } 12144 12145 ChangeStatus updateImpl(Attributor &A) override { 12146 unsigned NumUsesBefore = Uses.size(); 12147 12148 SmallPtrSet<const Value *, 8> Visited; 12149 SmallVector<const Value *> Worklist; 12150 Worklist.push_back(&getAnchorValue()); 12151 12152 auto UsePred = [&](const Use &U, bool &Follow) -> bool { 12153 Uses.insert(&U); 12154 switch (DetermineUseCaptureKind(U, nullptr)) { 12155 case UseCaptureKind::NO_CAPTURE: 12156 return checkUse(A, U, Follow, Worklist); 12157 case UseCaptureKind::MAY_CAPTURE: 12158 return checkUse(A, U, Follow, Worklist); 12159 case UseCaptureKind::PASSTHROUGH: 12160 Follow = true; 12161 return true; 12162 } 12163 return true; 12164 }; 12165 auto EquivalentUseCB = [&](const Use &OldU, const Use &NewU) { 12166 Uses.insert(&OldU); 12167 return true; 12168 }; 12169 12170 while (!Worklist.empty()) { 12171 const Value *V = Worklist.pop_back_val(); 12172 if (!Visited.insert(V).second) 12173 continue; 12174 if (!A.checkForAllUses(UsePred, *this, *V, 12175 /* CheckBBLivenessOnly */ true, 12176 DepClassTy::OPTIONAL, 12177 /* IgnoreDroppableUses */ true, EquivalentUseCB)) { 12178 return indicatePessimisticFixpoint(); 12179 } 12180 } 12181 12182 return Uses.size() == NumUsesBefore ? ChangeStatus::UNCHANGED 12183 : ChangeStatus::CHANGED; 12184 } 12185 12186 bool isPotentialUse(const Use &U) const override { 12187 return !isValidState() || Uses.contains(&U); 12188 } 12189 12190 /// See AbstractAttribute::manifest(...). 12191 ChangeStatus manifest(Attributor &A) override { 12192 return ChangeStatus::UNCHANGED; 12193 } 12194 12195 /// See AbstractAttribute::getAsStr(). 12196 const std::string getAsStr(Attributor *A) const override { 12197 return "[" + std::to_string(Uses.size()) + " uses]"; 12198 } 12199 12200 void trackStatistics() const override { 12201 STATS_DECLTRACK_FLOATING_ATTR(GlobalValuesTracked); 12202 } 12203 12204 private: 12205 /// Set of (transitive) uses of this GlobalValue. 12206 SmallPtrSet<const Use *, 8> Uses; 12207 }; 12208 } // namespace 12209 12210 /// ------------------------ Indirect Call Info ------------------------------- 12211 namespace { 12212 struct AAIndirectCallInfoCallSite : public AAIndirectCallInfo { 12213 AAIndirectCallInfoCallSite(const IRPosition &IRP, Attributor &A) 12214 : AAIndirectCallInfo(IRP, A) {} 12215 12216 /// See AbstractAttribute::initialize(...). 12217 void initialize(Attributor &A) override { 12218 auto *MD = getCtxI()->getMetadata(LLVMContext::MD_callees); 12219 if (!MD && !A.isClosedWorldModule()) 12220 return; 12221 12222 if (MD) { 12223 for (const auto &Op : MD->operands()) 12224 if (Function *Callee = mdconst::dyn_extract_or_null<Function>(Op)) 12225 PotentialCallees.insert(Callee); 12226 } else if (A.isClosedWorldModule()) { 12227 ArrayRef<Function *> IndirectlyCallableFunctions = 12228 A.getInfoCache().getIndirectlyCallableFunctions(A); 12229 PotentialCallees.insert(IndirectlyCallableFunctions.begin(), 12230 IndirectlyCallableFunctions.end()); 12231 } 12232 12233 if (PotentialCallees.empty()) 12234 indicateOptimisticFixpoint(); 12235 } 12236 12237 ChangeStatus updateImpl(Attributor &A) override { 12238 CallBase *CB = cast<CallBase>(getCtxI()); 12239 const Use &CalleeUse = CB->getCalledOperandUse(); 12240 Value *FP = CB->getCalledOperand(); 12241 12242 SmallSetVector<Function *, 4> AssumedCalleesNow; 12243 bool AllCalleesKnownNow = AllCalleesKnown; 12244 12245 auto CheckPotentialCalleeUse = [&](Function &PotentialCallee, 12246 bool &UsedAssumedInformation) { 12247 const auto *GIAA = A.getAAFor<AAGlobalValueInfo>( 12248 *this, IRPosition::value(PotentialCallee), DepClassTy::OPTIONAL); 12249 if (!GIAA || GIAA->isPotentialUse(CalleeUse)) 12250 return true; 12251 UsedAssumedInformation = !GIAA->isAtFixpoint(); 12252 return false; 12253 }; 12254 12255 auto AddPotentialCallees = [&]() { 12256 for (auto *PotentialCallee : PotentialCallees) { 12257 bool UsedAssumedInformation = false; 12258 if (CheckPotentialCalleeUse(*PotentialCallee, UsedAssumedInformation)) 12259 AssumedCalleesNow.insert(PotentialCallee); 12260 } 12261 }; 12262 12263 // Use simplification to find potential callees, if !callees was present, 12264 // fallback to that set if necessary. 12265 bool UsedAssumedInformation = false; 12266 SmallVector<AA::ValueAndContext> Values; 12267 if (!A.getAssumedSimplifiedValues(IRPosition::value(*FP), this, Values, 12268 AA::ValueScope::AnyScope, 12269 UsedAssumedInformation)) { 12270 if (PotentialCallees.empty()) 12271 return indicatePessimisticFixpoint(); 12272 AddPotentialCallees(); 12273 } 12274 12275 // Try to find a reason for \p Fn not to be a potential callee. If none was 12276 // found, add it to the assumed callees set. 12277 auto CheckPotentialCallee = [&](Function &Fn) { 12278 if (!PotentialCallees.empty() && !PotentialCallees.count(&Fn)) 12279 return false; 12280 12281 auto &CachedResult = FilterResults[&Fn]; 12282 if (CachedResult.has_value()) 12283 return CachedResult.value(); 12284 12285 bool UsedAssumedInformation = false; 12286 if (!CheckPotentialCalleeUse(Fn, UsedAssumedInformation)) { 12287 if (!UsedAssumedInformation) 12288 CachedResult = false; 12289 return false; 12290 } 12291 12292 int NumFnArgs = Fn.arg_size(); 12293 int NumCBArgs = CB->arg_size(); 12294 12295 // Check if any excess argument (which we fill up with poison) is known to 12296 // be UB on undef. 12297 for (int I = NumCBArgs; I < NumFnArgs; ++I) { 12298 bool IsKnown = false; 12299 if (AA::hasAssumedIRAttr<Attribute::NoUndef>( 12300 A, this, IRPosition::argument(*Fn.getArg(I)), 12301 DepClassTy::OPTIONAL, IsKnown)) { 12302 if (IsKnown) 12303 CachedResult = false; 12304 return false; 12305 } 12306 } 12307 12308 CachedResult = true; 12309 return true; 12310 }; 12311 12312 // Check simplification result, prune known UB callees, also restrict it to 12313 // the !callees set, if present. 12314 for (auto &VAC : Values) { 12315 if (isa<UndefValue>(VAC.getValue())) 12316 continue; 12317 if (isa<ConstantPointerNull>(VAC.getValue()) && 12318 VAC.getValue()->getType()->getPointerAddressSpace() == 0) 12319 continue; 12320 // TODO: Check for known UB, e.g., poison + noundef. 12321 if (auto *VACFn = dyn_cast<Function>(VAC.getValue())) { 12322 if (CheckPotentialCallee(*VACFn)) 12323 AssumedCalleesNow.insert(VACFn); 12324 continue; 12325 } 12326 if (!PotentialCallees.empty()) { 12327 AddPotentialCallees(); 12328 break; 12329 } 12330 AllCalleesKnownNow = false; 12331 } 12332 12333 if (AssumedCalleesNow == AssumedCallees && 12334 AllCalleesKnown == AllCalleesKnownNow) 12335 return ChangeStatus::UNCHANGED; 12336 12337 std::swap(AssumedCallees, AssumedCalleesNow); 12338 AllCalleesKnown = AllCalleesKnownNow; 12339 return ChangeStatus::CHANGED; 12340 } 12341 12342 /// See AbstractAttribute::manifest(...). 12343 ChangeStatus manifest(Attributor &A) override { 12344 // If we can't specialize at all, give up now. 12345 if (!AllCalleesKnown && AssumedCallees.empty()) 12346 return ChangeStatus::UNCHANGED; 12347 12348 CallBase *CB = cast<CallBase>(getCtxI()); 12349 bool UsedAssumedInformation = false; 12350 if (A.isAssumedDead(*CB, this, /*LivenessAA=*/nullptr, 12351 UsedAssumedInformation)) 12352 return ChangeStatus::UNCHANGED; 12353 12354 ChangeStatus Changed = ChangeStatus::UNCHANGED; 12355 Value *FP = CB->getCalledOperand(); 12356 if (FP->getType()->getPointerAddressSpace()) 12357 FP = new AddrSpaceCastInst(FP, PointerType::get(FP->getContext(), 0), 12358 FP->getName() + ".as0", CB->getIterator()); 12359 12360 bool CBIsVoid = CB->getType()->isVoidTy(); 12361 BasicBlock::iterator IP = CB->getIterator(); 12362 FunctionType *CSFT = CB->getFunctionType(); 12363 SmallVector<Value *> CSArgs(CB->args()); 12364 12365 // If we know all callees and there are none, the call site is (effectively) 12366 // dead (or UB). 12367 if (AssumedCallees.empty()) { 12368 assert(AllCalleesKnown && 12369 "Expected all callees to be known if there are none."); 12370 A.changeToUnreachableAfterManifest(CB); 12371 return ChangeStatus::CHANGED; 12372 } 12373 12374 // Special handling for the single callee case. 12375 if (AllCalleesKnown && AssumedCallees.size() == 1) { 12376 auto *NewCallee = AssumedCallees.front(); 12377 if (isLegalToPromote(*CB, NewCallee)) { 12378 promoteCall(*CB, NewCallee, nullptr); 12379 NumIndirectCallsPromoted++; 12380 return ChangeStatus::CHANGED; 12381 } 12382 Instruction *NewCall = 12383 CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs, 12384 CB->getName(), CB->getIterator()); 12385 if (!CBIsVoid) 12386 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *NewCall); 12387 A.deleteAfterManifest(*CB); 12388 return ChangeStatus::CHANGED; 12389 } 12390 12391 // For each potential value we create a conditional 12392 // 12393 // ``` 12394 // if (ptr == value) value(args); 12395 // else ... 12396 // ``` 12397 // 12398 bool SpecializedForAnyCallees = false; 12399 bool SpecializedForAllCallees = AllCalleesKnown; 12400 ICmpInst *LastCmp = nullptr; 12401 SmallVector<Function *, 8> SkippedAssumedCallees; 12402 SmallVector<std::pair<CallInst *, Instruction *>> NewCalls; 12403 for (Function *NewCallee : AssumedCallees) { 12404 if (!A.shouldSpecializeCallSiteForCallee(*this, *CB, *NewCallee, 12405 AssumedCallees.size())) { 12406 SkippedAssumedCallees.push_back(NewCallee); 12407 SpecializedForAllCallees = false; 12408 continue; 12409 } 12410 SpecializedForAnyCallees = true; 12411 12412 LastCmp = new ICmpInst(IP, llvm::CmpInst::ICMP_EQ, FP, NewCallee); 12413 Instruction *ThenTI = 12414 SplitBlockAndInsertIfThen(LastCmp, IP, /* Unreachable */ false); 12415 BasicBlock *CBBB = CB->getParent(); 12416 A.registerManifestAddedBasicBlock(*ThenTI->getParent()); 12417 A.registerManifestAddedBasicBlock(*IP->getParent()); 12418 auto *SplitTI = cast<BranchInst>(LastCmp->getNextNode()); 12419 BasicBlock *ElseBB; 12420 if (&*IP == CB) { 12421 ElseBB = BasicBlock::Create(ThenTI->getContext(), "", 12422 ThenTI->getFunction(), CBBB); 12423 A.registerManifestAddedBasicBlock(*ElseBB); 12424 IP = BranchInst::Create(CBBB, ElseBB)->getIterator(); 12425 SplitTI->replaceUsesOfWith(CBBB, ElseBB); 12426 } else { 12427 ElseBB = IP->getParent(); 12428 ThenTI->replaceUsesOfWith(ElseBB, CBBB); 12429 } 12430 CastInst *RetBC = nullptr; 12431 CallInst *NewCall = nullptr; 12432 if (isLegalToPromote(*CB, NewCallee)) { 12433 auto *CBClone = cast<CallBase>(CB->clone()); 12434 CBClone->insertBefore(ThenTI->getIterator()); 12435 NewCall = &cast<CallInst>(promoteCall(*CBClone, NewCallee, &RetBC)); 12436 NumIndirectCallsPromoted++; 12437 } else { 12438 NewCall = CallInst::Create(FunctionCallee(CSFT, NewCallee), CSArgs, 12439 CB->getName(), ThenTI->getIterator()); 12440 } 12441 NewCalls.push_back({NewCall, RetBC}); 12442 } 12443 12444 auto AttachCalleeMetadata = [&](CallBase &IndirectCB) { 12445 if (!AllCalleesKnown) 12446 return ChangeStatus::UNCHANGED; 12447 MDBuilder MDB(IndirectCB.getContext()); 12448 MDNode *Callees = MDB.createCallees(SkippedAssumedCallees); 12449 IndirectCB.setMetadata(LLVMContext::MD_callees, Callees); 12450 return ChangeStatus::CHANGED; 12451 }; 12452 12453 if (!SpecializedForAnyCallees) 12454 return AttachCalleeMetadata(*CB); 12455 12456 // Check if we need the fallback indirect call still. 12457 if (SpecializedForAllCallees) { 12458 LastCmp->replaceAllUsesWith(ConstantInt::getTrue(LastCmp->getContext())); 12459 LastCmp->eraseFromParent(); 12460 new UnreachableInst(IP->getContext(), IP); 12461 IP->eraseFromParent(); 12462 } else { 12463 auto *CBClone = cast<CallInst>(CB->clone()); 12464 CBClone->setName(CB->getName()); 12465 CBClone->insertBefore(*IP->getParent(), IP); 12466 NewCalls.push_back({CBClone, nullptr}); 12467 AttachCalleeMetadata(*CBClone); 12468 } 12469 12470 // Check if we need a PHI to merge the results. 12471 if (!CBIsVoid) { 12472 auto *PHI = PHINode::Create(CB->getType(), NewCalls.size(), 12473 CB->getName() + ".phi", 12474 CB->getParent()->getFirstInsertionPt()); 12475 for (auto &It : NewCalls) { 12476 CallBase *NewCall = It.first; 12477 Instruction *CallRet = It.second ? It.second : It.first; 12478 if (CallRet->getType() == CB->getType()) 12479 PHI->addIncoming(CallRet, CallRet->getParent()); 12480 else if (NewCall->getType()->isVoidTy()) 12481 PHI->addIncoming(PoisonValue::get(CB->getType()), 12482 NewCall->getParent()); 12483 else 12484 llvm_unreachable("Call return should match or be void!"); 12485 } 12486 A.changeAfterManifest(IRPosition::callsite_returned(*CB), *PHI); 12487 } 12488 12489 A.deleteAfterManifest(*CB); 12490 Changed = ChangeStatus::CHANGED; 12491 12492 return Changed; 12493 } 12494 12495 /// See AbstractAttribute::getAsStr(). 12496 const std::string getAsStr(Attributor *A) const override { 12497 return std::string(AllCalleesKnown ? "eliminate" : "specialize") + 12498 " indirect call site with " + std::to_string(AssumedCallees.size()) + 12499 " functions"; 12500 } 12501 12502 void trackStatistics() const override { 12503 if (AllCalleesKnown) { 12504 STATS_DECLTRACK( 12505 Eliminated, CallSites, 12506 "Number of indirect call sites eliminated via specialization") 12507 } else { 12508 STATS_DECLTRACK(Specialized, CallSites, 12509 "Number of indirect call sites specialized") 12510 } 12511 } 12512 12513 bool foreachCallee(function_ref<bool(Function *)> CB) const override { 12514 return isValidState() && AllCalleesKnown && all_of(AssumedCallees, CB); 12515 } 12516 12517 private: 12518 /// Map to remember filter results. 12519 DenseMap<Function *, std::optional<bool>> FilterResults; 12520 12521 /// If the !callee metadata was present, this set will contain all potential 12522 /// callees (superset). 12523 SmallSetVector<Function *, 4> PotentialCallees; 12524 12525 /// This set contains all currently assumed calllees, which might grow over 12526 /// time. 12527 SmallSetVector<Function *, 4> AssumedCallees; 12528 12529 /// Flag to indicate if all possible callees are in the AssumedCallees set or 12530 /// if there could be others. 12531 bool AllCalleesKnown = true; 12532 }; 12533 } // namespace 12534 12535 /// ------------------------ Address Space ------------------------------------ 12536 namespace { 12537 12538 template <typename InstType> 12539 static bool makeChange(Attributor &A, InstType *MemInst, const Use &U, 12540 Value *OriginalValue, PointerType *NewPtrTy, 12541 bool UseOriginalValue) { 12542 if (U.getOperandNo() != InstType::getPointerOperandIndex()) 12543 return false; 12544 12545 if (MemInst->isVolatile()) { 12546 auto *TTI = A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>( 12547 *MemInst->getFunction()); 12548 unsigned NewAS = NewPtrTy->getPointerAddressSpace(); 12549 if (!TTI || !TTI->hasVolatileVariant(MemInst, NewAS)) 12550 return false; 12551 } 12552 12553 if (UseOriginalValue) { 12554 A.changeUseAfterManifest(const_cast<Use &>(U), *OriginalValue); 12555 return true; 12556 } 12557 12558 Instruction *CastInst = new AddrSpaceCastInst(OriginalValue, NewPtrTy); 12559 CastInst->insertBefore(MemInst->getIterator()); 12560 A.changeUseAfterManifest(const_cast<Use &>(U), *CastInst); 12561 return true; 12562 } 12563 12564 struct AAAddressSpaceImpl : public AAAddressSpace { 12565 AAAddressSpaceImpl(const IRPosition &IRP, Attributor &A) 12566 : AAAddressSpace(IRP, A) {} 12567 12568 uint32_t getAddressSpace() const override { 12569 assert(isValidState() && "the AA is invalid"); 12570 return AssumedAddressSpace; 12571 } 12572 12573 /// See AbstractAttribute::initialize(...). 12574 void initialize(Attributor &A) override { 12575 assert(getAssociatedType()->isPtrOrPtrVectorTy() && 12576 "Associated value is not a pointer"); 12577 12578 if (!A.getInfoCache().getFlatAddressSpace().has_value()) { 12579 indicatePessimisticFixpoint(); 12580 return; 12581 } 12582 12583 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value(); 12584 unsigned AS = getAssociatedType()->getPointerAddressSpace(); 12585 if (AS != FlatAS) { 12586 [[maybe_unused]] bool R = takeAddressSpace(AS); 12587 assert(R && "The take should happen"); 12588 indicateOptimisticFixpoint(); 12589 } 12590 } 12591 12592 ChangeStatus updateImpl(Attributor &A) override { 12593 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value(); 12594 uint32_t OldAddressSpace = AssumedAddressSpace; 12595 12596 auto CheckAddressSpace = [&](Value &Obj) { 12597 if (isa<UndefValue>(&Obj)) 12598 return true; 12599 // If an argument in flat address space only has addrspace cast uses, and 12600 // those casts are same, then we take the dst addrspace. 12601 if (auto *Arg = dyn_cast<Argument>(&Obj)) { 12602 if (Arg->getType()->getPointerAddressSpace() == FlatAS) { 12603 unsigned CastAddrSpace = FlatAS; 12604 for (auto *U : Arg->users()) { 12605 auto *ASCI = dyn_cast<AddrSpaceCastInst>(U); 12606 if (!ASCI) 12607 return takeAddressSpace(Obj.getType()->getPointerAddressSpace()); 12608 if (CastAddrSpace != FlatAS && 12609 CastAddrSpace != ASCI->getDestAddressSpace()) 12610 return false; 12611 CastAddrSpace = ASCI->getDestAddressSpace(); 12612 } 12613 if (CastAddrSpace != FlatAS) 12614 return takeAddressSpace(CastAddrSpace); 12615 } 12616 } 12617 return takeAddressSpace(Obj.getType()->getPointerAddressSpace()); 12618 }; 12619 12620 auto *AUO = A.getOrCreateAAFor<AAUnderlyingObjects>(getIRPosition(), this, 12621 DepClassTy::REQUIRED); 12622 if (!AUO->forallUnderlyingObjects(CheckAddressSpace)) 12623 return indicatePessimisticFixpoint(); 12624 12625 return OldAddressSpace == AssumedAddressSpace ? ChangeStatus::UNCHANGED 12626 : ChangeStatus::CHANGED; 12627 } 12628 12629 /// See AbstractAttribute::manifest(...). 12630 ChangeStatus manifest(Attributor &A) override { 12631 unsigned NewAS = getAddressSpace(); 12632 12633 if (NewAS == InvalidAddressSpace || 12634 NewAS == getAssociatedType()->getPointerAddressSpace()) 12635 return ChangeStatus::UNCHANGED; 12636 12637 unsigned FlatAS = A.getInfoCache().getFlatAddressSpace().value(); 12638 12639 Value *AssociatedValue = &getAssociatedValue(); 12640 Value *OriginalValue = peelAddrspacecast(AssociatedValue, FlatAS); 12641 12642 PointerType *NewPtrTy = 12643 PointerType::get(getAssociatedType()->getContext(), NewAS); 12644 bool UseOriginalValue = 12645 OriginalValue->getType()->getPointerAddressSpace() == NewAS; 12646 12647 bool Changed = false; 12648 12649 auto Pred = [&](const Use &U, bool &) { 12650 if (U.get() != AssociatedValue) 12651 return true; 12652 auto *Inst = dyn_cast<Instruction>(U.getUser()); 12653 if (!Inst) 12654 return true; 12655 // This is a WA to make sure we only change uses from the corresponding 12656 // CGSCC if the AA is run on CGSCC instead of the entire module. 12657 if (!A.isRunOn(Inst->getFunction())) 12658 return true; 12659 if (auto *LI = dyn_cast<LoadInst>(Inst)) { 12660 Changed |= 12661 makeChange(A, LI, U, OriginalValue, NewPtrTy, UseOriginalValue); 12662 } else if (auto *SI = dyn_cast<StoreInst>(Inst)) { 12663 Changed |= 12664 makeChange(A, SI, U, OriginalValue, NewPtrTy, UseOriginalValue); 12665 } else if (auto *RMW = dyn_cast<AtomicRMWInst>(Inst)) { 12666 Changed |= 12667 makeChange(A, RMW, U, OriginalValue, NewPtrTy, UseOriginalValue); 12668 } else if (auto *CmpX = dyn_cast<AtomicCmpXchgInst>(Inst)) { 12669 Changed |= 12670 makeChange(A, CmpX, U, OriginalValue, NewPtrTy, UseOriginalValue); 12671 } 12672 return true; 12673 }; 12674 12675 // It doesn't matter if we can't check all uses as we can simply 12676 // conservatively ignore those that can not be visited. 12677 (void)A.checkForAllUses(Pred, *this, getAssociatedValue(), 12678 /* CheckBBLivenessOnly */ true); 12679 12680 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED; 12681 } 12682 12683 /// See AbstractAttribute::getAsStr(). 12684 const std::string getAsStr(Attributor *A) const override { 12685 if (!isValidState()) 12686 return "addrspace(<invalid>)"; 12687 return "addrspace(" + 12688 (AssumedAddressSpace == InvalidAddressSpace 12689 ? "none" 12690 : std::to_string(AssumedAddressSpace)) + 12691 ")"; 12692 } 12693 12694 private: 12695 uint32_t AssumedAddressSpace = InvalidAddressSpace; 12696 12697 bool takeAddressSpace(uint32_t AS) { 12698 if (AssumedAddressSpace == InvalidAddressSpace) { 12699 AssumedAddressSpace = AS; 12700 return true; 12701 } 12702 return AssumedAddressSpace == AS; 12703 } 12704 12705 static Value *peelAddrspacecast(Value *V, unsigned FlatAS) { 12706 if (auto *I = dyn_cast<AddrSpaceCastInst>(V)) { 12707 assert(I->getSrcAddressSpace() != FlatAS && 12708 "there should not be flat AS -> non-flat AS"); 12709 return I->getPointerOperand(); 12710 } 12711 if (auto *C = dyn_cast<ConstantExpr>(V)) 12712 if (C->getOpcode() == Instruction::AddrSpaceCast) { 12713 assert(C->getOperand(0)->getType()->getPointerAddressSpace() != 12714 FlatAS && 12715 "there should not be flat AS -> non-flat AS X"); 12716 return C->getOperand(0); 12717 } 12718 return V; 12719 } 12720 }; 12721 12722 struct AAAddressSpaceFloating final : AAAddressSpaceImpl { 12723 AAAddressSpaceFloating(const IRPosition &IRP, Attributor &A) 12724 : AAAddressSpaceImpl(IRP, A) {} 12725 12726 void trackStatistics() const override { 12727 STATS_DECLTRACK_FLOATING_ATTR(addrspace); 12728 } 12729 }; 12730 12731 struct AAAddressSpaceReturned final : AAAddressSpaceImpl { 12732 AAAddressSpaceReturned(const IRPosition &IRP, Attributor &A) 12733 : AAAddressSpaceImpl(IRP, A) {} 12734 12735 /// See AbstractAttribute::initialize(...). 12736 void initialize(Attributor &A) override { 12737 // TODO: we don't rewrite function argument for now because it will need to 12738 // rewrite the function signature and all call sites. 12739 (void)indicatePessimisticFixpoint(); 12740 } 12741 12742 void trackStatistics() const override { 12743 STATS_DECLTRACK_FNRET_ATTR(addrspace); 12744 } 12745 }; 12746 12747 struct AAAddressSpaceCallSiteReturned final : AAAddressSpaceImpl { 12748 AAAddressSpaceCallSiteReturned(const IRPosition &IRP, Attributor &A) 12749 : AAAddressSpaceImpl(IRP, A) {} 12750 12751 void trackStatistics() const override { 12752 STATS_DECLTRACK_CSRET_ATTR(addrspace); 12753 } 12754 }; 12755 12756 struct AAAddressSpaceArgument final : AAAddressSpaceImpl { 12757 AAAddressSpaceArgument(const IRPosition &IRP, Attributor &A) 12758 : AAAddressSpaceImpl(IRP, A) {} 12759 12760 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(addrspace); } 12761 }; 12762 12763 struct AAAddressSpaceCallSiteArgument final : AAAddressSpaceImpl { 12764 AAAddressSpaceCallSiteArgument(const IRPosition &IRP, Attributor &A) 12765 : AAAddressSpaceImpl(IRP, A) {} 12766 12767 /// See AbstractAttribute::initialize(...). 12768 void initialize(Attributor &A) override { 12769 // TODO: we don't rewrite call site argument for now because it will need to 12770 // rewrite the function signature of the callee. 12771 (void)indicatePessimisticFixpoint(); 12772 } 12773 12774 void trackStatistics() const override { 12775 STATS_DECLTRACK_CSARG_ATTR(addrspace); 12776 } 12777 }; 12778 } // namespace 12779 12780 /// ----------- Allocation Info ---------- 12781 namespace { 12782 struct AAAllocationInfoImpl : public AAAllocationInfo { 12783 AAAllocationInfoImpl(const IRPosition &IRP, Attributor &A) 12784 : AAAllocationInfo(IRP, A) {} 12785 12786 std::optional<TypeSize> getAllocatedSize() const override { 12787 assert(isValidState() && "the AA is invalid"); 12788 return AssumedAllocatedSize; 12789 } 12790 12791 std::optional<TypeSize> findInitialAllocationSize(Instruction *I, 12792 const DataLayout &DL) { 12793 12794 // TODO: implement case for malloc like instructions 12795 switch (I->getOpcode()) { 12796 case Instruction::Alloca: { 12797 AllocaInst *AI = cast<AllocaInst>(I); 12798 return AI->getAllocationSize(DL); 12799 } 12800 default: 12801 return std::nullopt; 12802 } 12803 } 12804 12805 ChangeStatus updateImpl(Attributor &A) override { 12806 12807 const IRPosition &IRP = getIRPosition(); 12808 Instruction *I = IRP.getCtxI(); 12809 12810 // TODO: update check for malloc like calls 12811 if (!isa<AllocaInst>(I)) 12812 return indicatePessimisticFixpoint(); 12813 12814 bool IsKnownNoCapture; 12815 if (!AA::hasAssumedIRAttr<Attribute::Captures>( 12816 A, this, IRP, DepClassTy::OPTIONAL, IsKnownNoCapture)) 12817 return indicatePessimisticFixpoint(); 12818 12819 const AAPointerInfo *PI = 12820 A.getOrCreateAAFor<AAPointerInfo>(IRP, *this, DepClassTy::REQUIRED); 12821 12822 if (!PI) 12823 return indicatePessimisticFixpoint(); 12824 12825 if (!PI->getState().isValidState() || PI->reachesReturn()) 12826 return indicatePessimisticFixpoint(); 12827 12828 const DataLayout &DL = A.getDataLayout(); 12829 const auto AllocationSize = findInitialAllocationSize(I, DL); 12830 12831 // If allocation size is nullopt, we give up. 12832 if (!AllocationSize) 12833 return indicatePessimisticFixpoint(); 12834 12835 // For zero sized allocations, we give up. 12836 // Since we can't reduce further 12837 if (*AllocationSize == 0) 12838 return indicatePessimisticFixpoint(); 12839 12840 int64_t BinSize = PI->numOffsetBins(); 12841 12842 // TODO: implement for multiple bins 12843 if (BinSize > 1) 12844 return indicatePessimisticFixpoint(); 12845 12846 if (BinSize == 0) { 12847 auto NewAllocationSize = std::optional<TypeSize>(TypeSize(0, false)); 12848 if (!changeAllocationSize(NewAllocationSize)) 12849 return ChangeStatus::UNCHANGED; 12850 return ChangeStatus::CHANGED; 12851 } 12852 12853 // TODO: refactor this to be part of multiple bin case 12854 const auto &It = PI->begin(); 12855 12856 // TODO: handle if Offset is not zero 12857 if (It->first.Offset != 0) 12858 return indicatePessimisticFixpoint(); 12859 12860 uint64_t SizeOfBin = It->first.Offset + It->first.Size; 12861 12862 if (SizeOfBin >= *AllocationSize) 12863 return indicatePessimisticFixpoint(); 12864 12865 auto NewAllocationSize = 12866 std::optional<TypeSize>(TypeSize(SizeOfBin * 8, false)); 12867 12868 if (!changeAllocationSize(NewAllocationSize)) 12869 return ChangeStatus::UNCHANGED; 12870 12871 return ChangeStatus::CHANGED; 12872 } 12873 12874 /// See AbstractAttribute::manifest(...). 12875 ChangeStatus manifest(Attributor &A) override { 12876 12877 assert(isValidState() && 12878 "Manifest should only be called if the state is valid."); 12879 12880 Instruction *I = getIRPosition().getCtxI(); 12881 12882 auto FixedAllocatedSizeInBits = getAllocatedSize()->getFixedValue(); 12883 12884 unsigned long NumBytesToAllocate = (FixedAllocatedSizeInBits + 7) / 8; 12885 12886 switch (I->getOpcode()) { 12887 // TODO: add case for malloc like calls 12888 case Instruction::Alloca: { 12889 12890 AllocaInst *AI = cast<AllocaInst>(I); 12891 12892 Type *CharType = Type::getInt8Ty(I->getContext()); 12893 12894 auto *NumBytesToValue = 12895 ConstantInt::get(I->getContext(), APInt(32, NumBytesToAllocate)); 12896 12897 BasicBlock::iterator insertPt = AI->getIterator(); 12898 insertPt = std::next(insertPt); 12899 AllocaInst *NewAllocaInst = 12900 new AllocaInst(CharType, AI->getAddressSpace(), NumBytesToValue, 12901 AI->getAlign(), AI->getName(), insertPt); 12902 12903 if (A.changeAfterManifest(IRPosition::inst(*AI), *NewAllocaInst)) 12904 return ChangeStatus::CHANGED; 12905 12906 break; 12907 } 12908 default: 12909 break; 12910 } 12911 12912 return ChangeStatus::UNCHANGED; 12913 } 12914 12915 /// See AbstractAttribute::getAsStr(). 12916 const std::string getAsStr(Attributor *A) const override { 12917 if (!isValidState()) 12918 return "allocationinfo(<invalid>)"; 12919 return "allocationinfo(" + 12920 (AssumedAllocatedSize == HasNoAllocationSize 12921 ? "none" 12922 : std::to_string(AssumedAllocatedSize->getFixedValue())) + 12923 ")"; 12924 } 12925 12926 private: 12927 std::optional<TypeSize> AssumedAllocatedSize = HasNoAllocationSize; 12928 12929 // Maintain the computed allocation size of the object. 12930 // Returns (bool) weather the size of the allocation was modified or not. 12931 bool changeAllocationSize(std::optional<TypeSize> Size) { 12932 if (AssumedAllocatedSize == HasNoAllocationSize || 12933 AssumedAllocatedSize != Size) { 12934 AssumedAllocatedSize = Size; 12935 return true; 12936 } 12937 return false; 12938 } 12939 }; 12940 12941 struct AAAllocationInfoFloating : AAAllocationInfoImpl { 12942 AAAllocationInfoFloating(const IRPosition &IRP, Attributor &A) 12943 : AAAllocationInfoImpl(IRP, A) {} 12944 12945 void trackStatistics() const override { 12946 STATS_DECLTRACK_FLOATING_ATTR(allocationinfo); 12947 } 12948 }; 12949 12950 struct AAAllocationInfoReturned : AAAllocationInfoImpl { 12951 AAAllocationInfoReturned(const IRPosition &IRP, Attributor &A) 12952 : AAAllocationInfoImpl(IRP, A) {} 12953 12954 /// See AbstractAttribute::initialize(...). 12955 void initialize(Attributor &A) override { 12956 // TODO: we don't rewrite function argument for now because it will need to 12957 // rewrite the function signature and all call sites 12958 (void)indicatePessimisticFixpoint(); 12959 } 12960 12961 void trackStatistics() const override { 12962 STATS_DECLTRACK_FNRET_ATTR(allocationinfo); 12963 } 12964 }; 12965 12966 struct AAAllocationInfoCallSiteReturned : AAAllocationInfoImpl { 12967 AAAllocationInfoCallSiteReturned(const IRPosition &IRP, Attributor &A) 12968 : AAAllocationInfoImpl(IRP, A) {} 12969 12970 void trackStatistics() const override { 12971 STATS_DECLTRACK_CSRET_ATTR(allocationinfo); 12972 } 12973 }; 12974 12975 struct AAAllocationInfoArgument : AAAllocationInfoImpl { 12976 AAAllocationInfoArgument(const IRPosition &IRP, Attributor &A) 12977 : AAAllocationInfoImpl(IRP, A) {} 12978 12979 void trackStatistics() const override { 12980 STATS_DECLTRACK_ARG_ATTR(allocationinfo); 12981 } 12982 }; 12983 12984 struct AAAllocationInfoCallSiteArgument : AAAllocationInfoImpl { 12985 AAAllocationInfoCallSiteArgument(const IRPosition &IRP, Attributor &A) 12986 : AAAllocationInfoImpl(IRP, A) {} 12987 12988 /// See AbstractAttribute::initialize(...). 12989 void initialize(Attributor &A) override { 12990 12991 (void)indicatePessimisticFixpoint(); 12992 } 12993 12994 void trackStatistics() const override { 12995 STATS_DECLTRACK_CSARG_ATTR(allocationinfo); 12996 } 12997 }; 12998 } // namespace 12999 13000 const char AANoUnwind::ID = 0; 13001 const char AANoSync::ID = 0; 13002 const char AANoFree::ID = 0; 13003 const char AANonNull::ID = 0; 13004 const char AAMustProgress::ID = 0; 13005 const char AANoRecurse::ID = 0; 13006 const char AANonConvergent::ID = 0; 13007 const char AAWillReturn::ID = 0; 13008 const char AAUndefinedBehavior::ID = 0; 13009 const char AANoAlias::ID = 0; 13010 const char AAIntraFnReachability::ID = 0; 13011 const char AANoReturn::ID = 0; 13012 const char AAIsDead::ID = 0; 13013 const char AADereferenceable::ID = 0; 13014 const char AAAlign::ID = 0; 13015 const char AAInstanceInfo::ID = 0; 13016 const char AANoCapture::ID = 0; 13017 const char AAValueSimplify::ID = 0; 13018 const char AAHeapToStack::ID = 0; 13019 const char AAPrivatizablePtr::ID = 0; 13020 const char AAMemoryBehavior::ID = 0; 13021 const char AAMemoryLocation::ID = 0; 13022 const char AAValueConstantRange::ID = 0; 13023 const char AAPotentialConstantValues::ID = 0; 13024 const char AAPotentialValues::ID = 0; 13025 const char AANoUndef::ID = 0; 13026 const char AANoFPClass::ID = 0; 13027 const char AACallEdges::ID = 0; 13028 const char AAInterFnReachability::ID = 0; 13029 const char AAPointerInfo::ID = 0; 13030 const char AAAssumptionInfo::ID = 0; 13031 const char AAUnderlyingObjects::ID = 0; 13032 const char AAAddressSpace::ID = 0; 13033 const char AAAllocationInfo::ID = 0; 13034 const char AAIndirectCallInfo::ID = 0; 13035 const char AAGlobalValueInfo::ID = 0; 13036 const char AADenormalFPMath::ID = 0; 13037 13038 // Macro magic to create the static generator function for attributes that 13039 // follow the naming scheme. 13040 13041 #define SWITCH_PK_INV(CLASS, PK, POS_NAME) \ 13042 case IRPosition::PK: \ 13043 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!"); 13044 13045 #define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \ 13046 case IRPosition::PK: \ 13047 AA = new (A.Allocator) CLASS##SUFFIX(IRP, A); \ 13048 ++NumAAs; \ 13049 break; 13050 13051 #define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \ 13052 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 13053 CLASS *AA = nullptr; \ 13054 switch (IRP.getPositionKind()) { \ 13055 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \ 13056 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \ 13057 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \ 13058 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \ 13059 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \ 13060 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \ 13061 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \ 13062 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \ 13063 } \ 13064 return *AA; \ 13065 } 13066 13067 #define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \ 13068 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 13069 CLASS *AA = nullptr; \ 13070 switch (IRP.getPositionKind()) { \ 13071 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \ 13072 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \ 13073 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \ 13074 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \ 13075 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \ 13076 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \ 13077 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \ 13078 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \ 13079 } \ 13080 return *AA; \ 13081 } 13082 13083 #define CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(POS, SUFFIX, CLASS) \ 13084 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 13085 CLASS *AA = nullptr; \ 13086 switch (IRP.getPositionKind()) { \ 13087 SWITCH_PK_CREATE(CLASS, IRP, POS, SUFFIX) \ 13088 default: \ 13089 llvm_unreachable("Cannot create " #CLASS " for position otherthan " #POS \ 13090 " position!"); \ 13091 } \ 13092 return *AA; \ 13093 } 13094 13095 #define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \ 13096 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 13097 CLASS *AA = nullptr; \ 13098 switch (IRP.getPositionKind()) { \ 13099 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \ 13100 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \ 13101 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \ 13102 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \ 13103 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \ 13104 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \ 13105 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \ 13106 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \ 13107 } \ 13108 return *AA; \ 13109 } 13110 13111 #define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \ 13112 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 13113 CLASS *AA = nullptr; \ 13114 switch (IRP.getPositionKind()) { \ 13115 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \ 13116 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \ 13117 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \ 13118 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \ 13119 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \ 13120 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \ 13121 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \ 13122 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \ 13123 } \ 13124 return *AA; \ 13125 } 13126 13127 #define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \ 13128 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \ 13129 CLASS *AA = nullptr; \ 13130 switch (IRP.getPositionKind()) { \ 13131 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \ 13132 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \ 13133 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \ 13134 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \ 13135 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \ 13136 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \ 13137 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \ 13138 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \ 13139 } \ 13140 return *AA; \ 13141 } 13142 13143 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUnwind) 13144 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoSync) 13145 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoRecurse) 13146 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAWillReturn) 13147 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoReturn) 13148 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryLocation) 13149 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AACallEdges) 13150 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAssumptionInfo) 13151 CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMustProgress) 13152 13153 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonNull) 13154 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoAlias) 13155 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPrivatizablePtr) 13156 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADereferenceable) 13157 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAlign) 13158 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAInstanceInfo) 13159 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoCapture) 13160 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueConstantRange) 13161 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPotentialConstantValues) 13162 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPotentialValues) 13163 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUndef) 13164 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFPClass) 13165 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPointerInfo) 13166 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAddressSpace) 13167 CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAllocationInfo) 13168 13169 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify) 13170 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIsDead) 13171 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree) 13172 CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAUnderlyingObjects) 13173 13174 CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(IRP_CALL_SITE, CallSite, 13175 AAIndirectCallInfo) 13176 CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION(IRP_FLOAT, Floating, 13177 AAGlobalValueInfo) 13178 13179 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAHeapToStack) 13180 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAUndefinedBehavior) 13181 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonConvergent) 13182 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIntraFnReachability) 13183 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAInterFnReachability) 13184 CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADenormalFPMath) 13185 13186 CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryBehavior) 13187 13188 #undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION 13189 #undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION 13190 #undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION 13191 #undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION 13192 #undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION 13193 #undef CREATE_ABSTRACT_ATTRIBUTE_FOR_ONE_POSITION 13194 #undef SWITCH_PK_CREATE 13195 #undef SWITCH_PK_INV 13196