19d46ef67baf92022f82a49bb2eb8b737b2bdbe95Michael Gottesman//===- ObjCARCContract.cpp - ObjC ARC Optimization ------------------------===//
23a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman//
33a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman//                     The LLVM Compiler Infrastructure
43a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman//
53a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman// This file is distributed under the University of Illinois Open Source
63a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman// License. See LICENSE.TXT for details.
73a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman//
83a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman//===----------------------------------------------------------------------===//
93a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// \file
103a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// This file defines late ObjC ARC optimizations. ARC stands for Automatic
113a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// Reference Counting and is a system for managing reference counts for objects
123a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// in Objective C.
133a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman///
1465c46b0cff2a7bcefff9b58895cdf8d710e3b6f7Michael Gottesman/// This specific file mainly deals with ``contracting'' multiple lower level
1565c46b0cff2a7bcefff9b58895cdf8d710e3b6f7Michael Gottesman/// operations into singular higher level operations through pattern matching.
1665c46b0cff2a7bcefff9b58895cdf8d710e3b6f7Michael Gottesman///
173a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// WARNING: This file knows about certain library functions. It recognizes them
183a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// by name, and hardwires knowledge of their semantics.
193a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman///
203a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// WARNING: This file knows about how certain Objective-C library functions are
213a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// used. Naive LLVM IR transformations which would otherwise be
223a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// behavior-preserving may break these assumptions.
233a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman///
243a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman//===----------------------------------------------------------------------===//
253a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
263a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman// TODO: ObjCARCContract could insert PHI nodes when uses aren't
273a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman// dominated by single calls.
283a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
293a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman#include "ObjCARC.h"
302e696cf61c30c68c595b0b000d368a834ddc63b9Michael Gottesman#include "ARCRuntimeEntryPoints.h"
313a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman#include "DependencyAnalysis.h"
327a7102d17f979918042bc040e27288d64a6bea5fMichael Gottesman#include "ProvenanceAnalysis.h"
333a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman#include "llvm/ADT/Statistic.h"
3436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/Dominators.h"
353a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman#include "llvm/IR/InlineAsm.h"
363a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman#include "llvm/IR/Operator.h"
379ab758b9bc2fe51af6dabbdeb30f4a2e600bdcd0Michael Gottesman#include "llvm/Support/Debug.h"
384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/Support/raw_ostream.h"
393a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
403a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesmanusing namespace llvm;
413a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesmanusing namespace llvm::objcarc;
423a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
43dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "objc-arc-contract"
44dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
453a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael GottesmanSTATISTIC(NumPeeps,       "Number of calls peephole-optimized");
463a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael GottesmanSTATISTIC(NumStoreStrongs, "Number objc_storeStrong calls formed");
473a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
48ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===//
49ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//                                Declarations
50ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===//
51ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
523a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesmannamespace {
533a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  /// \brief Late ARC optimizations
543a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  ///
553a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  /// These change the IR in a way that makes it difficult to be analyzed by
563a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  /// ObjCARCOpt, so it's run late.
573a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  class ObjCARCContract : public FunctionPass {
583a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    bool Changed;
593a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    AliasAnalysis *AA;
603a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    DominatorTree *DT;
613a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    ProvenanceAnalysis PA;
622e696cf61c30c68c595b0b000d368a834ddc63b9Michael Gottesman    ARCRuntimeEntryPoints EP;
633a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
643a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    /// A flag indicating whether this optimization pass should run.
653a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    bool Run;
663a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
673a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    /// The inline asm string to insert between calls and RetainRV calls to make
683a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    /// the optimization work on targets which need it.
693a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    const MDString *RetainRVMarker;
703a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
713a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    /// The set of inserted objc_storeStrong calls. If at the end of walking the
723a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    /// function we have found no alloca instructions, these calls can be marked
733a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    /// "tail".
743a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    SmallPtrSet<CallInst *, 8> StoreStrongCalls;
753a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
76ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    /// Returns true if we eliminated Inst.
77ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    bool tryToPeepholeInstruction(Function &F, Instruction *Inst,
78ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                  inst_iterator &Iter,
79ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                  SmallPtrSetImpl<Instruction *> &DepInsts,
80ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                  SmallPtrSetImpl<const BasicBlock *> &Visited,
81ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                  bool &TailOkForStoreStrong);
82f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman
83ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    bool optimizeRetainCall(Function &F, Instruction *Retain);
843a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
85ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    bool
86ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    contractAutorelease(Function &F, Instruction *Autorelease,
87ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                        ARCInstKind Class,
88ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                        SmallPtrSetImpl<Instruction *> &DependingInstructions,
89ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                        SmallPtrSetImpl<const BasicBlock *> &Visited);
90ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
91ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    void tryToContractReleaseIntoStoreStrong(Instruction *Release,
92ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                             inst_iterator &Iter);
933a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    void getAnalysisUsage(AnalysisUsage &AU) const override;
9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool doInitialization(Module &M) override;
9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool runOnFunction(Function &F) override;
973a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
983a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  public:
993a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    static char ID;
1003a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    ObjCARCContract() : FunctionPass(ID) {
1013a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      initializeObjCARCContractPass(*PassRegistry::getPassRegistry());
1023a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    }
1033a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  };
1043a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman}
1053a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
106ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===//
107ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//                               Implementation
108ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===//
1093a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
110f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman/// Turn objc_retain into objc_retainAutoreleasedReturnValue if the operand is a
111f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman/// return value. We do this late so we do not disrupt the dataflow analysis in
112f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman/// ObjCARCOpt.
113ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesbool ObjCARCContract::optimizeRetainCall(Function &F, Instruction *Retain) {
114ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  ImmutableCallSite CS(GetArgRCIdentityRoot(Retain));
115f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman  const Instruction *Call = CS.getInstruction();
116f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman  if (!Call)
117f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman    return false;
118f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman  if (Call->getParent() != Retain->getParent())
119f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman    return false;
120f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman
121f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman  // Check that the call is next to the retain.
122f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman  BasicBlock::const_iterator I = Call;
123f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman  ++I;
124f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman  while (IsNoopInstruction(I)) ++I;
125f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman  if (&*I != Retain)
126f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman    return false;
127f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman
128f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman  // Turn it to an objc_retainAutoreleasedReturnValue.
129f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman  Changed = true;
130f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman  ++NumPeeps;
131f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman
132f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman  DEBUG(dbgs() << "Transforming objc_retain => "
133f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman                  "objc_retainAutoreleasedReturnValue since the operand is a "
134f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman                  "return value.\nOld: "<< *Retain << "\n");
135f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman
136f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman  // We do not have to worry about tail calls/does not throw since
137f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman  // retain/retainRV have the same properties.
1384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  Constant *Decl = EP.get(ARCRuntimeEntryPointKind::RetainRV);
1392e696cf61c30c68c595b0b000d368a834ddc63b9Michael Gottesman  cast<CallInst>(Retain)->setCalledFunction(Decl);
140f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman
141f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman  DEBUG(dbgs() << "New: " << *Retain << "\n");
142f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman  return true;
143f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman}
144f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman
1453a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// Merge an autorelease with a retain into a fused call.
146ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesbool ObjCARCContract::contractAutorelease(
147ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Function &F, Instruction *Autorelease, ARCInstKind Class,
148ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    SmallPtrSetImpl<Instruction *> &DependingInstructions,
149ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    SmallPtrSetImpl<const BasicBlock *> &Visited) {
150ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  const Value *Arg = GetArgRCIdentityRoot(Autorelease);
1513a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
1523a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  // Check that there are no instructions between the retain and the autorelease
1533a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  // (such as an autorelease_pop) which may change the count.
154dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  CallInst *Retain = nullptr;
155ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (Class == ARCInstKind::AutoreleaseRV)
1563a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    FindDependencies(RetainAutoreleaseRVDep, Arg,
1573a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman                     Autorelease->getParent(), Autorelease,
1583a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman                     DependingInstructions, Visited, PA);
1593a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  else
1603a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    FindDependencies(RetainAutoreleaseDep, Arg,
1613a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman                     Autorelease->getParent(), Autorelease,
1623a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman                     DependingInstructions, Visited, PA);
1633a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
1643a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  Visited.clear();
1653a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  if (DependingInstructions.size() != 1) {
1663a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    DependingInstructions.clear();
1673a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    return false;
1683a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  }
1693a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
1703a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  Retain = dyn_cast_or_null<CallInst>(*DependingInstructions.begin());
1713a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  DependingInstructions.clear();
1723a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
173ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (!Retain || GetBasicARCInstKind(Retain) != ARCInstKind::Retain ||
174ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      GetArgRCIdentityRoot(Retain) != Arg)
1753a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    return false;
1763a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
1773a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  Changed = true;
1783a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  ++NumPeeps;
1793a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
180ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  DEBUG(dbgs() << "    Fusing retain/autorelease!\n"
181ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                  "        Autorelease:" << *Autorelease << "\n"
182ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                  "        Retain: " << *Retain << "\n");
1833a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
184ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Constant *Decl = EP.get(Class == ARCInstKind::AutoreleaseRV
1854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                              ? ARCRuntimeEntryPointKind::RetainAutoreleaseRV
1864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                              : ARCRuntimeEntryPointKind::RetainAutorelease);
1872e696cf61c30c68c595b0b000d368a834ddc63b9Michael Gottesman  Retain->setCalledFunction(Decl);
1883a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
189ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  DEBUG(dbgs() << "        New RetainAutorelease: " << *Retain << "\n");
1903a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
1913a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  EraseInstruction(Autorelease);
1923a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  return true;
1933a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman}
1943a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
195ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic StoreInst *findSafeStoreForStoreStrongContraction(LoadInst *Load,
196ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                                         Instruction *Release,
197ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                                         ProvenanceAnalysis &PA,
198ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                                         AliasAnalysis *AA) {
199ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  StoreInst *Store = nullptr;
200ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool SawRelease = false;
2013a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
202ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Get the location associated with Load.
203ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  AliasAnalysis::Location Loc = AA->getLocation(Load);
2043a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
2053a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  // Walk down to find the store and the release, which may be in either order.
206ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (auto I = std::next(BasicBlock::iterator(Load)),
207ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            E = Load->getParent()->end();
208ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines       I != E; ++I) {
209ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // If we found the store we were looking for and saw the release,
210ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // break. There is no more work to be done.
211ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (Store && SawRelease)
212ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
2133a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
214ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // Now we know that we have not seen either the store or the release. If I
215ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // is the the release, mark that we saw the release and continue.
216ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Instruction *Inst = &*I;
2173a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    if (Inst == Release) {
2183a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      SawRelease = true;
2193a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      continue;
2203a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    }
2213a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
222ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // Otherwise, we check if Inst is a "good" store. Grab the instruction class
223ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // of Inst.
224ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    ARCInstKind Class = GetBasicARCInstKind(Inst);
2253a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
226ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // If Inst is an unrelated retain, we don't care about it.
227ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    //
228ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // TODO: This is one area where the optimization could be made more
229ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // aggressive.
2303a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    if (IsRetain(Class))
2313a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      continue;
2323a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
233ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // If we have seen the store, but not the release...
2343a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    if (Store) {
235ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // We need to make sure that it is safe to move the release from its
236ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // current position to the store. This implies proving that any
237ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // instruction in between Store and the Release conservatively can not use
238ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // the RCIdentityRoot of Release. If we can prove we can ignore Inst, so
239ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // continue...
240ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (!CanUse(Inst, Load, PA, Class)) {
241ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        continue;
242ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      }
243ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
244ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // Otherwise, be conservative and return nullptr.
245ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return nullptr;
2463a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    }
247ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
248ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // Ok, now we know we have not seen a store yet. See if Inst can write to
249ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // our load location, if it can not, just ignore the instruction.
250ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (!(AA->getModRefInfo(Inst, Loc) & AliasAnalysis::Mod))
251ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      continue;
252ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
253ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Store = dyn_cast<StoreInst>(Inst);
254ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
255ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // If Inst can, then check if Inst is a simple store. If Inst is not a
256ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // store or a store that is not simple, then we have some we do not
257ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // understand writing to this memory implying we can not move the load
258ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // over the write to any subsequent store that we may find.
259ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (!Store || !Store->isSimple())
260ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return nullptr;
261ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
262ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // Then make sure that the pointer we are storing to is Ptr. If so, we
263ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // found our Store!
264ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (Store->getPointerOperand() == Loc.Ptr)
265ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      continue;
266ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
267ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // Otherwise, we have an unknown store to some other ptr that clobbers
268ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // Loc.Ptr. Bail!
269ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return nullptr;
2703a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  }
2713a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
272ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // If we did not find the store or did not see the release, fail.
273ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (!Store || !SawRelease)
274ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return nullptr;
275ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
276ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // We succeeded!
277ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return Store;
278ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
2793a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
280ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic Instruction *
281ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesfindRetainForStoreStrongContraction(Value *New, StoreInst *Store,
282ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                    Instruction *Release,
283ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                    ProvenanceAnalysis &PA) {
284ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Walk up from the Store to find the retain.
285ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  BasicBlock::iterator I = Store;
286ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  BasicBlock::iterator Begin = Store->getParent()->begin();
287ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  while (I != Begin && GetBasicARCInstKind(I) != ARCInstKind::Retain) {
288ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Instruction *Inst = &*I;
289ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
290ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // It is only safe to move the retain to the store if we can prove
291ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // conservatively that nothing besides the release can decrement reference
292ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // counts in between the retain and the store.
293ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (CanDecrementRefCount(Inst, New, PA) && Inst != Release)
294ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return nullptr;
2953a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    --I;
296ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
2973a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  Instruction *Retain = I;
298ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (GetBasicARCInstKind(Retain) != ARCInstKind::Retain)
299ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return nullptr;
300ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (GetArgRCIdentityRoot(Retain) != New)
301ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return nullptr;
302ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return Retain;
303ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
304ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
305ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// Attempt to merge an objc_release with a store, load, and objc_retain to form
306ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// an objc_storeStrong. An objc_storeStrong:
307ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines///
308ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines///   objc_storeStrong(i8** %old_ptr, i8* new_value)
309ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines///
310ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// is equivalent to the following IR sequence:
311ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines///
312ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines///   ; Load old value.
313ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines///   %old_value = load i8** %old_ptr               (1)
314ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines///
315ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines///   ; Increment the new value and then release the old value. This must occur
316ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines///   ; in order in case old_value releases new_value in its destructor causing
317ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines///   ; us to potentially have a dangling ptr.
318ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines///   tail call i8* @objc_retain(i8* %new_value)    (2)
319ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines///   tail call void @objc_release(i8* %old_value)  (3)
320ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines///
321ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines///   ; Store the new_value into old_ptr
322ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines///   store i8* %new_value, i8** %old_ptr           (4)
323ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines///
324ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// The safety of this optimization is based around the following
325ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// considerations:
326ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines///
327ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines///  1. We are forming the store strong at the store. Thus to perform this
328ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines///     optimization it must be safe to move the retain, load, and release to
329ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines///     (4).
330ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines///  2. We need to make sure that any re-orderings of (1), (2), (3), (4) are
331ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines///     safe.
332ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid ObjCARCContract::tryToContractReleaseIntoStoreStrong(Instruction *Release,
333ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                                          inst_iterator &Iter) {
334ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // See if we are releasing something that we just loaded.
335ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  auto *Load = dyn_cast<LoadInst>(GetArgRCIdentityRoot(Release));
336ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (!Load || !Load->isSimple())
337ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return;
338ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
339ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // For now, require everything to be in one basic block.
340ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  BasicBlock *BB = Release->getParent();
341ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (Load->getParent() != BB)
342ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return;
343ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
344ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // First scan down the BB from Load, looking for a store of the RCIdentityRoot
345ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // of Load's
346ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  StoreInst *Store =
347ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      findSafeStoreForStoreStrongContraction(Load, Release, PA, AA);
348ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // If we fail, bail.
349ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (!Store)
350ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return;
351ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
352ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Then find what new_value's RCIdentity Root is.
353ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Value *New = GetRCIdentityRoot(Store->getValueOperand());
354ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
355ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Then walk up the BB and look for a retain on New without any intervening
356ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // instructions which conservatively might decrement ref counts.
357ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Instruction *Retain =
358ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      findRetainForStoreStrongContraction(New, Store, Release, PA);
359ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
360ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // If we fail, bail.
361ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (!Retain)
362ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return;
3633a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
3643a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  Changed = true;
3653a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  ++NumStoreStrongs;
3663a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
367ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  DEBUG(
368ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      llvm::dbgs() << "    Contracting retain, release into objc_storeStrong.\n"
369ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                   << "        Old:\n"
370ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                   << "            Store:   " << *Store << "\n"
371ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                   << "            Release: " << *Release << "\n"
372ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                   << "            Retain:  " << *Retain << "\n"
373ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                   << "            Load:    " << *Load << "\n");
374ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
3753a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  LLVMContext &C = Release->getContext();
3763a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
3773a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  Type *I8XX = PointerType::getUnqual(I8X);
3783a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
3793a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  Value *Args[] = { Load->getPointerOperand(), New };
3803a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  if (Args[0]->getType() != I8XX)
3813a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    Args[0] = new BitCastInst(Args[0], I8XX, "", Store);
3823a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  if (Args[1]->getType() != I8X)
3833a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    Args[1] = new BitCastInst(Args[1], I8X, "", Store);
3844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  Constant *Decl = EP.get(ARCRuntimeEntryPointKind::StoreStrong);
3852e696cf61c30c68c595b0b000d368a834ddc63b9Michael Gottesman  CallInst *StoreStrong = CallInst::Create(Decl, Args, "", Store);
3863a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  StoreStrong->setDoesNotThrow();
3873a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  StoreStrong->setDebugLoc(Store->getDebugLoc());
3883a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
3893a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  // We can't set the tail flag yet, because we haven't yet determined
3903a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  // whether there are any escaping allocas. Remember this call, so that
3913a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  // we can set the tail flag once we know it's safe.
3923a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  StoreStrongCalls.insert(StoreStrong);
3933a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
394ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  DEBUG(llvm::dbgs() << "        New Store Strong: " << *StoreStrong << "\n");
395ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
3963a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  if (&*Iter == Store) ++Iter;
3973a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  Store->eraseFromParent();
3983a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  Release->eraseFromParent();
3993a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  EraseInstruction(Retain);
4003a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  if (Load->use_empty())
4013a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    Load->eraseFromParent();
4023a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman}
4033a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
404ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesbool ObjCARCContract::tryToPeepholeInstruction(
405ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Function &F, Instruction *Inst, inst_iterator &Iter,
406ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  SmallPtrSetImpl<Instruction *> &DependingInsts,
407ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  SmallPtrSetImpl<const BasicBlock *> &Visited,
408ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool &TailOkForStoreStrongs) {
4093a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    // Only these library routines return their argument. In particular,
4103a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    // objc_retainBlock does not necessarily return its argument.
411ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  ARCInstKind Class = GetBasicARCInstKind(Inst);
4123a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    switch (Class) {
413ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case ARCInstKind::FusedRetainAutorelease:
414ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case ARCInstKind::FusedRetainAutoreleaseRV:
415ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return false;
416ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case ARCInstKind::Autorelease:
417ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case ARCInstKind::AutoreleaseRV:
418ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return contractAutorelease(F, Inst, Class, DependingInsts, Visited);
419ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case ARCInstKind::Retain:
420f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman      // Attempt to convert retains to retainrvs if they are next to function
421f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman      // calls.
422ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (!optimizeRetainCall(F, Inst))
423ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        return false;
424f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman      // If we succeed in our optimization, fall through.
425f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman      // FALLTHROUGH
426ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case ARCInstKind::RetainRV: {
4273a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      // If we're compiling for a target which needs a special inline-asm
4283a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      // marker to do the retainAutoreleasedReturnValue optimization,
4293a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      // insert it now.
4303a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      if (!RetainRVMarker)
431ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        return false;
4323a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      BasicBlock::iterator BBI = Inst;
4333a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      BasicBlock *InstParent = Inst->getParent();
4343a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
4353a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      // Step up to see if the call immediately precedes the RetainRV call.
4363a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      // If it's an invoke, we have to cross a block boundary. And we have
4373a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      // to carefully dodge no-op instructions.
4383a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      do {
4393a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        if (&*BBI == InstParent->begin()) {
4403a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman          BasicBlock *Pred = InstParent->getSinglePredecessor();
4413a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman          if (!Pred)
4423a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman            goto decline_rv_optimization;
4433a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman          BBI = Pred->getTerminator();
4443a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman          break;
4453a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        }
4463a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        --BBI;
447f0a15d88afce23453ff55894400035014ad46a15Michael Gottesman      } while (IsNoopInstruction(BBI));
4483a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
449ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (&*BBI == GetArgRCIdentityRoot(Inst)) {
450ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        DEBUG(dbgs() << "Adding inline asm marker for "
4513a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman                        "retainAutoreleasedReturnValue optimization.\n");
4523a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        Changed = true;
4533a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        InlineAsm *IA =
4543a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman          InlineAsm::get(FunctionType::get(Type::getVoidTy(Inst->getContext()),
4553a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman                                           /*isVarArg=*/false),
4563a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman                         RetainRVMarker->getString(),
4573a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman                         /*Constraints=*/"", /*hasSideEffects=*/true);
4583a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        CallInst::Create(IA, "", Inst);
4593a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      }
4603a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    decline_rv_optimization:
461ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return false;
4623a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    }
463ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case ARCInstKind::InitWeak: {
4643a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      // objc_initWeak(p, null) => *p = null
4653a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      CallInst *CI = cast<CallInst>(Inst);
466f0a15d88afce23453ff55894400035014ad46a15Michael Gottesman      if (IsNullOrUndef(CI->getArgOperand(1))) {
4673a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        Value *Null =
4683a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman          ConstantPointerNull::get(cast<PointerType>(CI->getType()));
4693a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        Changed = true;
4703a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        new StoreInst(Null, CI->getArgOperand(0), CI);
4713a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
4723a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        DEBUG(dbgs() << "OBJCARCContract: Old = " << *CI << "\n"
4733a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman                     << "                 New = " << *Null << "\n");
4743a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
4753a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        CI->replaceAllUsesWith(Null);
4763a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        CI->eraseFromParent();
4773a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      }
478ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return true;
4793a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    }
480ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case ARCInstKind::Release:
481ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // Try to form an objc store strong from our release. If we fail, there is
482ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // nothing further to do below, so continue.
483ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      tryToContractReleaseIntoStoreStrong(Inst, Iter);
484ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return true;
485ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case ARCInstKind::User:
4863a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      // Be conservative if the function has any alloca instructions.
4873a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      // Technically we only care about escaping alloca instructions,
4883a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      // but this is sufficient to handle some interesting cases.
4893a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      if (isa<AllocaInst>(Inst))
4903a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        TailOkForStoreStrongs = false;
491ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return true;
492ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case ARCInstKind::IntrinsicUser:
4931f9c4407c0e66f0c473ed5d6e3abcedda3a838c9John McCall      // Remove calls to @clang.arc.use(...).
4941f9c4407c0e66f0c473ed5d6e3abcedda3a838c9John McCall      Inst->eraseFromParent();
495ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return true;
4963a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    default:
497ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return true;
4983a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    }
499ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
500ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
501ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===//
502ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//                              Top Level Driver
503ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===//
504ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
505ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesbool ObjCARCContract::runOnFunction(Function &F) {
506ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (!EnableARCOpts)
507ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return false;
508ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
509ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // If nothing in the Module uses ARC, don't do anything.
510ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (!Run)
511ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return false;
5123a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
513ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Changed = false;
514ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  AA = &getAnalysis<AliasAnalysis>();
515ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
516ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
517ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  PA.setAA(&getAnalysis<AliasAnalysis>());
518ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
519ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  DEBUG(llvm::dbgs() << "**** ObjCARC Contract ****\n");
520ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
521ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Track whether it's ok to mark objc_storeStrong calls with the "tail"
522ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // keyword. Be conservative if the function has variadic arguments.
523ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // It seems that functions which "return twice" are also unsafe for the
524ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // "tail" argument, because they are setjmp, which could need to
525ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // return to an earlier stack state.
526ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool TailOkForStoreStrongs =
527ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      !F.isVarArg() && !F.callsFunctionThatReturnsTwice();
5283a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
529ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // For ObjC library calls which return their argument, replace uses of the
530ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // argument with uses of the call return value, if it dominates the use. This
531ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // reduces register pressure.
532ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  SmallPtrSet<Instruction *, 4> DependingInstructions;
533ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  SmallPtrSet<const BasicBlock *, 4> Visited;
534ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E;) {
535ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Instruction *Inst = &*I++;
536ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
537ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    DEBUG(dbgs() << "Visiting: " << *Inst << "\n");
538ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
539ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // First try to peephole Inst. If there is nothing further we can do in
540ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // terms of undoing objc-arc-expand, process the next inst.
541ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (tryToPeepholeInstruction(F, Inst, I, DependingInstructions, Visited,
542ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                 TailOkForStoreStrongs))
543ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      continue;
544ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
545ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // Otherwise, try to undo objc-arc-expand.
546ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
547ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // Don't use GetArgRCIdentityRoot because we don't want to look through bitcasts
5483a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    // and such; to do the replacement, the argument must have type i8*.
54936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Value *Arg = cast<CallInst>(Inst)->getArgOperand(0);
550ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
551ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // TODO: Change this to a do-while.
5523a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    for (;;) {
5533a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      // If we're compiling bugpointed code, don't get in trouble.
5543a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      if (!isa<Instruction>(Arg) && !isa<Argument>(Arg))
5553a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        break;
5563a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      // Look through the uses of the pointer.
55736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      for (Value::use_iterator UI = Arg->use_begin(), UE = Arg->use_end();
5583a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman           UI != UE; ) {
55936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        // Increment UI now, because we may unlink its element.
56036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Use &U = *UI++;
56136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        unsigned OperandNo = U.getOperandNo();
5623a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
5633a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        // If the call's return value dominates a use of the call's argument
5643a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        // value, rewrite the use to use the return value. We check for
5653a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        // reachability here because an unreachable call is considered to
5663a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        // trivially dominate itself, which would lead us to rewriting its
5673a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        // argument in terms of its return value, which would lead to
568ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        // infinite loops in GetArgRCIdentityRoot.
5693a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        if (DT->isReachableFromEntry(U) && DT->dominates(Inst, U)) {
5703a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman          Changed = true;
5713a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman          Instruction *Replacement = Inst;
5723a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman          Type *UseTy = U.get()->getType();
5733a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman          if (PHINode *PHI = dyn_cast<PHINode>(U.getUser())) {
5743a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman            // For PHI nodes, insert the bitcast in the predecessor block.
5753a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman            unsigned ValNo = PHINode::getIncomingValueNumForOperand(OperandNo);
5763a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman            BasicBlock *BB = PHI->getIncomingBlock(ValNo);
5773a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman            if (Replacement->getType() != UseTy)
5783a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman              Replacement = new BitCastInst(Replacement, UseTy, "",
5793a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman                                            &BB->back());
5803a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman            // While we're here, rewrite all edges for this PHI, rather
5813a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman            // than just one use at a time, to minimize the number of
5823a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman            // bitcasts we emit.
5833a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman            for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i)
5843a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman              if (PHI->getIncomingBlock(i) == BB) {
5853a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman                // Keep the UI iterator valid.
58636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                if (UI != UE &&
58736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                    &PHI->getOperandUse(
58836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                        PHINode::getOperandNumForIncomingValue(i)) == &*UI)
5893a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman                  ++UI;
5903a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman                PHI->setIncomingValue(i, Replacement);
5913a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman              }
5923a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman          } else {
5933a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman            if (Replacement->getType() != UseTy)
5943a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman              Replacement = new BitCastInst(Replacement, UseTy, "",
5953a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman                                            cast<Instruction>(U.getUser()));
5963a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman            U.set(Replacement);
5973a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman          }
5983a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        }
5993a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      }
6003a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
6013a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      // If Arg is a no-op casted pointer, strip one level of casts and iterate.
6023a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      if (const BitCastInst *BI = dyn_cast<BitCastInst>(Arg))
6033a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        Arg = BI->getOperand(0);
6043a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      else if (isa<GEPOperator>(Arg) &&
6053a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman               cast<GEPOperator>(Arg)->hasAllZeroIndices())
6063a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        Arg = cast<GEPOperator>(Arg)->getPointerOperand();
6073a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      else if (isa<GlobalAlias>(Arg) &&
6083a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman               !cast<GlobalAlias>(Arg)->mayBeOverridden())
6093a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        Arg = cast<GlobalAlias>(Arg)->getAliasee();
6103a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman      else
6113a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman        break;
6123a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman    }
6133a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  }
6143a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
6153a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  // If this function has no escaping allocas or suspicious vararg usage,
6163a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  // objc_storeStrong calls can be marked with the "tail" keyword.
6173a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  if (TailOkForStoreStrongs)
61837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    for (CallInst *CI : StoreStrongCalls)
61937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      CI->setTailCall();
6203a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  StoreStrongCalls.clear();
6213a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman
6223a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman  return Changed;
6233a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman}
624ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
625ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===//
626ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//                             Misc Pass Manager
627ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===//
628ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
629ebe69fe11e48d322045d5949c83283927a0d790bStephen Hineschar ObjCARCContract::ID = 0;
630ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesINITIALIZE_PASS_BEGIN(ObjCARCContract, "objc-arc-contract",
631ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                      "ObjC ARC contraction", false, false)
632ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesINITIALIZE_AG_DEPENDENCY(AliasAnalysis)
633ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesINITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
634ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesINITIALIZE_PASS_END(ObjCARCContract, "objc-arc-contract",
635ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                    "ObjC ARC contraction", false, false)
636ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
637ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid ObjCARCContract::getAnalysisUsage(AnalysisUsage &AU) const {
638ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  AU.addRequired<AliasAnalysis>();
639ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  AU.addRequired<DominatorTreeWrapperPass>();
640ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  AU.setPreservesCFG();
641ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
642ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
643ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesPass *llvm::createObjCARCContractPass() { return new ObjCARCContract(); }
644ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
645ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesbool ObjCARCContract::doInitialization(Module &M) {
646ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // If nothing in the Module uses ARC, don't do anything.
647ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Run = ModuleHasARC(M);
648ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (!Run)
649ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return false;
650ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
6514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  EP.init(&M);
652ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
653ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Initialize RetainRVMarker.
654ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  RetainRVMarker = nullptr;
655ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (NamedMDNode *NMD =
656ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          M.getNamedMetadata("clang.arc.retainAutoreleasedReturnValueMarker"))
657ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (NMD->getNumOperands() == 1) {
658ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      const MDNode *N = NMD->getOperand(0);
659ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (N->getNumOperands() == 1)
660ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (const MDString *S = dyn_cast<MDString>(N->getOperand(0)))
661ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          RetainRVMarker = S;
662ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
663ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
664ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return false;
665ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
666