//===--- 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 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 &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 values, SmallVectorImpl &results); }; } // end namespace swift #endif