Files
swift-mirror/include/swift/SILOptimizer/Utils/ConstExpr.h
Marc Rasi 44d7cdd4e6 constant interpreter: basic integer operations
Implements a constant interpreter that can deal with basic integer operations.

Summary of the features that it includes:
* builtin integer values, and builtin integer insts
* struct and tuple values, and insts that construct and extract them (necessary to use stdlib integers)
* function referencing and application (necessary to call stdlib integer functions)
* error handling data structures and logic, for telling you why your value is not evaluatable
* metatype values (not necessary for integers, but it's only a few extra lines, so I thought it would be more trouble than it's worth to put them in a separate PR)
* conditional branches (ditto)
2018-11-26 14:27:10 -08:00

89 lines
3.1 KiB
C++

//===--- ConstExpr.h - Constant expression evaluator -----------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This defines an interface to evaluate Swift language level constant
// expressions. Its model is intended to be general and reasonably powerful,
// with the goal of standardization in a future version of Swift.
//
// Constant expressions are functions without side effects that take constant
// values and return constant values. These constants may be integer, and
// floating point values. We allow abstractions to be built out of fragile
// structs and tuples.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_SILOPTIMIZER_CONSTEXPR_H
#define SWIFT_SILOPTIMIZER_CONSTEXPR_H
#include "swift/Basic/LLVM.h"
#include "swift/Basic/SourceLoc.h"
#include "llvm/Support/Allocator.h"
namespace swift {
class ApplyInst;
class ASTContext;
class Operand;
class SILInstruction;
class SILModule;
class SILNode;
class SILValue;
class SymbolicValue;
enum class UnknownReason;
/// This class is the main entrypoint for evaluating constant expressions. It
/// also handles caching of previously computed constexpr results.
class ConstExprEvaluator {
/// We store arguments and result values for the cached constexpr calls we
/// have already analyzed in this ASTContext so that they are available even
/// after this ConstExprEvaluator is gone.
ASTContext &astContext;
/// 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(SILModule &m);
~ConstExprEvaluator();
ASTContext &getASTContext() { return astContext; }
void pushCallStack(SourceLoc loc) { callStack.push_back(loc); }
void popCallStack() {
assert(!callStack.empty());
callStack.pop_back();
}
const llvm::SmallVector<SourceLoc, 4> &getCallStack() { return callStack; }
// As SymbolicValue::getUnknown(), but handles passing the call stack and
// allocator.
SymbolicValue getUnknown(SILNode *node, UnknownReason reason);
/// Analyze the specified values to determine if they are constant values.
/// This is done in code that is not necessarily itself a constexpr
/// function. The results are added to the results list which is a parallel
/// structure to the input values.
///
/// TODO: Return information about which callees were found to be
/// constexprs, which would allow the caller to delete dead calls to them
/// that occur after after folding them.
void computeConstantValues(ArrayRef<SILValue> values,
SmallVectorImpl<SymbolicValue> &results);
};
} // end namespace swift
#endif