@@ -847,15 +847,15 @@ MemoryEffects BasicAAResult::getMemoryEffects(const Function *F) {
847
847
848
848
ModRefInfo BasicAAResult::getArgModRefInfo (const CallBase *Call,
849
849
unsigned ArgIdx) {
850
- if (Call->paramHasAttr (ArgIdx, Attribute::WriteOnly))
850
+ if (Call->doesNotAccessMemory (ArgIdx))
851
+ return ModRefInfo::NoModRef;
852
+
853
+ if (Call->onlyWritesMemory (ArgIdx))
851
854
return ModRefInfo::Mod;
852
855
853
- if (Call->paramHasAttr (ArgIdx, Attribute::ReadOnly ))
856
+ if (Call->onlyReadsMemory (ArgIdx))
854
857
return ModRefInfo::Ref;
855
858
856
- if (Call->paramHasAttr (ArgIdx, Attribute::ReadNone))
857
- return ModRefInfo::NoModRef;
858
-
859
859
return ModRefInfo::ModRef;
860
860
}
861
861
@@ -921,66 +921,58 @@ ModRefInfo BasicAAResult::getModRefInfo(const CallBase *Call,
921
921
if (!AI->isStaticAlloca () && isIntrinsicCall (Call, Intrinsic::stackrestore))
922
922
return ModRefInfo::Mod;
923
923
924
- // A call can access a locally allocated object either because it is passed as
925
- // an argument to the call, or because it has escaped prior to the call.
926
- //
927
- // Make sure the object has not escaped here, and then check that none of the
928
- // call arguments alias the object below.
924
+ // We can completely ignore inaccessible memory here, because MemoryLocations
925
+ // can only reference accessible memory.
926
+ auto ME = AAQI.AAR .getMemoryEffects (Call, AAQI)
927
+ .getWithoutLoc (IRMemLocation::InaccessibleMem);
928
+ if (ME.doesNotAccessMemory ())
929
+ return ModRefInfo::NoModRef;
930
+
931
+ ModRefInfo ArgMR = ME.getModRef (IRMemLocation::ArgMem);
932
+ ModRefInfo OtherMR = ME.getWithoutLoc (IRMemLocation::ArgMem).getModRef ();
933
+
934
+ // An identified function-local object that does not escape can only be
935
+ // accessed via call arguments. Reduce OtherMR (which includes accesses to
936
+ // escaped memory) based on that.
929
937
//
930
938
// We model calls that can return twice (setjmp) as clobbering non-escaping
931
939
// objects, to model any accesses that may occur prior to the second return.
932
940
// As an exception, ignore allocas, as setjmp is not required to preserve
933
941
// non-volatile stores for them.
934
- if (!isa<Constant>(Object) && Call != Object &&
935
- AAQI.CA ->isNotCapturedBefore (Object, Call, /* OrAt*/ false ) &&
936
- (isa<AllocaInst>(Object) || !Call->hasFnAttr (Attribute::ReturnsTwice))) {
937
-
938
- // Optimistically assume that call doesn't touch Object and check this
939
- // assumption in the following loop.
940
- ModRefInfo Result = ModRefInfo::NoModRef;
941
-
942
- unsigned OperandNo = 0 ;
943
- for (auto CI = Call->data_operands_begin (), CE = Call->data_operands_end ();
944
- CI != CE; ++CI, ++OperandNo) {
945
- if (!(*CI)->getType ()->isPointerTy ())
946
- continue ;
947
-
948
- // Call doesn't access memory through this operand, so we don't care
949
- // if it aliases with Object.
950
- if (Call->doesNotAccessMemory (OperandNo))
951
- continue ;
952
-
953
- // If this is a no-capture pointer argument, see if we can tell that it
954
- // is impossible to alias the pointer we're checking.
955
- AliasResult AR =
956
- AAQI.AAR .alias (MemoryLocation::getBeforeOrAfter (*CI),
957
- MemoryLocation::getBeforeOrAfter (Object), AAQI);
958
- // Operand doesn't alias 'Object', continue looking for other aliases
959
- if (AR == AliasResult::NoAlias)
942
+ if (isModOrRefSet (OtherMR) && !isa<Constant>(Object) && Call != Object &&
943
+ AAQI.CA ->isNotCapturedBefore (Object, Call, /* OrAt=*/ false ) &&
944
+ (isa<AllocaInst>(Object) || !Call->hasFnAttr (Attribute::ReturnsTwice)))
945
+ OtherMR = ModRefInfo::NoModRef;
946
+
947
+ // Refine the modref info for argument memory. We only bother to do this
948
+ // if ArgMR is not a subset of OtherMR, otherwise this won't have an impact
949
+ // on the final result.
950
+ if ((ArgMR | OtherMR) != OtherMR) {
951
+ ModRefInfo NewArgMR = ModRefInfo::NoModRef;
952
+ for (const Use &U : Call->data_ops ()) {
953
+ const Value *Arg = U;
954
+ if (!Arg->getType ()->isPointerTy ())
960
955
continue ;
961
- // Operand aliases 'Object', but call doesn't modify it. Strengthen
962
- // initial assumption and keep looking in case if there are more aliases.
963
- if (Call->onlyReadsMemory (OperandNo)) {
964
- Result |= ModRefInfo::Ref;
965
- continue ;
966
- }
967
- // Operand aliases 'Object' but call only writes into it.
968
- if (Call->onlyWritesMemory (OperandNo)) {
969
- Result |= ModRefInfo::Mod;
970
- continue ;
971
- }
972
- // This operand aliases 'Object' and call reads and writes into it.
973
- // Setting ModRef will not yield an early return below, MustAlias is not
974
- // used further.
975
- Result = ModRefInfo::ModRef;
976
- break ;
956
+ unsigned ArgIdx = Call->getDataOperandNo (&U);
957
+ MemoryLocation ArgLoc =
958
+ Call->isArgOperand (&U)
959
+ ? MemoryLocation::getForArgument (Call, ArgIdx, TLI)
960
+ : MemoryLocation::getBeforeOrAfter (Arg);
961
+ AliasResult ArgAlias = AAQI.AAR .alias (ArgLoc, Loc, AAQI, Call);
962
+ if (ArgAlias != AliasResult::NoAlias)
963
+ NewArgMR |= ArgMR & AAQI.AAR .getArgModRefInfo (Call, ArgIdx);
964
+
965
+ // Exit early if we cannot improve over the original ArgMR.
966
+ if (NewArgMR == ArgMR)
967
+ break ;
977
968
}
978
-
979
- // Early return if we improved mod ref information
980
- if (!isModAndRefSet (Result))
981
- return Result;
969
+ ArgMR = NewArgMR;
982
970
}
983
971
972
+ ModRefInfo Result = ArgMR | OtherMR;
973
+ if (!isModAndRefSet (Result))
974
+ return Result;
975
+
984
976
// If the call is malloc/calloc like, we can assume that it doesn't
985
977
// modify any IR visible value. This is only valid because we assume these
986
978
// routines do not read values visible in the IR. TODO: Consider special
0 commit comments