pub enum Purity {
Const,
LoopingConst,
Pure,
LoopingPure,
Opaque,
}Expand description
What a call can do.
Five, because there are two questions with two answers each and then everything else. Does the
result depend on memory, does the call come back, and if either answer is not known then the
call is Purity::Opaque and no pass may assume anything at all.
Variants§
Const
Reads no memory, writes none, and comes back. __attribute__((const)), GCC’s ECF_CONST.
LoopingConst
Reads no memory and writes none, and may not come back. GCC’s ECF_CONST together with
ECF_LOOPING_CONST_OR_PURE.
Pure
Reads memory, writes none, and comes back. __attribute__((pure)), GCC’s ECF_PURE.
LoopingPure
Reads memory, writes none, and may not come back.
Opaque
Anything, which is what a call is until something says otherwise.
Implementations§
Source§impl Purity
impl Purity
Sourcepub const fn reads_memory(self) -> bool
pub const fn reads_memory(self) -> bool
Whether the call may read memory the caller cares about.
Sourcepub const fn writes_memory(self) -> bool
pub const fn writes_memory(self) -> bool
Whether the call may write memory.
Only an opaque call may. That is what the other four have in common and it is most of what makes them worth telling apart from the rest.
Sourcepub const fn terminates(self) -> bool
pub const fn terminates(self) -> bool
Whether control is known to come back from the call.
Not known and known not to are the same answer here, because both of them stop the same
transformations. Which of the two it is belongs to noreturn, which is an attribute on the
function rather than a level of this.
Sourcepub const fn depends_only_on_arguments(self) -> bool
pub const fn depends_only_on_arguments(self) -> bool
Whether the result is a function of the arguments and nothing else.
This is what lets two calls with the same arguments become one call with no question asked
about what happened to memory in between. A Purity::Pure call can be folded the same way
when the caller can show nothing wrote memory between the two, which is a question for the
alias analysis and not for this.
Sourcepub const fn can_be_deleted_when_unused(self) -> bool
pub const fn can_be_deleted_when_unused(self) -> bool
Whether a call whose result nothing reads may be removed.
Both halves are needed. A call that writes memory does something even when its result is thrown away, and a call that may not come back does something by not coming back, which is why the looping levels exist at all.
Sourcepub const fn stronger(self, other: Self) -> Self
pub const fn stronger(self, other: Self) -> Self
The strongest thing true of both, for a caller that has two sources and believes each.
Purity::Opaque is nothing known, so it gives way to whatever the other source says. Two
sources that each know half give the whole: a declaration saying the result comes out of the
arguments and an analysis saying the loop inside terminates add up to Purity::Const.