1 //===- ARCInstKind.cpp - ObjC ARC Optimization ----------------------------===// 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 /// \file 9 /// This file defines several utility functions used by various ARC 10 /// optimizations which are IMHO too big to be in a header file. 11 /// 12 /// WARNING: This file knows about certain library functions. It recognizes them 13 /// by name, and hardwires knowledge of their semantics. 14 /// 15 /// WARNING: This file knows about how certain Objective-C library functions are 16 /// used. Naive LLVM IR transformations which would otherwise be 17 /// behavior-preserving may break these assumptions. 18 /// 19 //===----------------------------------------------------------------------===// 20 21 #include "llvm/Analysis/ObjCARCInstKind.h" 22 #include "llvm/Analysis/ObjCARCAnalysisUtils.h" 23 #include "llvm/IR/Intrinsics.h" 24 25 using namespace llvm; 26 using namespace llvm::objcarc; 27 28 raw_ostream &llvm::objcarc::operator<<(raw_ostream &OS, 29 const ARCInstKind Class) { 30 switch (Class) { 31 case ARCInstKind::Retain: 32 return OS << "ARCInstKind::Retain"; 33 case ARCInstKind::RetainRV: 34 return OS << "ARCInstKind::RetainRV"; 35 case ARCInstKind::UnsafeClaimRV: 36 return OS << "ARCInstKind::UnsafeClaimRV"; 37 case ARCInstKind::RetainBlock: 38 return OS << "ARCInstKind::RetainBlock"; 39 case ARCInstKind::Release: 40 return OS << "ARCInstKind::Release"; 41 case ARCInstKind::Autorelease: 42 return OS << "ARCInstKind::Autorelease"; 43 case ARCInstKind::AutoreleaseRV: 44 return OS << "ARCInstKind::AutoreleaseRV"; 45 case ARCInstKind::AutoreleasepoolPush: 46 return OS << "ARCInstKind::AutoreleasepoolPush"; 47 case ARCInstKind::AutoreleasepoolPop: 48 return OS << "ARCInstKind::AutoreleasepoolPop"; 49 case ARCInstKind::NoopCast: 50 return OS << "ARCInstKind::NoopCast"; 51 case ARCInstKind::FusedRetainAutorelease: 52 return OS << "ARCInstKind::FusedRetainAutorelease"; 53 case ARCInstKind::FusedRetainAutoreleaseRV: 54 return OS << "ARCInstKind::FusedRetainAutoreleaseRV"; 55 case ARCInstKind::LoadWeakRetained: 56 return OS << "ARCInstKind::LoadWeakRetained"; 57 case ARCInstKind::StoreWeak: 58 return OS << "ARCInstKind::StoreWeak"; 59 case ARCInstKind::InitWeak: 60 return OS << "ARCInstKind::InitWeak"; 61 case ARCInstKind::LoadWeak: 62 return OS << "ARCInstKind::LoadWeak"; 63 case ARCInstKind::MoveWeak: 64 return OS << "ARCInstKind::MoveWeak"; 65 case ARCInstKind::CopyWeak: 66 return OS << "ARCInstKind::CopyWeak"; 67 case ARCInstKind::DestroyWeak: 68 return OS << "ARCInstKind::DestroyWeak"; 69 case ARCInstKind::StoreStrong: 70 return OS << "ARCInstKind::StoreStrong"; 71 case ARCInstKind::CallOrUser: 72 return OS << "ARCInstKind::CallOrUser"; 73 case ARCInstKind::Call: 74 return OS << "ARCInstKind::Call"; 75 case ARCInstKind::User: 76 return OS << "ARCInstKind::User"; 77 case ARCInstKind::IntrinsicUser: 78 return OS << "ARCInstKind::IntrinsicUser"; 79 case ARCInstKind::None: 80 return OS << "ARCInstKind::None"; 81 } 82 llvm_unreachable("Unknown instruction class!"); 83 } 84 85 ARCInstKind llvm::objcarc::GetFunctionClass(const Function *F) { 86 87 Intrinsic::ID ID = F->getIntrinsicID(); 88 switch (ID) { 89 default: 90 return ARCInstKind::CallOrUser; 91 case Intrinsic::objc_autorelease: 92 return ARCInstKind::Autorelease; 93 case Intrinsic::objc_autoreleasePoolPop: 94 return ARCInstKind::AutoreleasepoolPop; 95 case Intrinsic::objc_autoreleasePoolPush: 96 return ARCInstKind::AutoreleasepoolPush; 97 case Intrinsic::objc_autoreleaseReturnValue: 98 return ARCInstKind::AutoreleaseRV; 99 case Intrinsic::objc_copyWeak: 100 return ARCInstKind::CopyWeak; 101 case Intrinsic::objc_destroyWeak: 102 return ARCInstKind::DestroyWeak; 103 case Intrinsic::objc_initWeak: 104 return ARCInstKind::InitWeak; 105 case Intrinsic::objc_loadWeak: 106 return ARCInstKind::LoadWeak; 107 case Intrinsic::objc_loadWeakRetained: 108 return ARCInstKind::LoadWeakRetained; 109 case Intrinsic::objc_moveWeak: 110 return ARCInstKind::MoveWeak; 111 case Intrinsic::objc_release: 112 return ARCInstKind::Release; 113 case Intrinsic::objc_retain: 114 return ARCInstKind::Retain; 115 case Intrinsic::objc_retainAutorelease: 116 return ARCInstKind::FusedRetainAutorelease; 117 case Intrinsic::objc_retainAutoreleaseReturnValue: 118 return ARCInstKind::FusedRetainAutoreleaseRV; 119 case Intrinsic::objc_retainAutoreleasedReturnValue: 120 return ARCInstKind::RetainRV; 121 case Intrinsic::objc_retainBlock: 122 return ARCInstKind::RetainBlock; 123 case Intrinsic::objc_storeStrong: 124 return ARCInstKind::StoreStrong; 125 case Intrinsic::objc_storeWeak: 126 return ARCInstKind::StoreWeak; 127 case Intrinsic::objc_clang_arc_use: 128 return ARCInstKind::IntrinsicUser; 129 case Intrinsic::objc_unsafeClaimAutoreleasedReturnValue: 130 return ARCInstKind::UnsafeClaimRV; 131 case Intrinsic::objc_retainedObject: 132 return ARCInstKind::NoopCast; 133 case Intrinsic::objc_unretainedObject: 134 return ARCInstKind::NoopCast; 135 case Intrinsic::objc_unretainedPointer: 136 return ARCInstKind::NoopCast; 137 case Intrinsic::objc_retain_autorelease: 138 return ARCInstKind::FusedRetainAutorelease; 139 case Intrinsic::objc_sync_enter: 140 return ARCInstKind::User; 141 case Intrinsic::objc_sync_exit: 142 return ARCInstKind::User; 143 case Intrinsic::objc_clang_arc_noop_use: 144 case Intrinsic::objc_arc_annotation_topdown_bbstart: 145 case Intrinsic::objc_arc_annotation_topdown_bbend: 146 case Intrinsic::objc_arc_annotation_bottomup_bbstart: 147 case Intrinsic::objc_arc_annotation_bottomup_bbend: 148 // Ignore annotation calls. This is important to stop the 149 // optimizer from treating annotations as uses which would 150 // make the state of the pointers they are attempting to 151 // elucidate to be incorrect. 152 return ARCInstKind::None; 153 } 154 } 155 156 // A list of intrinsics that we know do not use objc pointers or decrement 157 // ref counts. 158 static bool isInertIntrinsic(unsigned ID) { 159 // TODO: Make this into a covered switch. 160 switch (ID) { 161 case Intrinsic::returnaddress: 162 case Intrinsic::addressofreturnaddress: 163 case Intrinsic::frameaddress: 164 case Intrinsic::stacksave: 165 case Intrinsic::stackrestore: 166 case Intrinsic::vastart: 167 case Intrinsic::vacopy: 168 case Intrinsic::vaend: 169 case Intrinsic::objectsize: 170 case Intrinsic::prefetch: 171 case Intrinsic::stackprotector: 172 case Intrinsic::eh_return_i32: 173 case Intrinsic::eh_return_i64: 174 case Intrinsic::eh_typeid_for: 175 case Intrinsic::eh_dwarf_cfa: 176 case Intrinsic::eh_sjlj_lsda: 177 case Intrinsic::eh_sjlj_functioncontext: 178 case Intrinsic::init_trampoline: 179 case Intrinsic::adjust_trampoline: 180 case Intrinsic::lifetime_start: 181 case Intrinsic::lifetime_end: 182 case Intrinsic::invariant_start: 183 case Intrinsic::invariant_end: 184 // Don't let dbg info affect our results. 185 case Intrinsic::dbg_declare: 186 case Intrinsic::dbg_value: 187 case Intrinsic::dbg_label: 188 // Short cut: Some intrinsics obviously don't use ObjC pointers. 189 return true; 190 default: 191 return false; 192 } 193 } 194 195 // A list of intrinsics that we know do not use objc pointers or decrement 196 // ref counts. 197 static bool isUseOnlyIntrinsic(unsigned ID) { 198 // We are conservative and even though intrinsics are unlikely to touch 199 // reference counts, we white list them for safety. 200 // 201 // TODO: Expand this into a covered switch. There is a lot more here. 202 switch (ID) { 203 case Intrinsic::memcpy: 204 case Intrinsic::memmove: 205 case Intrinsic::memset: 206 return true; 207 default: 208 return false; 209 } 210 } 211 212 /// Determine what kind of construct V is. 213 ARCInstKind llvm::objcarc::GetARCInstKind(const Value *V) { 214 if (const Instruction *I = dyn_cast<Instruction>(V)) { 215 // Any instruction other than bitcast and gep with a pointer operand have a 216 // use of an objc pointer. Bitcasts, GEPs, Selects, PHIs transfer a pointer 217 // to a subsequent use, rather than using it themselves, in this sense. 218 // As a short cut, several other opcodes are known to have no pointer 219 // operands of interest. And ret is never followed by a release, so it's 220 // not interesting to examine. 221 switch (I->getOpcode()) { 222 case Instruction::Call: { 223 const CallInst *CI = cast<CallInst>(I); 224 // See if we have a function that we know something about. 225 if (const Function *F = CI->getCalledFunction()) { 226 ARCInstKind Class = GetFunctionClass(F); 227 if (Class != ARCInstKind::CallOrUser) 228 return Class; 229 Intrinsic::ID ID = F->getIntrinsicID(); 230 if (isInertIntrinsic(ID)) 231 return ARCInstKind::None; 232 if (isUseOnlyIntrinsic(ID)) 233 return ARCInstKind::User; 234 } 235 236 // Otherwise, be conservative. 237 return GetCallSiteClass(*CI); 238 } 239 case Instruction::Invoke: 240 // Otherwise, be conservative. 241 return GetCallSiteClass(cast<InvokeInst>(*I)); 242 case Instruction::BitCast: 243 case Instruction::GetElementPtr: 244 case Instruction::Select: 245 case Instruction::PHI: 246 case Instruction::Ret: 247 case Instruction::Br: 248 case Instruction::Switch: 249 case Instruction::IndirectBr: 250 case Instruction::Alloca: 251 case Instruction::VAArg: 252 case Instruction::Add: 253 case Instruction::FAdd: 254 case Instruction::Sub: 255 case Instruction::FSub: 256 case Instruction::Mul: 257 case Instruction::FMul: 258 case Instruction::SDiv: 259 case Instruction::UDiv: 260 case Instruction::FDiv: 261 case Instruction::SRem: 262 case Instruction::URem: 263 case Instruction::FRem: 264 case Instruction::Shl: 265 case Instruction::LShr: 266 case Instruction::AShr: 267 case Instruction::And: 268 case Instruction::Or: 269 case Instruction::Xor: 270 case Instruction::SExt: 271 case Instruction::ZExt: 272 case Instruction::Trunc: 273 case Instruction::IntToPtr: 274 case Instruction::FCmp: 275 case Instruction::FPTrunc: 276 case Instruction::FPExt: 277 case Instruction::FPToUI: 278 case Instruction::FPToSI: 279 case Instruction::UIToFP: 280 case Instruction::SIToFP: 281 case Instruction::InsertElement: 282 case Instruction::ExtractElement: 283 case Instruction::ShuffleVector: 284 case Instruction::ExtractValue: 285 break; 286 case Instruction::ICmp: 287 // Comparing a pointer with null, or any other constant, isn't an 288 // interesting use, because we don't care what the pointer points to, or 289 // about the values of any other dynamic reference-counted pointers. 290 if (IsPotentialRetainableObjPtr(I->getOperand(1))) 291 return ARCInstKind::User; 292 break; 293 default: 294 // For anything else, check all the operands. 295 // Note that this includes both operands of a Store: while the first 296 // operand isn't actually being dereferenced, it is being stored to 297 // memory where we can no longer track who might read it and dereference 298 // it, so we have to consider it potentially used. 299 for (const Use &U : I->operands()) 300 if (IsPotentialRetainableObjPtr(U)) 301 return ARCInstKind::User; 302 } 303 } 304 305 // Otherwise, it's totally inert for ARC purposes. 306 return ARCInstKind::None; 307 } 308 309 /// Test if the given class is a kind of user. 310 bool llvm::objcarc::IsUser(ARCInstKind Class) { 311 switch (Class) { 312 case ARCInstKind::User: 313 case ARCInstKind::CallOrUser: 314 case ARCInstKind::IntrinsicUser: 315 return true; 316 case ARCInstKind::Retain: 317 case ARCInstKind::RetainRV: 318 case ARCInstKind::RetainBlock: 319 case ARCInstKind::Release: 320 case ARCInstKind::Autorelease: 321 case ARCInstKind::AutoreleaseRV: 322 case ARCInstKind::AutoreleasepoolPush: 323 case ARCInstKind::AutoreleasepoolPop: 324 case ARCInstKind::NoopCast: 325 case ARCInstKind::FusedRetainAutorelease: 326 case ARCInstKind::FusedRetainAutoreleaseRV: 327 case ARCInstKind::LoadWeakRetained: 328 case ARCInstKind::StoreWeak: 329 case ARCInstKind::InitWeak: 330 case ARCInstKind::LoadWeak: 331 case ARCInstKind::MoveWeak: 332 case ARCInstKind::CopyWeak: 333 case ARCInstKind::DestroyWeak: 334 case ARCInstKind::StoreStrong: 335 case ARCInstKind::Call: 336 case ARCInstKind::None: 337 case ARCInstKind::UnsafeClaimRV: 338 return false; 339 } 340 llvm_unreachable("covered switch isn't covered?"); 341 } 342 343 /// Test if the given class is objc_retain or equivalent. 344 bool llvm::objcarc::IsRetain(ARCInstKind Class) { 345 switch (Class) { 346 case ARCInstKind::Retain: 347 case ARCInstKind::RetainRV: 348 return true; 349 // I believe we treat retain block as not a retain since it can copy its 350 // block. 351 case ARCInstKind::RetainBlock: 352 case ARCInstKind::Release: 353 case ARCInstKind::Autorelease: 354 case ARCInstKind::AutoreleaseRV: 355 case ARCInstKind::AutoreleasepoolPush: 356 case ARCInstKind::AutoreleasepoolPop: 357 case ARCInstKind::NoopCast: 358 case ARCInstKind::FusedRetainAutorelease: 359 case ARCInstKind::FusedRetainAutoreleaseRV: 360 case ARCInstKind::LoadWeakRetained: 361 case ARCInstKind::StoreWeak: 362 case ARCInstKind::InitWeak: 363 case ARCInstKind::LoadWeak: 364 case ARCInstKind::MoveWeak: 365 case ARCInstKind::CopyWeak: 366 case ARCInstKind::DestroyWeak: 367 case ARCInstKind::StoreStrong: 368 case ARCInstKind::IntrinsicUser: 369 case ARCInstKind::CallOrUser: 370 case ARCInstKind::Call: 371 case ARCInstKind::User: 372 case ARCInstKind::None: 373 case ARCInstKind::UnsafeClaimRV: 374 return false; 375 } 376 llvm_unreachable("covered switch isn't covered?"); 377 } 378 379 /// Test if the given class is objc_autorelease or equivalent. 380 bool llvm::objcarc::IsAutorelease(ARCInstKind Class) { 381 switch (Class) { 382 case ARCInstKind::Autorelease: 383 case ARCInstKind::AutoreleaseRV: 384 return true; 385 case ARCInstKind::Retain: 386 case ARCInstKind::RetainRV: 387 case ARCInstKind::UnsafeClaimRV: 388 case ARCInstKind::RetainBlock: 389 case ARCInstKind::Release: 390 case ARCInstKind::AutoreleasepoolPush: 391 case ARCInstKind::AutoreleasepoolPop: 392 case ARCInstKind::NoopCast: 393 case ARCInstKind::FusedRetainAutorelease: 394 case ARCInstKind::FusedRetainAutoreleaseRV: 395 case ARCInstKind::LoadWeakRetained: 396 case ARCInstKind::StoreWeak: 397 case ARCInstKind::InitWeak: 398 case ARCInstKind::LoadWeak: 399 case ARCInstKind::MoveWeak: 400 case ARCInstKind::CopyWeak: 401 case ARCInstKind::DestroyWeak: 402 case ARCInstKind::StoreStrong: 403 case ARCInstKind::IntrinsicUser: 404 case ARCInstKind::CallOrUser: 405 case ARCInstKind::Call: 406 case ARCInstKind::User: 407 case ARCInstKind::None: 408 return false; 409 } 410 llvm_unreachable("covered switch isn't covered?"); 411 } 412 413 /// Test if the given class represents instructions which return their 414 /// argument verbatim. 415 bool llvm::objcarc::IsForwarding(ARCInstKind Class) { 416 switch (Class) { 417 case ARCInstKind::Retain: 418 case ARCInstKind::RetainRV: 419 case ARCInstKind::UnsafeClaimRV: 420 case ARCInstKind::Autorelease: 421 case ARCInstKind::AutoreleaseRV: 422 case ARCInstKind::NoopCast: 423 return true; 424 case ARCInstKind::RetainBlock: 425 case ARCInstKind::Release: 426 case ARCInstKind::AutoreleasepoolPush: 427 case ARCInstKind::AutoreleasepoolPop: 428 case ARCInstKind::FusedRetainAutorelease: 429 case ARCInstKind::FusedRetainAutoreleaseRV: 430 case ARCInstKind::LoadWeakRetained: 431 case ARCInstKind::StoreWeak: 432 case ARCInstKind::InitWeak: 433 case ARCInstKind::LoadWeak: 434 case ARCInstKind::MoveWeak: 435 case ARCInstKind::CopyWeak: 436 case ARCInstKind::DestroyWeak: 437 case ARCInstKind::StoreStrong: 438 case ARCInstKind::IntrinsicUser: 439 case ARCInstKind::CallOrUser: 440 case ARCInstKind::Call: 441 case ARCInstKind::User: 442 case ARCInstKind::None: 443 return false; 444 } 445 llvm_unreachable("covered switch isn't covered?"); 446 } 447 448 /// Test if the given class represents instructions which do nothing if 449 /// passed a null pointer. 450 bool llvm::objcarc::IsNoopOnNull(ARCInstKind Class) { 451 switch (Class) { 452 case ARCInstKind::Retain: 453 case ARCInstKind::RetainRV: 454 case ARCInstKind::UnsafeClaimRV: 455 case ARCInstKind::Release: 456 case ARCInstKind::Autorelease: 457 case ARCInstKind::AutoreleaseRV: 458 case ARCInstKind::RetainBlock: 459 return true; 460 case ARCInstKind::AutoreleasepoolPush: 461 case ARCInstKind::AutoreleasepoolPop: 462 case ARCInstKind::FusedRetainAutorelease: 463 case ARCInstKind::FusedRetainAutoreleaseRV: 464 case ARCInstKind::LoadWeakRetained: 465 case ARCInstKind::StoreWeak: 466 case ARCInstKind::InitWeak: 467 case ARCInstKind::LoadWeak: 468 case ARCInstKind::MoveWeak: 469 case ARCInstKind::CopyWeak: 470 case ARCInstKind::DestroyWeak: 471 case ARCInstKind::StoreStrong: 472 case ARCInstKind::IntrinsicUser: 473 case ARCInstKind::CallOrUser: 474 case ARCInstKind::Call: 475 case ARCInstKind::User: 476 case ARCInstKind::None: 477 case ARCInstKind::NoopCast: 478 return false; 479 } 480 llvm_unreachable("covered switch isn't covered?"); 481 } 482 483 /// Test if the given class represents instructions which do nothing if 484 /// passed a global variable. 485 bool llvm::objcarc::IsNoopOnGlobal(ARCInstKind Class) { 486 switch (Class) { 487 case ARCInstKind::Retain: 488 case ARCInstKind::RetainRV: 489 case ARCInstKind::UnsafeClaimRV: 490 case ARCInstKind::Release: 491 case ARCInstKind::Autorelease: 492 case ARCInstKind::AutoreleaseRV: 493 case ARCInstKind::RetainBlock: 494 case ARCInstKind::FusedRetainAutorelease: 495 case ARCInstKind::FusedRetainAutoreleaseRV: 496 return true; 497 case ARCInstKind::AutoreleasepoolPush: 498 case ARCInstKind::AutoreleasepoolPop: 499 case ARCInstKind::LoadWeakRetained: 500 case ARCInstKind::StoreWeak: 501 case ARCInstKind::InitWeak: 502 case ARCInstKind::LoadWeak: 503 case ARCInstKind::MoveWeak: 504 case ARCInstKind::CopyWeak: 505 case ARCInstKind::DestroyWeak: 506 case ARCInstKind::StoreStrong: 507 case ARCInstKind::IntrinsicUser: 508 case ARCInstKind::CallOrUser: 509 case ARCInstKind::Call: 510 case ARCInstKind::User: 511 case ARCInstKind::None: 512 case ARCInstKind::NoopCast: 513 return false; 514 } 515 llvm_unreachable("covered switch isn't covered?"); 516 } 517 518 /// Test if the given class represents instructions which are always safe 519 /// to mark with the "tail" keyword. 520 bool llvm::objcarc::IsAlwaysTail(ARCInstKind Class) { 521 // ARCInstKind::RetainBlock may be given a stack argument. 522 switch (Class) { 523 case ARCInstKind::Retain: 524 case ARCInstKind::RetainRV: 525 case ARCInstKind::UnsafeClaimRV: 526 case ARCInstKind::AutoreleaseRV: 527 return true; 528 case ARCInstKind::Release: 529 case ARCInstKind::Autorelease: 530 case ARCInstKind::RetainBlock: 531 case ARCInstKind::AutoreleasepoolPush: 532 case ARCInstKind::AutoreleasepoolPop: 533 case ARCInstKind::FusedRetainAutorelease: 534 case ARCInstKind::FusedRetainAutoreleaseRV: 535 case ARCInstKind::LoadWeakRetained: 536 case ARCInstKind::StoreWeak: 537 case ARCInstKind::InitWeak: 538 case ARCInstKind::LoadWeak: 539 case ARCInstKind::MoveWeak: 540 case ARCInstKind::CopyWeak: 541 case ARCInstKind::DestroyWeak: 542 case ARCInstKind::StoreStrong: 543 case ARCInstKind::IntrinsicUser: 544 case ARCInstKind::CallOrUser: 545 case ARCInstKind::Call: 546 case ARCInstKind::User: 547 case ARCInstKind::None: 548 case ARCInstKind::NoopCast: 549 return false; 550 } 551 llvm_unreachable("covered switch isn't covered?"); 552 } 553 554 /// Test if the given class represents instructions which are never safe 555 /// to mark with the "tail" keyword. 556 bool llvm::objcarc::IsNeverTail(ARCInstKind Class) { 557 /// It is never safe to tail call objc_autorelease since by tail calling 558 /// objc_autorelease: fast autoreleasing causing our object to be potentially 559 /// reclaimed from the autorelease pool which violates the semantics of 560 /// __autoreleasing types in ARC. 561 switch (Class) { 562 case ARCInstKind::Autorelease: 563 return true; 564 case ARCInstKind::Retain: 565 case ARCInstKind::RetainRV: 566 case ARCInstKind::UnsafeClaimRV: 567 case ARCInstKind::AutoreleaseRV: 568 case ARCInstKind::Release: 569 case ARCInstKind::RetainBlock: 570 case ARCInstKind::AutoreleasepoolPush: 571 case ARCInstKind::AutoreleasepoolPop: 572 case ARCInstKind::FusedRetainAutorelease: 573 case ARCInstKind::FusedRetainAutoreleaseRV: 574 case ARCInstKind::LoadWeakRetained: 575 case ARCInstKind::StoreWeak: 576 case ARCInstKind::InitWeak: 577 case ARCInstKind::LoadWeak: 578 case ARCInstKind::MoveWeak: 579 case ARCInstKind::CopyWeak: 580 case ARCInstKind::DestroyWeak: 581 case ARCInstKind::StoreStrong: 582 case ARCInstKind::IntrinsicUser: 583 case ARCInstKind::CallOrUser: 584 case ARCInstKind::Call: 585 case ARCInstKind::User: 586 case ARCInstKind::None: 587 case ARCInstKind::NoopCast: 588 return false; 589 } 590 llvm_unreachable("covered switch isn't covered?"); 591 } 592 593 /// Test if the given class represents instructions which are always safe 594 /// to mark with the nounwind attribute. 595 bool llvm::objcarc::IsNoThrow(ARCInstKind Class) { 596 // objc_retainBlock is not nounwind because it calls user copy constructors 597 // which could theoretically throw. 598 switch (Class) { 599 case ARCInstKind::Retain: 600 case ARCInstKind::RetainRV: 601 case ARCInstKind::UnsafeClaimRV: 602 case ARCInstKind::Release: 603 case ARCInstKind::Autorelease: 604 case ARCInstKind::AutoreleaseRV: 605 case ARCInstKind::AutoreleasepoolPush: 606 case ARCInstKind::AutoreleasepoolPop: 607 return true; 608 case ARCInstKind::RetainBlock: 609 case ARCInstKind::FusedRetainAutorelease: 610 case ARCInstKind::FusedRetainAutoreleaseRV: 611 case ARCInstKind::LoadWeakRetained: 612 case ARCInstKind::StoreWeak: 613 case ARCInstKind::InitWeak: 614 case ARCInstKind::LoadWeak: 615 case ARCInstKind::MoveWeak: 616 case ARCInstKind::CopyWeak: 617 case ARCInstKind::DestroyWeak: 618 case ARCInstKind::StoreStrong: 619 case ARCInstKind::IntrinsicUser: 620 case ARCInstKind::CallOrUser: 621 case ARCInstKind::Call: 622 case ARCInstKind::User: 623 case ARCInstKind::None: 624 case ARCInstKind::NoopCast: 625 return false; 626 } 627 llvm_unreachable("covered switch isn't covered?"); 628 } 629 630 /// Test whether the given instruction can autorelease any pointer or cause an 631 /// autoreleasepool pop. 632 /// 633 /// This means that it *could* interrupt the RV optimization. 634 bool llvm::objcarc::CanInterruptRV(ARCInstKind Class) { 635 switch (Class) { 636 case ARCInstKind::AutoreleasepoolPop: 637 case ARCInstKind::CallOrUser: 638 case ARCInstKind::Call: 639 case ARCInstKind::Autorelease: 640 case ARCInstKind::AutoreleaseRV: 641 case ARCInstKind::FusedRetainAutorelease: 642 case ARCInstKind::FusedRetainAutoreleaseRV: 643 return true; 644 case ARCInstKind::Retain: 645 case ARCInstKind::RetainRV: 646 case ARCInstKind::UnsafeClaimRV: 647 case ARCInstKind::Release: 648 case ARCInstKind::AutoreleasepoolPush: 649 case ARCInstKind::RetainBlock: 650 case ARCInstKind::LoadWeakRetained: 651 case ARCInstKind::StoreWeak: 652 case ARCInstKind::InitWeak: 653 case ARCInstKind::LoadWeak: 654 case ARCInstKind::MoveWeak: 655 case ARCInstKind::CopyWeak: 656 case ARCInstKind::DestroyWeak: 657 case ARCInstKind::StoreStrong: 658 case ARCInstKind::IntrinsicUser: 659 case ARCInstKind::User: 660 case ARCInstKind::None: 661 case ARCInstKind::NoopCast: 662 return false; 663 } 664 llvm_unreachable("covered switch isn't covered?"); 665 } 666 667 bool llvm::objcarc::CanDecrementRefCount(ARCInstKind Kind) { 668 switch (Kind) { 669 case ARCInstKind::Retain: 670 case ARCInstKind::RetainRV: 671 case ARCInstKind::Autorelease: 672 case ARCInstKind::AutoreleaseRV: 673 case ARCInstKind::NoopCast: 674 case ARCInstKind::FusedRetainAutorelease: 675 case ARCInstKind::FusedRetainAutoreleaseRV: 676 case ARCInstKind::IntrinsicUser: 677 case ARCInstKind::User: 678 case ARCInstKind::None: 679 return false; 680 681 // The cases below are conservative. 682 683 // RetainBlock can result in user defined copy constructors being called 684 // implying releases may occur. 685 case ARCInstKind::RetainBlock: 686 case ARCInstKind::Release: 687 case ARCInstKind::AutoreleasepoolPush: 688 case ARCInstKind::AutoreleasepoolPop: 689 case ARCInstKind::LoadWeakRetained: 690 case ARCInstKind::StoreWeak: 691 case ARCInstKind::InitWeak: 692 case ARCInstKind::LoadWeak: 693 case ARCInstKind::MoveWeak: 694 case ARCInstKind::CopyWeak: 695 case ARCInstKind::DestroyWeak: 696 case ARCInstKind::StoreStrong: 697 case ARCInstKind::CallOrUser: 698 case ARCInstKind::Call: 699 case ARCInstKind::UnsafeClaimRV: 700 return true; 701 } 702 703 llvm_unreachable("covered switch isn't covered?"); 704 } 705