33
33
#include " llvm/Intrinsics.h"
34
34
#include " llvm/GlobalVariable.h"
35
35
#include " llvm/DerivedTypes.h"
36
+ #include " llvm/Module.h"
36
37
#include " llvm/Analysis/ValueTracking.h"
37
38
#include " llvm/Transforms/Utils/Local.h"
38
39
#include " llvm/Support/CallSite.h"
@@ -564,6 +565,29 @@ static const Value *FindSingleUseIdentifiedObject(const Value *Arg) {
564
565
return 0 ;
565
566
}
566
567
568
+ // / ModuleHasARC - Test if the given module looks interesting to run ARC
569
+ // / optimization on.
570
+ static bool ModuleHasARC (const Module &M) {
571
+ return
572
+ M.getNamedValue (" objc_retain" ) ||
573
+ M.getNamedValue (" objc_release" ) ||
574
+ M.getNamedValue (" objc_autorelease" ) ||
575
+ M.getNamedValue (" objc_retainAutoreleasedReturnValue" ) ||
576
+ M.getNamedValue (" objc_retainBlock" ) ||
577
+ M.getNamedValue (" objc_autoreleaseReturnValue" ) ||
578
+ M.getNamedValue (" objc_autoreleasePoolPush" ) ||
579
+ M.getNamedValue (" objc_loadWeakRetained" ) ||
580
+ M.getNamedValue (" objc_loadWeak" ) ||
581
+ M.getNamedValue (" objc_destroyWeak" ) ||
582
+ M.getNamedValue (" objc_storeWeak" ) ||
583
+ M.getNamedValue (" objc_initWeak" ) ||
584
+ M.getNamedValue (" objc_moveWeak" ) ||
585
+ M.getNamedValue (" objc_copyWeak" ) ||
586
+ M.getNamedValue (" objc_retainedObject" ) ||
587
+ M.getNamedValue (" objc_unretainedObject" ) ||
588
+ M.getNamedValue (" objc_unretainedPointer" );
589
+ }
590
+
567
591
// ===----------------------------------------------------------------------===//
568
592
// ARC AliasAnalysis.
569
593
// ===----------------------------------------------------------------------===//
@@ -749,8 +773,12 @@ namespace {
749
773
// / ObjCARCExpand - Early ARC transformations.
750
774
class ObjCARCExpand : public FunctionPass {
751
775
virtual void getAnalysisUsage (AnalysisUsage &AU) const ;
776
+ virtual bool doInitialization (Module &M);
752
777
virtual bool runOnFunction (Function &F);
753
778
779
+ // / Run - A flag indicating whether this optimization pass should run.
780
+ bool Run;
781
+
754
782
public:
755
783
static char ID;
756
784
ObjCARCExpand () : FunctionPass(ID) {
@@ -771,10 +799,19 @@ void ObjCARCExpand::getAnalysisUsage(AnalysisUsage &AU) const {
771
799
AU.setPreservesCFG ();
772
800
}
773
801
802
+ bool ObjCARCExpand::doInitialization (Module &M) {
803
+ Run = ModuleHasARC (M);
804
+ return false ;
805
+ }
806
+
774
807
bool ObjCARCExpand::runOnFunction (Function &F) {
775
808
if (!EnableARCOpts)
776
809
return false ;
777
810
811
+ // If nothing in the Module uses ARC, don't do anything.
812
+ if (!Run)
813
+ return false ;
814
+
778
815
bool Changed = false ;
779
816
780
817
for (inst_iterator I = inst_begin (&F), E = inst_end (&F); I != E; ++I) {
@@ -840,8 +877,9 @@ bool ObjCARCExpand::runOnFunction(Function &F) {
840
877
// usually can't sink them past other calls, which would be the main
841
878
// case where it would be useful.
842
879
880
+ // / TODO: The pointer returned from objc_loadWeakRetained is retained.
881
+
843
882
#include " llvm/GlobalAlias.h"
844
- #include " llvm/Module.h"
845
883
#include " llvm/Constants.h"
846
884
#include " llvm/LLVMContext.h"
847
885
#include " llvm/Support/ErrorHandling.h"
@@ -1365,10 +1403,12 @@ namespace {
1365
1403
bool Changed;
1366
1404
ProvenanceAnalysis PA;
1367
1405
1406
+ // / Run - A flag indicating whether this optimization pass should run.
1407
+ bool Run;
1408
+
1368
1409
// / RetainFunc, RelaseFunc - Declarations for objc_retain,
1369
1410
// / objc_retainBlock, and objc_release.
1370
- Function *RetainFunc, *RetainBlockFunc, *RetainRVFunc, *ReleaseFunc,
1371
- *AutoreleaseFunc;
1411
+ Function *RetainFunc, *RetainBlockFunc, *RetainRVFunc, *ReleaseFunc;
1372
1412
1373
1413
// / RetainRVCallee, etc. - Declarations for ObjC runtime
1374
1414
// / functions, for use in creating calls to them. These are initialized
@@ -3069,6 +3109,10 @@ bool ObjCARCOpt::doInitialization(Module &M) {
3069
3109
if (!EnableARCOpts)
3070
3110
return false ;
3071
3111
3112
+ Run = ModuleHasARC (M);
3113
+ if (!Run)
3114
+ return false ;
3115
+
3072
3116
// Identify the imprecise release metadata kind.
3073
3117
ImpreciseReleaseMDKind =
3074
3118
M.getContext ().getMDKindID (" clang.imprecise_release" );
@@ -3078,7 +3122,6 @@ bool ObjCARCOpt::doInitialization(Module &M) {
3078
3122
RetainBlockFunc = M.getFunction (" objc_retainBlock" );
3079
3123
RetainRVFunc = M.getFunction (" objc_retainAutoreleasedReturnValue" );
3080
3124
ReleaseFunc = M.getFunction (" objc_release" );
3081
- AutoreleaseFunc = M.getFunction (" objc_autorelease" );
3082
3125
3083
3126
// Intuitively, objc_retain and others are nocapture, however in practice
3084
3127
// they are not, because they return their argument value. And objc_release
@@ -3098,6 +3141,10 @@ bool ObjCARCOpt::runOnFunction(Function &F) {
3098
3141
if (!EnableARCOpts)
3099
3142
return false ;
3100
3143
3144
+ // If nothing in the Module uses ARC, don't do anything.
3145
+ if (!Run)
3146
+ return false ;
3147
+
3101
3148
Changed = false ;
3102
3149
3103
3150
PA.setAA (&getAnalysis<AliasAnalysis>());
@@ -3162,6 +3209,9 @@ namespace {
3162
3209
DominatorTree *DT;
3163
3210
ProvenanceAnalysis PA;
3164
3211
3212
+ // / Run - A flag indicating whether this optimization pass should run.
3213
+ bool Run;
3214
+
3165
3215
// / StoreStrongCallee, etc. - Declarations for ObjC runtime
3166
3216
// / functions, for use in creating calls to them. These are initialized
3167
3217
// / lazily to avoid cluttering up the Module with unused declarations.
@@ -3384,6 +3434,10 @@ void ObjCARCContract::ContractRelease(Instruction *Release,
3384
3434
}
3385
3435
3386
3436
bool ObjCARCContract::doInitialization (Module &M) {
3437
+ Run = ModuleHasARC (M);
3438
+ if (!Run)
3439
+ return false ;
3440
+
3387
3441
// These are initialized lazily.
3388
3442
StoreStrongCallee = 0 ;
3389
3443
RetainAutoreleaseCallee = 0 ;
@@ -3407,6 +3461,10 @@ bool ObjCARCContract::runOnFunction(Function &F) {
3407
3461
if (!EnableARCOpts)
3408
3462
return false ;
3409
3463
3464
+ // If nothing in the Module uses ARC, don't do anything.
3465
+ if (!Run)
3466
+ return false ;
3467
+
3410
3468
Changed = false ;
3411
3469
AA = &getAnalysis<AliasAnalysis>();
3412
3470
DT = &getAnalysis<DominatorTree>();
0 commit comments