mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[const evaluator] Expose the step-wise constant evaluation mode
(also referred to as flow-sensitive mode) so that the evaluator can be used by clients to constant evaluate instructions in a SILFunction body one by one following the flow of control.
This commit is contained in:
@@ -26,17 +26,18 @@
|
||||
|
||||
#include "swift/Basic/LLVM.h"
|
||||
#include "swift/Basic/SourceLoc.h"
|
||||
#include "swift/SIL/SILBasicBlock.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
|
||||
namespace swift {
|
||||
class ApplyInst;
|
||||
class ASTContext;
|
||||
class Operand;
|
||||
class SILInstruction;
|
||||
class SILFunction;
|
||||
class SILModule;
|
||||
class SILNode;
|
||||
class SILValue;
|
||||
class SymbolicValue;
|
||||
class SymbolicValueAllocator;
|
||||
class ConstExprFunctionState;
|
||||
enum class UnknownReason;
|
||||
|
||||
/// This class is the main entrypoint for evaluating constant expressions. It
|
||||
@@ -47,13 +48,14 @@ class ConstExprEvaluator {
|
||||
/// The current call stack, used for providing accurate diagnostics.
|
||||
llvm::SmallVector<SourceLoc, 4> callStack;
|
||||
|
||||
ConstExprEvaluator(const ConstExprEvaluator &) = delete;
|
||||
void operator=(const ConstExprEvaluator &) = delete;
|
||||
|
||||
public:
|
||||
explicit ConstExprEvaluator(SymbolicValueAllocator &alloc);
|
||||
~ConstExprEvaluator();
|
||||
|
||||
explicit ConstExprEvaluator(const ConstExprEvaluator &other);
|
||||
|
||||
SymbolicValueAllocator &getAllocator() { return allocator; }
|
||||
|
||||
void pushCallStack(SourceLoc loc) { callStack.push_back(loc); }
|
||||
@@ -81,5 +83,52 @@ public:
|
||||
SmallVectorImpl<SymbolicValue> &results);
|
||||
};
|
||||
|
||||
/// A constant-expression evaluator that can be used to step through a control
|
||||
/// flow graph (SILFunction body) by evaluating one instruction at a time.
|
||||
class ConstExprStepEvaluator {
|
||||
private:
|
||||
ConstExprEvaluator evaluator;
|
||||
|
||||
ConstExprFunctionState *internalState;
|
||||
|
||||
unsigned stepsEvaluated = 0;
|
||||
|
||||
/// Targets of branches that were visited. This is used to detect loops during
|
||||
/// evaluation.
|
||||
SmallPtrSet<SILBasicBlock *, 8> visitedBlocks;
|
||||
|
||||
Optional<SymbolicValue>
|
||||
incrementStepsAndCheckLimit(SILInstruction *inst,
|
||||
bool includeInInstructionLimit);
|
||||
|
||||
ConstExprStepEvaluator(const ConstExprEvaluator &) = delete;
|
||||
void operator=(const ConstExprEvaluator &) = delete;
|
||||
|
||||
public:
|
||||
/// Constructs a step evaluator given an allocator and a non-null pointer to a
|
||||
/// SILFunction.
|
||||
explicit ConstExprStepEvaluator(SymbolicValueAllocator &alloc,
|
||||
SILFunction *fun);
|
||||
~ConstExprStepEvaluator();
|
||||
|
||||
/// Evaluate an instruction in the current interpreter state.
|
||||
/// \param instI instruction to be evaluated in the current interpreter state.
|
||||
/// \returns a pair where the first and second elements are defined as
|
||||
/// follows:
|
||||
/// The first element is the iterator to the next instruction from where
|
||||
/// the evaluation can continue, if the evaluation is successful.
|
||||
/// Otherwise, it is None.
|
||||
///
|
||||
/// Second element is None, if the evaluation is successful.
|
||||
/// Otherwise, is an unknown symbolic value that contains the error.
|
||||
std::pair<Optional<SILBasicBlock::iterator>, Optional<SymbolicValue>>
|
||||
evaluate(SILBasicBlock::iterator instI,
|
||||
bool includeInInstructionLimit = true);
|
||||
|
||||
Optional<SymbolicValue> lookupConstValue(SILValue value);
|
||||
|
||||
bool isKnownFunction(SILFunction *fun);
|
||||
};
|
||||
|
||||
} // end namespace swift
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user