159 lines
4.4 KiB
C++
159 lines
4.4 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
#pragma once
|
|
|
|
#include "VectorVM.h"
|
|
#include "VectorVMTypes.h"
|
|
|
|
#define VVM_OP_CAT_XM_LIST \
|
|
VVM_OP_CAT_XM(Input) \
|
|
VVM_OP_CAT_XM(Output) \
|
|
VVM_OP_CAT_XM(Op) \
|
|
VVM_OP_CAT_XM(ExtFnCall) \
|
|
VVM_OP_CAT_XM(IndexGen) \
|
|
VVM_OP_CAT_XM(RWBuffer) \
|
|
VVM_OP_CAT_XM(Stat) \
|
|
VVM_OP_CAT_XM(Other)
|
|
|
|
#define VVM_OP_CAT_XM(Category, ...) Category,
|
|
enum class EVectorVMOpCategory : uint8 {
|
|
VVM_OP_CAT_XM_LIST
|
|
MAX
|
|
};
|
|
#undef VVM_OP_CAT_XM
|
|
|
|
static const EVectorVMOpCategory VVM_OP_CATEGORIES[] = {
|
|
#define VVM_OP_XM(op, cat, ...) EVectorVMOpCategory::cat,
|
|
VVM_OP_XM_LIST
|
|
#undef VVM_OP_XM
|
|
};
|
|
|
|
#if WITH_EDITORONLY_DATA
|
|
|
|
namespace VectorVM::Optimizer
|
|
{
|
|
|
|
enum
|
|
{
|
|
VVM_RT_TEMPREG,
|
|
VVM_RT_CONST,
|
|
VVM_RT_INPUT,
|
|
VVM_RT_OUTPUT,
|
|
VVM_RT_INVALID
|
|
};
|
|
|
|
struct FVectorVMOptimizerContext;
|
|
|
|
//prototypes for optimizer
|
|
typedef uint32 (VectorVMOptimizerErrorCallback) (FVectorVMOptimizerContext* OptimizeContext, uint32 ErrorFlags); //return new error flags
|
|
|
|
//Optimization
|
|
struct FVectorVMOptimizeInstruction
|
|
{
|
|
EVectorVMOp OpCode;
|
|
EVectorVMOpCategory OpCat;
|
|
uint32 PtrOffsetInOrigBytecode;
|
|
uint32 PtrOffsetInOptimizedBytecode;
|
|
int Index; //initial index. Instructions are moved around and removed and dependency chains are created based on index, so we need to store this.
|
|
int InsMergedIdx; //if not -1, then the instruction index that this is merged with. Instructions with a set InsMergedIdx are not written to the final bytecode
|
|
int OutputMergeIdx[2]; //if not -1 then this instruction writes directly to an output, not a temp register
|
|
uint16 RegPtrOffset;
|
|
int NumInputRegisters;
|
|
int NumOutputRegisters;
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
uint16 DataSetIdx;
|
|
uint16 InputIdx;
|
|
} Input;
|
|
struct
|
|
{
|
|
uint16 DataSetIdx;
|
|
uint16 DstRegIdx;
|
|
int MergeIdx; //if not -1 then this instruction index is merged with an output or an op, if it's -2 then it's already been taken care of
|
|
uint16 SerialIdx;
|
|
} Output;
|
|
struct
|
|
{
|
|
|
|
} Op;
|
|
struct
|
|
{
|
|
uint16 DataSetIdx;
|
|
} IndexGen;
|
|
struct
|
|
{
|
|
uint16 ExtFnIdx;
|
|
uint16 NumInputs;
|
|
uint16 NumOutputs;
|
|
} ExtFnCall;
|
|
struct
|
|
{
|
|
uint16 DataSetIdx;
|
|
} RWBuffer;
|
|
struct
|
|
{
|
|
uint16 ID;
|
|
} Stat;
|
|
struct
|
|
{
|
|
} Other;
|
|
};
|
|
};
|
|
|
|
enum EVectorVMOptimizeError
|
|
{
|
|
VVMOptErr_OutOfMemory = 1 << 0,
|
|
VVMOptErr_Overflow = 1 << 1,
|
|
VVMOptErr_Bytecode = 1 << 2,
|
|
VVMOptErr_RegisterUsage = 1 << 3,
|
|
VVMOptErr_ConstRemap = 1 << 4,
|
|
VVMOptErr_Instructions = 1 << 5,
|
|
VVMOptErr_InputMergeBuffer = 1 << 6,
|
|
VVMOptErr_InstructionReOrder = 1 << 7,
|
|
VVMOptErr_SSARemap = 1 << 8,
|
|
VVMOptErr_OptimizedBytecode = 1 << 9,
|
|
VVMOptErr_ExternalFunction = 1 << 10,
|
|
VVMOptErr_RedundantInstruction = 1 << 11,
|
|
|
|
VVMOptErr_Fatal = 1 << 31
|
|
};
|
|
|
|
typedef void* (VectorVMReallocFn)(void* Ptr, size_t NumBytes, const char* Filename, int LineNumber);
|
|
typedef void (VectorVMFreeFn)(void* Ptr, const char* Filename, int LineNumber);
|
|
|
|
struct FVectorVMOptimizerContext : public VectorVM::Runtime::FVectorVMRuntimeContext
|
|
{
|
|
~FVectorVMOptimizerContext();
|
|
|
|
struct
|
|
{
|
|
VectorVMReallocFn * ReallocFn = nullptr;
|
|
VectorVMFreeFn * FreeFn = nullptr;
|
|
const char * ScriptName = nullptr;
|
|
} Init; //Set this stuff when calling Optimize()
|
|
|
|
struct
|
|
{
|
|
uint32 Flags = 0; //zero is good
|
|
uint32 Line = 0;
|
|
VectorVMOptimizerErrorCallback* CallbackFn = nullptr; //set this to get a callback whenever there's an error
|
|
} Error;
|
|
|
|
struct
|
|
{
|
|
FVectorVMOptimizeInstruction* Instructions = nullptr;
|
|
uint8* RegisterUsageType = nullptr;
|
|
uint16* RegisterUsageBuffer = nullptr;
|
|
uint16* SSARegisterUsageBuffer = nullptr;
|
|
uint16* ParentInstructionIdx = nullptr;
|
|
uint32 NumInstructions = 0;
|
|
uint32 NumInstructionsAlloced = 0;
|
|
uint32 NumRegistersUsed = 0;
|
|
} Intermediate; //these are freed and NULL after optimize() unless SaveIntermediateData is true when calling OptimizeVectorVMScript
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|