Files
UnrealEngine/Engine/Source/Runtime/VectorVM/Private/VectorVMEditor.h
2025-05-18 13:04:45 +08:00

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