/*
 * Copyright 2018 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SKSL_JIT
#define SKSL_JIT

#ifdef SK_LLVM_AVAILABLE

#include "ir/SkSLAppendStage.h"
#include "ir/SkSLBinaryExpression.h"
#include "ir/SkSLBreakStatement.h"
#include "ir/SkSLContinueStatement.h"
#include "ir/SkSLExpression.h"
#include "ir/SkSLDoStatement.h"
#include "ir/SkSLForStatement.h"
#include "ir/SkSLFunctionCall.h"
#include "ir/SkSLFunctionDefinition.h"
#include "ir/SkSLIfStatement.h"
#include "ir/SkSLIndexExpression.h"
#include "ir/SkSLPrefixExpression.h"
#include "ir/SkSLPostfixExpression.h"
#include "ir/SkSLProgram.h"
#include "ir/SkSLReturnStatement.h"
#include "ir/SkSLStatement.h"
#include "ir/SkSLSwizzle.h"
#include "ir/SkSLTernaryExpression.h"
#include "ir/SkSLVarDeclarationsStatement.h"
#include "ir/SkSLVariableReference.h"
#include "ir/SkSLWhileStatement.h"

#include "llvm-c/Analysis.h"
#include "llvm-c/Core.h"
#include "llvm-c/OrcBindings.h"
#include "llvm-c/Support.h"
#include "llvm-c/Target.h"
#include "llvm-c/Transforms/PassManagerBuilder.h"
#include "llvm-c/Types.h"
#include <stack>

class SkRasterPipeline;

namespace SkSL {

/**
 * A just-in-time compiler for SkSL code which uses an LLVM backend. Only available when the
 * skia_llvm_path gn arg is set.
 *
 * Example of using SkSLJIT to set up an SkJumper pipeline stage:
 *
 * #ifdef SK_LLVM_AVAILABLE
 *   SkSL::Compiler compiler;
 *   SkSL::Program::Settings settings;
 *   std::unique_ptr<SkSL::Program> program = compiler.convertProgram(SkSL::Program::kCPU_Kind,
 *       "void swap(int x, int y, inout float4 color) {"
 *       "    color.rb = color.br;"
 *       "}",
 *       settings);
 *   if (!program) {
 *       printf("%s\n", compiler.errorText().c_str());
 *       abort();
 *   }
 *   SkSL::JIT& jit = *scratch->make<SkSL::JIT>(&compiler);
 *   std::unique_ptr<SkSL::JIT::Module> module = jit.compile(std::move(program));
 *   void* func = module->getJumperStage("swap");
 *   p->append(func, nullptr);
 * #endif
 */
class JIT {
    typedef int StackIndex;

public:
    class Module {
    public:
        /**
         * Returns the address of a symbol in the module.
         */
        void* getSymbol(const char* name);

        /**
         * Returns the address of a function as an SkJumper pipeline stage. The function must have
         * the signature void <name>(int x, int y, inout float4 color). The returned function will
         * have the correct signature to function as an SkJumper stage (meaning it will actually
         * have a different signature at runtime, accepting vector parameters and operating on
         * multiple pixels simultaneously as is normal for SkJumper stages).
         */
        void* getJumperStage(const char* name);

        ~Module() {
            LLVMOrcDisposeSharedModuleRef(fSharedModule);
        }

    private:
        Module(std::unique_ptr<Program> program,
               LLVMSharedModuleRef sharedModule,
               LLVMOrcJITStackRef jitStack)
        : fProgram(std::move(program))
        , fSharedModule(sharedModule)
        , fJITStack(jitStack) {}

        std::unique_ptr<Program> fProgram;
        LLVMSharedModuleRef fSharedModule;
        LLVMOrcJITStackRef fJITStack;

        friend class JIT;
    };

    JIT(Compiler* compiler);

    ~JIT();

    /**
     * Just-in-time compiles an SkSL program and returns the resulting Module. The JIT must not be
     * destroyed before all of its Modules are destroyed.
     */
    std::unique_ptr<Module> compile(std::unique_ptr<Program> program);

private:
    static constexpr int CHANNELS = 4;

    enum TypeKind {
        kFloat_TypeKind,
        kInt_TypeKind,
        kUInt_TypeKind,
        kBool_TypeKind
    };

    class LValue {
    public:
        virtual ~LValue() {}

        virtual LLVMValueRef load(LLVMBuilderRef builder) = 0;

        virtual void store(LLVMBuilderRef builder, LLVMValueRef value) = 0;
    };

    void addBuiltinFunction(const char* ourName, const char* realName, LLVMTypeRef returnType,
                            std::vector<LLVMTypeRef> parameters);

    void loadBuiltinFunctions();

    void setBlock(LLVMBuilderRef builder, LLVMBasicBlockRef block);

    LLVMTypeRef getType(const Type& type);

    TypeKind typeKind(const Type& type);

    std::unique_ptr<LValue> getLValue(LLVMBuilderRef builder, const Expression& expr);

    void vectorize(LLVMBuilderRef builder, LLVMValueRef* value, int columns);

    void vectorize(LLVMBuilderRef builder, const BinaryExpression& b, LLVMValueRef* left,
                   LLVMValueRef* right);

    LLVMValueRef compileBinary(LLVMBuilderRef builder, const BinaryExpression& b);

    LLVMValueRef compileConstructor(LLVMBuilderRef builder, const Constructor& c);

    LLVMValueRef compileFunctionCall(LLVMBuilderRef builder, const FunctionCall& fc);

    LLVMValueRef compileIndex(LLVMBuilderRef builder, const IndexExpression& v);

    LLVMValueRef compilePostfix(LLVMBuilderRef builder, const PostfixExpression& p);

    LLVMValueRef compilePrefix(LLVMBuilderRef builder, const PrefixExpression& p);

    LLVMValueRef compileSwizzle(LLVMBuilderRef builder, const Swizzle& s);

    LLVMValueRef compileVariableReference(LLVMBuilderRef builder, const VariableReference& v);

    LLVMValueRef compileTernary(LLVMBuilderRef builder, const TernaryExpression& t);

    LLVMValueRef compileExpression(LLVMBuilderRef builder, const Expression& expr);

    void appendStage(LLVMBuilderRef builder, const AppendStage& a);

    void compileBlock(LLVMBuilderRef builder, const Block& block);

    void compileBreak(LLVMBuilderRef builder, const BreakStatement& b);

    void compileContinue(LLVMBuilderRef builder, const ContinueStatement& c);

    void compileDo(LLVMBuilderRef builder, const DoStatement& d);

    void compileFor(LLVMBuilderRef builder, const ForStatement& f);

    void compileIf(LLVMBuilderRef builder, const IfStatement& i);

    void compileReturn(LLVMBuilderRef builder, const ReturnStatement& r);

    void compileVarDeclarations(LLVMBuilderRef builder, const VarDeclarationsStatement& decls);

    void compileWhile(LLVMBuilderRef builder, const WhileStatement& w);

    void compileStatement(LLVMBuilderRef builder, const Statement& stmt);

    // The "Vector" variants of functions attempt to compile a given expression or statement as part
    // of a vectorized SkJumper stage function - that is, with r, g, b, and a each being vectors of
    // fVectorCount floats. So a statement like "color.r = 0;" looks like it modifies a single
    // channel of a single pixel, but the compiled code will actually modify the red channel of
    // fVectorCount pixels at once.
    //
    // As not everything can be vectorized, these calls return a bool to indicate whether they were
    // successful. If anything anywhere in the function cannot be vectorized, the JIT will fall back
    // to looping over the pixels instead.
    //
    // Since we process multiple pixels at once, and each pixel consists of multiple color channels,
    // expressions may effectively result in a vector-of-vectors. We produce zero to four outputs
    // when compiling expression, each of which is a vector, so that e.g. float2(1, 0) actually
    // produces two vectors, one containing all 1s, the other all 0s. The out parameter always
    // allows for 4 channels, but the functions produce 0 to 4 channels depending on the type they
    // are operating on. Thus evaluating "color.rgb" actually fills in out[0] through out[2],
    // leaving out[3] uninitialized.
    // As the number of outputs can be inferred from the type of the expression, it is not
    // explicitly signalled anywhere.
    bool compileVectorBinary(LLVMBuilderRef builder, const BinaryExpression& b,
                             LLVMValueRef out[CHANNELS]);

    bool compileVectorConstructor(LLVMBuilderRef builder, const Constructor& c,
                                  LLVMValueRef out[CHANNELS]);

    bool compileVectorFloatLiteral(LLVMBuilderRef builder, const FloatLiteral& f,
                                   LLVMValueRef out[CHANNELS]);

    bool compileVectorSwizzle(LLVMBuilderRef builder, const Swizzle& s,
                              LLVMValueRef out[CHANNELS]);

    bool compileVectorVariableReference(LLVMBuilderRef builder, const VariableReference& v,
                                        LLVMValueRef out[CHANNELS]);

    bool compileVectorExpression(LLVMBuilderRef builder, const Expression& expr,
                                 LLVMValueRef out[CHANNELS]);

    bool getVectorLValue(LLVMBuilderRef builder, const Expression& e, LLVMValueRef out[CHANNELS]);

    /**
     * Evaluates the left and right operands of a binary operation, promoting one of them to a
     * vector if necessary to make the types match.
     */
    bool getVectorBinaryOperands(LLVMBuilderRef builder, const Expression& left,
                                 LLVMValueRef outLeft[CHANNELS], const Expression& right,
                                 LLVMValueRef outRight[CHANNELS]);

    bool compileVectorStatement(LLVMBuilderRef builder, const Statement& stmt);

    /**
     * Returns true if this function has the signature void(int, int, inout float4) and thus can be
     * used as an SkJumper stage.
     */
    bool hasStageSignature(const FunctionDeclaration& f);

    /**
     * Attempts to compile a vectorized stage function, returning true on success. A stage function
     * of e.g. "color.r = 0;" will produce code which sets the entire red vector to zeros in a
     * single instruction, thus calculating several pixels at once.
     */
    bool compileStageFunctionVector(const FunctionDefinition& f, LLVMValueRef newFunc);

    /**
     * Fallback function which loops over the pixels, for when vectorization fails. A stage function
     * of e.g. "color.r = 0;" will produce a loop which iterates over the entries in the red vector,
     * setting each one to zero individually.
     */
    void compileStageFunctionLoop(const FunctionDefinition& f, LLVMValueRef newFunc);

    /**
     * Called when compiling a function which has the signature of an SkJumper stage. Produces a
     * version of the function which can be plugged into SkJumper (thus having a signature which
     * accepts four vectors, one for each color channel, containing the color data of multiple
     * pixels at once). To go from SkSL code which operates on a single pixel at a time to CPU code
     * which operates on multiple pixels at once, the code is either vectorized using
     * compileStageFunctionVector or wrapped in a loop using compileStageFunctionLoop.
     */
    LLVMValueRef compileStageFunction(const FunctionDefinition& f);

    /**
     * Compiles an SkSL function to an LLVM function. If the function has the signature of an
     * SkJumper stage, it will *also* be compiled by compileStageFunction, resulting in both a stage
     * and non-stage version of the function.
     */
    LLVMValueRef compileFunction(const FunctionDefinition& f);

    void createModule();

    void optimize();

    bool isColorRef(const Expression& expr);

    static uint64_t resolveSymbol(const char* name, JIT* jit);

    const char* fCPU;
    int fVectorCount;
    Compiler& fCompiler;
    std::unique_ptr<Program> fProgram;
    LLVMContextRef fContext;
    LLVMModuleRef fModule;
    LLVMSharedModuleRef fSharedModule;
    LLVMOrcJITStackRef fJITStack;
    LLVMValueRef fCurrentFunction;
    LLVMBasicBlockRef fAllocaBlock;
    LLVMBasicBlockRef fCurrentBlock;
    LLVMTypeRef fVoidType;
    LLVMTypeRef fInt1Type;
    LLVMTypeRef fInt8Type;
    LLVMTypeRef fInt8PtrType;
    LLVMTypeRef fInt32Type;
    LLVMTypeRef fInt32VectorType;
    LLVMTypeRef fInt32Vector2Type;
    LLVMTypeRef fInt32Vector3Type;
    LLVMTypeRef fInt32Vector4Type;
    LLVMTypeRef fInt64Type;
    LLVMTypeRef fSizeTType;
    LLVMTypeRef fFloat32Type;
    LLVMTypeRef fFloat32VectorType;
    LLVMTypeRef fFloat32Vector2Type;
    LLVMTypeRef fFloat32Vector3Type;
    LLVMTypeRef fFloat32Vector4Type;
    // Our SkSL stage functions have a single float4 for color, but the actual SkJumper stage
    // function has four separate vectors, one for each channel. These four values are references to
    // the red, green, blue, and alpha vectors respectively.
    LLVMValueRef fChannels[CHANNELS];
    // when processing a stage function, this points to the SkSL color parameter (an inout float4)
    const Variable* fColorParam;
    std::map<const FunctionDeclaration*, LLVMValueRef> fFunctions;
    std::map<const Variable*, LLVMValueRef> fVariables;
    // LLVM function parameters are read-only, so when modifying function parameters we need to
    // first promote them to variables. This keeps track of which parameters have been promoted.
    std::set<const Variable*> fPromotedParameters;
    std::vector<LLVMBasicBlockRef> fBreakTarget;
    std::vector<LLVMBasicBlockRef> fContinueTarget;

    LLVMValueRef fAppendFunc;
    LLVMValueRef fAppendCallbackFunc;
    LLVMValueRef fDebugFunc;
};

} // namespace

#endif // SK_LLVM_AVAILABLE

#endif // SKSL_JIT
