Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion llvm/include/llvm/IR/Function.h
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ class LLVM_ABI Function : public GlobalObject, public ilist_node<Function> {
bool onlyWritesMemory() const;
void setOnlyWritesMemory();

/// Determine if the call can access memmory only using pointers based
/// Determine if the call can access memory only using pointers based
/// on its arguments.
bool onlyAccessesArgMemory() const;
void setOnlyAccessesArgMemory();
Expand Down
10 changes: 10 additions & 0 deletions llvm/include/llvm/Support/ModRef.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,16 @@ template <typename LocationEnum> class MemoryEffectsBase {
return FRMB;
}

/// Create MemoryEffectsBase that can only access argument or errno memory.
static MemoryEffectsBase
argumentOrErrnoMemOnly(ModRefInfo ArgMR = ModRefInfo::ModRef,
ModRefInfo ErrnoMR = ModRefInfo::ModRef) {
MemoryEffectsBase FRMB = none();
FRMB.setModRef(Location::ArgMem, ArgMR);
FRMB.setModRef(Location::ErrnoMem, ErrnoMR);
return FRMB;
}

/// Create MemoryEffectsBase from an encoded integer value (used by memory
/// attribute).
static MemoryEffectsBase createFromIntValue(uint32_t Data) {
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/IR/Function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -904,7 +904,7 @@ void Function::setOnlyWritesMemory() {
setMemoryEffects(getMemoryEffects() & MemoryEffects::writeOnly());
}

/// Determine if the call can access memmory only using pointers based
/// Determine if the call can access memory only using pointers based
/// on its arguments.
bool Function::onlyAccessesArgMemory() const {
return getMemoryEffects().onlyAccessesArgPointees();
Expand Down
108 changes: 67 additions & 41 deletions llvm/lib/Transforms/Utils/BuildLibCalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,13 @@ STATISTIC(NumInaccessibleMemOnly,
STATISTIC(NumReadOnly, "Number of functions inferred as readonly");
STATISTIC(NumWriteOnly, "Number of functions inferred as writeonly");
STATISTIC(NumArgMemOnly, "Number of functions inferred as argmemonly");
STATISTIC(NumWriteErrnoMemOnly,
"Number of functions inferred as memory(errnomem: write)");
STATISTIC(NumInaccessibleMemOrArgMemOnly,
"Number of functions inferred as inaccessiblemem_or_argmemonly");
STATISTIC(
NumWriteArgumentMemOrErrnoMemOnly,
"Number of functions inferred as memory(argmem: write, errnomem: write)");
STATISTIC(NumNoUnwind, "Number of functions inferred as nounwind");
STATISTIC(NumNoCapture, "Number of arguments inferred as nocapture");
STATISTIC(NumWriteOnlyArg, "Number of arguments inferred as writeonly");
Expand Down Expand Up @@ -120,6 +125,21 @@ static bool setOnlyAccessesInaccessibleMemOrArgMem(Function &F) {
return true;
}

static bool setOnlyWritesErrnoMemory(Function &F) {
if (!setMemoryEffects(F, MemoryEffects::errnoMemOnly(ModRefInfo::Mod)))
return false;
++NumWriteErrnoMemOnly;
return true;
}

static bool setOnlyWritesArgMemOrErrnoMem(Function &F) {
if (!setMemoryEffects(F, MemoryEffects::argumentOrErrnoMemOnly(
ModRefInfo::Mod, ModRefInfo::Mod)))
return false;
++NumWriteArgumentMemOrErrnoMemOnly;
return true;
}

static bool setDoesNotThrow(Function &F) {
if (F.doesNotThrow())
return false;
Expand Down Expand Up @@ -1149,14 +1169,9 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_ldexp:
case LibFunc_ldexpf:
case LibFunc_ldexpl:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can merge ldexp with the rest of the FP libcall list? Should also be able to set doesNotThrow and setDoesNotFreeMemory on it...

Changed |= setOnlyWritesErrnoMemory(F);
Changed |= setWillReturn(F);
break;
case LibFunc_remquo:
case LibFunc_remquof:
case LibFunc_remquol:
Changed |= setDoesNotCapture(F, 2);
[[fallthrough]];
case LibFunc_abs:
case LibFunc_acos:
case LibFunc_acosf:
case LibFunc_acosh:
Expand All @@ -1178,15 +1193,9 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_atanhf:
case LibFunc_atanhl:
case LibFunc_atanl:
case LibFunc_cbrt:
case LibFunc_cbrtf:
case LibFunc_cbrtl:
case LibFunc_ceil:
case LibFunc_ceilf:
case LibFunc_ceill:
case LibFunc_copysign:
case LibFunc_copysignf:
case LibFunc_copysignl:
case LibFunc_cos:
case LibFunc_cosh:
case LibFunc_coshf:
Expand All @@ -1210,37 +1219,15 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_expm1:
case LibFunc_expm1f:
case LibFunc_expm1l:
case LibFunc_fabs:
case LibFunc_fabsf:
case LibFunc_fabsl:
case LibFunc_fdim:
case LibFunc_fdiml:
case LibFunc_fdimf:
case LibFunc_ffs:
case LibFunc_ffsl:
case LibFunc_ffsll:
case LibFunc_floor:
case LibFunc_floorf:
case LibFunc_floorl:
case LibFunc_fls:
case LibFunc_flsl:
case LibFunc_flsll:
case LibFunc_fmax:
case LibFunc_fmaxf:
case LibFunc_fmaxl:
case LibFunc_fmin:
case LibFunc_fminf:
case LibFunc_fminl:
case LibFunc_fmod:
case LibFunc_fmodf:
case LibFunc_fmodl:
case LibFunc_hypot:
case LibFunc_hypotf:
case LibFunc_hypotl:
case LibFunc_isascii:
case LibFunc_isdigit:
case LibFunc_labs:
case LibFunc_llabs:
case LibFunc_log:
case LibFunc_log10:
case LibFunc_log10f:
Expand All @@ -1259,9 +1246,6 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_ilogbl:
case LibFunc_logf:
case LibFunc_logl:
case LibFunc_nearbyint:
case LibFunc_nearbyintf:
case LibFunc_nearbyintl:
case LibFunc_pow:
case LibFunc_powf:
case LibFunc_powl:
Expand Down Expand Up @@ -1298,26 +1282,68 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
case LibFunc_tanhf:
case LibFunc_tanhl:
case LibFunc_tanl:
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotFreeMemory(F);
Changed |= setWillReturn(F);
Changed |= setOnlyWritesErrnoMemory(F);
break;
case LibFunc_abs:
case LibFunc_cbrt:
case LibFunc_cbrtf:
case LibFunc_cbrtl:
case LibFunc_copysign:
case LibFunc_copysignf:
case LibFunc_copysignl:
case LibFunc_fabs:
case LibFunc_fabsf:
case LibFunc_fabsl:
case LibFunc_ffs:
case LibFunc_ffsl:
case LibFunc_ffsll:
case LibFunc_floor:
case LibFunc_floorf:
case LibFunc_floorl:
case LibFunc_fls:
case LibFunc_flsl:
case LibFunc_flsll:
case LibFunc_fmax:
case LibFunc_fmaxf:
case LibFunc_fmaxl:
case LibFunc_fmin:
case LibFunc_fminf:
case LibFunc_fminl:
case LibFunc_labs:
case LibFunc_llabs:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For all othe other ones, these should be setDoesNotAccessMemory, right? As they don't access ernno or anything else.

case LibFunc_nearbyint:
case LibFunc_nearbyintf:
case LibFunc_nearbyintl:
case LibFunc_toascii:
case LibFunc_trunc:
case LibFunc_truncf:
case LibFunc_truncl:
Changed |= setDoesNotAccessMemory(F);
[[fallthrough]];
case LibFunc_isascii:
case LibFunc_isdigit:
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotFreeMemory(F);
Changed |= setOnlyWritesMemory(F);
Changed |= setWillReturn(F);
break;
case LibFunc_sincos:
case LibFunc_sincosf:
case LibFunc_sincosl:
Changed |= setDoesNotCapture(F, 1);
Changed |= setOnlyWritesMemory(F, 1);
[[fallthrough]];
case LibFunc_remquo:
case LibFunc_remquof:
case LibFunc_remquol:
Changed |= setDoesNotThrow(F);
Changed |= setDoesNotFreeMemory(F);
Changed |= setOnlyWritesMemory(F);
Changed |= setOnlyWritesMemory(F, 1);
Changed |= setOnlyWritesMemory(F, 2);
Changed |= setDoesNotCapture(F, 1);
Changed |= setDoesNotCapture(F, 2);
Changed |= setWillReturn(F);
Changed |= setOnlyWritesArgMemOrErrnoMem(F);
break;
default:
// FIXME: It'd be really nice to cover all the library functions we're
Expand Down
Loading
Loading