mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
8443f06170
Introduce a pass which statically demotes some helpers from candidates
for inlining:
1) Helpers which are part of SCC on the callgraph.
2) Helpers which contains an `insertvalue`.
3) Helpers which _fail_ the `CriticalArguments` criterion.
A critical argument is defined starting from the critical operand
definition.
A critical operand is either the condition of a `switch` instruction or
the indices of a `getelementptr` instruction.
If the dataflow computing the the operand trace back to a formal
parameter of the function, that parameter will be considered critical
when attempting the inlining of the helper.
In case each condition is satisfied, the `revng.inline.policy` metadata
is attached to the function, so that it can be used at _inline_ time to
take the decision based on the critical arguments constantness.
The metadata is encoded as an `iN` integer with N = `arg_size() + 1`:
the extra most-significant bit is always zero so LLVM's signed-decimal
`iN` printer renders the value positively (avoiding e.g. `!{i2 -2}`).
The (de)serialisation primitives live in `revng/Support/IRHelpers.h`
as `serializeInliningPolicy` / `deserializeInliningPolicy` so the
runtime `revngFunctionIsolation` doesn't need to link the build-time
`revngHelperInliningAnalyses` to read the metadata back.
39 lines
1.4 KiB
C++
39 lines
1.4 KiB
C++
#pragma once
|
|
|
|
//
|
|
// This file is distributed under the MIT License. See LICENSE.md for details.
|
|
//
|
|
|
|
#include <optional>
|
|
|
|
#include "llvm/ADT/BitVector.h"
|
|
#include "llvm/IR/Function.h"
|
|
|
|
namespace DetectUninlinableHelpers {
|
|
|
|
/// \return `true` if `Pointer` addresses a `GlobalVariable` marked as
|
|
/// `constant`.
|
|
bool isPointerToConstantGlobal(const llvm::Value *Pointer);
|
|
|
|
/// Compute the set of *critical formal arguments* of `Helper`.
|
|
///
|
|
/// An operand of an instruction is *critical* when one of the following holds:
|
|
/// - it is the condition of a `switch` instruction;
|
|
/// - it is one of the index operands of a `getelementptr` instruction.
|
|
///
|
|
/// A *critical argument* of `Helper` is a formal parameter that flows into a
|
|
/// critical operand. The function performs a backward dataflow walk from every
|
|
/// critical operand and classifies as critical every formal parameter reached
|
|
/// during the walk.
|
|
///
|
|
/// \return One of three possible values:
|
|
/// - `std::nullopt`: the helper cannot be inlined at any call site (the
|
|
/// backward walk reaches a `load` from runtime memory).
|
|
/// - empty `BitVector`: the helper can always be inlined.
|
|
/// - non-empty `BitVector`: the set of formal-parameter indices that must be
|
|
/// `isa<Constant>` at the call site for the helper to be inlinable.
|
|
std::optional<llvm::BitVector>
|
|
computeCriticalArgumentsFor(const llvm::Function &Helper);
|
|
|
|
} // namespace DetectUninlinableHelpers
|