mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 03:28:20 +02:00
3728 lines
No EOL
93 KiB
C++
3728 lines
No EOL
93 KiB
C++
#include "BeIRCodeGen.h"
|
|
#include "../Compiler/BfIRCodeGen.h"
|
|
#include "BeDbgModule.h"
|
|
#include "BeefySysLib/util/BeefPerf.h"
|
|
|
|
#include "BeefySysLib/util/AllocDebug.h"
|
|
#include "BeefySysLib/util/Hash.h"
|
|
#include "BeModule.h"
|
|
#include "BeContext.h"
|
|
#include "../Compiler/CeMachine.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define BE_EXTRA_CHECKS
|
|
#endif
|
|
|
|
USING_NS_BF;
|
|
|
|
//#define CODEGEN_TRACK
|
|
|
|
#ifdef CODEGEN_TRACK
|
|
#include "../Compiler/MemReporter.h"
|
|
MemReporter gBEMemReporter;
|
|
CritSect gBEMemReporterCritSect;
|
|
int gBEMemReporterSize = 0;
|
|
|
|
#define BE_MEM_START \
|
|
int startPos = mStream->GetReadPos();
|
|
|
|
#define BE_MEM_END(name) \
|
|
gBEMemReporter.Add(name, mStream->GetReadPos() - startPos);
|
|
|
|
static const char* gIRCmdNames[] =
|
|
{
|
|
"Module_Start",
|
|
"Module_SetTargetTriple",
|
|
"Module_AddModuleFlag",
|
|
"WriteIR",
|
|
"SetType",
|
|
"SetInstType",
|
|
"PrimitiveType",
|
|
"CreateStruct",
|
|
"StructSetBody",
|
|
"Type",
|
|
"TypeInst",
|
|
"TypeInstPtr",
|
|
"GetType",
|
|
"GetPointerToFuncType",
|
|
"GetPointerToType",
|
|
"GetSizedArrayType",
|
|
"CreateConstStruct",
|
|
"CreateConstStructZero",
|
|
"CreateConstArray",
|
|
"CreateConstString",
|
|
"SetName",
|
|
"CreateUndefValue",
|
|
"NumericCast",
|
|
"CmpEQ",
|
|
"CmpNE",
|
|
"CmpSLT",
|
|
"CmpULT",
|
|
"CmpSLE",
|
|
"CmpULE",
|
|
"CmpSGT",
|
|
"CmpUGT",
|
|
"CmpSGE",
|
|
"CmpUGE",
|
|
"Add",
|
|
"Sub",
|
|
"Mul",
|
|
"SDiv",
|
|
"UDiv",
|
|
"SRem",
|
|
"URem",
|
|
"And",
|
|
"Or",
|
|
"Xor",
|
|
"Shl",
|
|
"AShr",
|
|
"LShr",
|
|
"Neg",
|
|
"Not",
|
|
"BitCast",
|
|
"PtrToInt",
|
|
"IntToPtr",
|
|
"InboundsGEP1_32",
|
|
"InboundsGEP2_32",
|
|
"InBoundsGEP1",
|
|
"InBoundsGEP2",
|
|
"IsNull",
|
|
"IsNotNull",
|
|
"ExtractValue",
|
|
"InsertValue",
|
|
"Alloca",
|
|
"AllocaArray",
|
|
"SetAllocaAlignment",
|
|
"SetAllocaNoChkStkHint",
|
|
"SetAllocaForceMem",
|
|
"LifetimeStart",
|
|
"LifetimeEnd",
|
|
"LifetimeExtend",
|
|
"ValueScopeStart",
|
|
"ValueScopeRetain",
|
|
"ValueScopeSoftEnd",
|
|
"ValueScopeHardEnd",
|
|
"Load",
|
|
"AlignedLoad",
|
|
"Store",
|
|
"AlignedStore",
|
|
"MemSet",
|
|
"Fence",
|
|
"StackSave",
|
|
"StackRestore",
|
|
"GlobalVariable",
|
|
"GlobalVar_SetUnnamedAddr",
|
|
"GlobalVar_SetInitializer",
|
|
"GlobalVar_SetAlignment",
|
|
"GlobalStringPtr",
|
|
"CreateBlock",
|
|
"MaybeChainNewBlock",
|
|
"AddBlock",
|
|
"DropBlocks",
|
|
"MergeBlockDown",
|
|
"SetInsertPoint",
|
|
"SetInsertPointAtStart",
|
|
"EraseFromParent",
|
|
"DeleteBlock",
|
|
"EraseInstFromParent",
|
|
"CreateBr",
|
|
"CreateBr_NoCollapse",
|
|
"CreateCondBr",
|
|
"MoveBlockToEnd",
|
|
"CreateSwitch",
|
|
"AddSwitchCase",
|
|
"SetSwitchDefaultDest",
|
|
"CreatePhi",
|
|
"AddPhiIncoming",
|
|
"GetIntrinsic",
|
|
"CreateFunctionType",
|
|
"CreateFunction",
|
|
"EnsureFunctionPatchable",
|
|
"RemapBindFunction",
|
|
"SetActiveFunction",
|
|
"CreateCall",
|
|
"SetCallCallingConv",
|
|
"SetFuncCallingConv",
|
|
"SetTailCall",
|
|
"SetCallAttribute",
|
|
"CreateRet",
|
|
"CreateRetVoid",
|
|
"CreateUnreachable",
|
|
"Call_AddAttribute",
|
|
"Call_AddAttribute1",
|
|
"Func_AddAttribute",
|
|
"Func_AddAttribute1",
|
|
"Func_SetParamName",
|
|
"Func_DeleteBody",
|
|
"Func_EraseFromParent",
|
|
"Func_SetLinkage",
|
|
"SaveDebugLocation",
|
|
"RestoreDebugLocation",
|
|
"ClearDebugLocation",
|
|
"ClearDebugLocationInst",
|
|
"UpdateDebugLocation",
|
|
"SetCurrentDebugLocation",
|
|
"Nop",
|
|
"EnsureInstructionAt",
|
|
"StatementStart",
|
|
"ObjectAccessCheck",
|
|
"DbgInit",
|
|
"DbgFinalize",
|
|
"DbgCreateCompileUnit",
|
|
"DbgCreateFile",
|
|
"ConstValueI64",
|
|
"DbgGetCurrentLocation",
|
|
"DbgSetType",
|
|
"DbgSetInstType",
|
|
"DbgGetType",
|
|
"DbgGetTypeInst",
|
|
"DbgTrackDITypes",
|
|
"DbgCreateNamespace",
|
|
"DbgCreateImportedModule",
|
|
"DbgCreateBasicType",
|
|
"DbgCreateStructType",
|
|
"DbgCreateEnumerationType",
|
|
"DbgCreatePointerType",
|
|
"DbgCreateReferenceType",
|
|
"DbgCreateConstType",
|
|
"DbgCreateArtificialType",
|
|
"DbgCreateArrayType",
|
|
"DbgCreateReplaceableCompositeType",
|
|
"DbgCreateForwardDecl",
|
|
"DbgCreateSizedForwardDecl",
|
|
"BeIRCmd_DbgSetTypeSize",
|
|
"DbgReplaceAllUses",
|
|
"DbgDeleteTemporary",
|
|
"DbgMakePermanent",
|
|
"CreateEnumerator",
|
|
"DbgCreateMemberType",
|
|
"DbgStaticCreateMemberType",
|
|
"DbgCreateInheritance",
|
|
"DbgCreateMethod",
|
|
"DbgCreateFunction",
|
|
"DbgCreateParameterVariable",
|
|
"DbgCreateSubroutineType",
|
|
"DbgCreateAutoVariable",
|
|
"DbgInsertValueIntrinsic",
|
|
"DbgInsertDeclare",
|
|
"DbgLifetimeEnd",
|
|
"DbgCreateGlobalVariable",
|
|
"DbgCreateLexicalBlock",
|
|
"DbgCreateLexicalBlockFile",
|
|
"DbgCreateAnnotation"
|
|
};
|
|
|
|
BF_STATIC_ASSERT(BF_ARRAY_COUNT(gIRCmdNames) == BfIRCmd_COUNT);
|
|
|
|
#else
|
|
#define BE_MEM_START
|
|
#define BE_MEM_END(name)
|
|
#endif
|
|
|
|
#pragma warning(disable:4146)
|
|
|
|
#define CMD_PARAM(ty, name) ty name; Read(name);
|
|
|
|
BeIRCodeGen::BeIRCodeGen()
|
|
{
|
|
mBfIRBuilder = NULL;
|
|
mStream = NULL;
|
|
mActiveFunction = NULL;
|
|
mBeContext = NULL;
|
|
mBeModule = NULL;
|
|
mHasDebugLoc = false;
|
|
mDebugging = false;
|
|
mCmdCount = 0;
|
|
}
|
|
|
|
BeIRCodeGen::~BeIRCodeGen()
|
|
{
|
|
BF_ASSERT(mSavedDebugLocs.size() == 0);
|
|
delete mBeModule;
|
|
delete mBeContext;
|
|
delete mStream;
|
|
}
|
|
|
|
void BeIRCodeGen::Hash(BeHashContext& hashCtx)
|
|
{
|
|
// if (mBeModule->mModuleName == "IDE_IDEApp")
|
|
// {
|
|
// hashCtx.mDbgViz = true;
|
|
// NOP;
|
|
// }
|
|
|
|
hashCtx.Mixin(mPtrSize);
|
|
hashCtx.Mixin(mIsOptimized);
|
|
if (mBeModule != NULL)
|
|
mBeModule->Hash(hashCtx);
|
|
|
|
Array<BeStructType*> structHashList;
|
|
|
|
for (auto beType : mBeContext->mTypes)
|
|
{
|
|
if (!beType->IsStruct())
|
|
continue;
|
|
auto beStructType = (BeStructType*)beType;
|
|
if (beStructType->mHashId != -1)
|
|
continue;
|
|
structHashList.Add(beStructType);
|
|
}
|
|
|
|
structHashList.Sort([](BeStructType* lhs, BeStructType* rhs)
|
|
{
|
|
return lhs->mName < rhs->mName;
|
|
});
|
|
|
|
for (auto beStructType : structHashList)
|
|
{
|
|
beStructType->HashReference(hashCtx);
|
|
}
|
|
}
|
|
|
|
bool BeIRCodeGen::IsModuleEmpty()
|
|
{
|
|
if (!mBeModule->mFunctions.IsEmpty())
|
|
return false;
|
|
if (!mBeModule->mGlobalVariables.IsEmpty())
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
void BeIRCodeGen::FatalError(const StringImpl& err)
|
|
{
|
|
String failStr = "Fatal Error in Module: ";
|
|
if (mBeModule != NULL)
|
|
failStr += mBeModule->mModuleName;
|
|
failStr += "\n";
|
|
if (mBeModule != NULL)
|
|
{
|
|
BeDumpContext dumpCtx;
|
|
|
|
if (mActiveFunction != NULL)
|
|
{
|
|
failStr += "Function: ";
|
|
failStr += mActiveFunction->mName;
|
|
failStr += "\n";
|
|
}
|
|
|
|
if (mBeModule->mCurDbgLoc != NULL)
|
|
{
|
|
failStr += "DbgLoc: ";
|
|
dumpCtx.ToString(failStr, mBeModule->mCurDbgLoc);
|
|
failStr += "\n";
|
|
}
|
|
}
|
|
|
|
failStr += err;
|
|
BF_FATAL(failStr);
|
|
}
|
|
|
|
void BeIRCodeGen::NotImpl()
|
|
{
|
|
BF_FATAL("Not implemented");
|
|
}
|
|
|
|
BeType* BeIRCodeGen::GetBeType(BfTypeCode typeCode, bool& isSigned)
|
|
{
|
|
isSigned = false;
|
|
BeTypeCode beTypeCode = BeTypeCode_None;
|
|
switch (typeCode)
|
|
{
|
|
case BfTypeCode_None:
|
|
beTypeCode = BeTypeCode_None;
|
|
break;
|
|
case BfTypeCode_NullPtr:
|
|
beTypeCode = BeTypeCode_NullPtr;
|
|
break;
|
|
case BfTypeCode_Boolean:
|
|
beTypeCode = BeTypeCode_Boolean;
|
|
break;
|
|
case BfTypeCode_Int8:
|
|
isSigned = true;
|
|
beTypeCode = BeTypeCode_Int8;
|
|
break;
|
|
case BfTypeCode_UInt8:
|
|
case BfTypeCode_Char8:
|
|
beTypeCode = BeTypeCode_Int8;
|
|
break;
|
|
case BfTypeCode_Int16:
|
|
isSigned = true;
|
|
beTypeCode = BeTypeCode_Int16;
|
|
break;
|
|
case BfTypeCode_Char16:
|
|
case BfTypeCode_UInt16:
|
|
beTypeCode = BeTypeCode_Int16;
|
|
break;
|
|
case BfTypeCode_Int32:
|
|
isSigned = true;
|
|
beTypeCode = BeTypeCode_Int32;
|
|
break;
|
|
case BfTypeCode_UInt32:
|
|
case BfTypeCode_Char32:
|
|
beTypeCode = BeTypeCode_Int32;
|
|
break;
|
|
case BfTypeCode_Int64:
|
|
isSigned = true;
|
|
beTypeCode = BeTypeCode_Int64;
|
|
break;
|
|
case BfTypeCode_UInt64:
|
|
beTypeCode = BeTypeCode_Int64;
|
|
break;
|
|
case BfTypeCode_IntPtr:
|
|
BF_FATAL("Illegal");
|
|
/*isSigned = true;
|
|
if (mModule->mSystem->mPtrSize == 4)
|
|
return llvm::Type::getInt32Ty(*mLLVMContext);
|
|
else
|
|
return llvm::Type::getInt64Ty(*mLLVMContext);*/
|
|
case BfTypeCode_UIntPtr:
|
|
BF_FATAL("Illegal");
|
|
/*if (mModule->mSystem->mPtrSize == 4)
|
|
return llvm::Type::getInt32Ty(*mLLVMContext);
|
|
else
|
|
return llvm::Type::getInt64Ty(*mLLVMContext);*/
|
|
case BfTypeCode_Float:
|
|
isSigned = true;
|
|
beTypeCode = BeTypeCode_Float;
|
|
break;
|
|
case BfTypeCode_Double:
|
|
isSigned = true;
|
|
beTypeCode = BeTypeCode_Double;
|
|
break;
|
|
}
|
|
|
|
return mBeContext->GetPrimitiveType(beTypeCode);
|
|
}
|
|
|
|
BeIRTypeEntry& BeIRCodeGen::GetTypeEntry(int typeId)
|
|
{
|
|
BeIRTypeEntry& typeEntry = mTypes[typeId];
|
|
if (typeEntry.mTypeId == -1)
|
|
typeEntry.mTypeId = typeId;
|
|
return typeEntry;
|
|
}
|
|
|
|
void BeIRCodeGen::FixValues(BeStructType* structType, CmdParamVec<BeValue*>& values)
|
|
{
|
|
if (values.size() >= structType->mMembers.size())
|
|
return;
|
|
|
|
int readIdx = values.size() - 1;
|
|
values.resize(structType->mMembers.size());
|
|
for (int i = (int)values.size() - 1; i >= 0; i--)
|
|
{
|
|
if (mBeContext->AreTypesEqual(values[readIdx]->GetType(), structType->mMembers[i].mType))
|
|
{
|
|
values[i] = values[readIdx];
|
|
readIdx--;
|
|
}
|
|
else if (structType->mMembers[i].mType->IsSizedArray())
|
|
{
|
|
auto beConst = mBeModule->mAlloc.Alloc<BeConstant>();
|
|
beConst->mType = structType->mMembers[i].mType;
|
|
values[i] = beConst;
|
|
}
|
|
else
|
|
{
|
|
FatalError("Malformed structure values");
|
|
}
|
|
}
|
|
}
|
|
|
|
void BeIRCodeGen::Init(const BfSizedArray<uint8>& buffer)
|
|
{
|
|
BP_ZONE("BeIRCodeGen::Init");
|
|
|
|
BF_ASSERT(mStream == NULL);
|
|
mStream = new ChunkedDataBuffer();
|
|
mStream->InitFlatRef(buffer.mVals, buffer.mSize);
|
|
|
|
#ifdef CODEGEN_TRACK
|
|
AutoCrit autoCrit(gBEMemReporterCritSect);
|
|
AutoMemReporter autoMemReporter(&gBEMemReporter, "BeIRCodeGen");
|
|
#endif
|
|
|
|
//
|
|
{
|
|
BP_ZONE("BeIRCodeGen::ProcessBfIRData.HandleNextCmds");
|
|
while (mStream->GetReadPos() < buffer.mSize)
|
|
{
|
|
if (mFailed)
|
|
break;
|
|
HandleNextCmd();
|
|
}
|
|
}
|
|
|
|
BF_ASSERT((mFailed) || (mStream->GetReadPos() == buffer.mSize));
|
|
}
|
|
|
|
void BeIRCodeGen::Process()
|
|
{
|
|
BP_ZONE("BeIRCodeGen::process");
|
|
|
|
//mDebugging |= ((mBeModule->mDbgModule != NULL) && (mBeModule->mDbgModule->mFileName == "ClassQ"));
|
|
if (mDebugging)
|
|
{
|
|
String dbgStr;
|
|
dbgStr = mBeModule->ToString();
|
|
OutputDebugStr(dbgStr);
|
|
}
|
|
|
|
mBeModule->DoInlining();
|
|
|
|
if (mDebugging)
|
|
{
|
|
String dbgStr = "-------------- AFTER INLINING --------------\n";
|
|
dbgStr += mBeModule->ToString();
|
|
OutputDebugStr(dbgStr);
|
|
}
|
|
}
|
|
|
|
void BeIRCodeGen::ProcessBfIRData(const BfSizedArray<uint8>& buffer)
|
|
{
|
|
BP_ZONE("BeIRCodeGen::ProcessBfIRData");
|
|
|
|
Init(buffer);
|
|
Process();
|
|
}
|
|
|
|
BfTypeCode BeIRCodeGen::GetTypeCode(BeType * type, bool isSigned)
|
|
{
|
|
switch (type->mTypeCode)
|
|
{
|
|
case BeTypeCode_Int8:
|
|
return (isSigned) ? BfTypeCode_Int8 : BfTypeCode_UInt8;
|
|
case BeTypeCode_Int16:
|
|
return (isSigned) ? BfTypeCode_Int16 : BfTypeCode_UInt16;
|
|
case BeTypeCode_Int32:
|
|
return (isSigned) ? BfTypeCode_Int32 : BfTypeCode_UInt32;
|
|
case BeTypeCode_Int64:
|
|
return (isSigned) ? BfTypeCode_Int64 : BfTypeCode_UInt64;
|
|
case BeTypeCode_Float:
|
|
return BfTypeCode_Float;
|
|
case BeTypeCode_Double:
|
|
return BfTypeCode_Double;
|
|
default:
|
|
return BfTypeCode_None;
|
|
}
|
|
}
|
|
|
|
void BeIRCodeGen::SetResult(int id, BeValue* value)
|
|
{
|
|
BeIRCodeGenEntry entry;
|
|
entry.mKind = BeIRCodeGenEntryKind_Value;
|
|
entry.mBeValue = value;
|
|
mResults.TryAdd(id, entry);
|
|
}
|
|
|
|
void BeIRCodeGen::SetResult(int id, BeType* type)
|
|
{
|
|
BeIRCodeGenEntry entry;
|
|
entry.mKind = BeIRCodeGenEntryKind_Type;
|
|
entry.mBeType = type;
|
|
mResults.TryAdd(id, entry);
|
|
}
|
|
|
|
void BeIRCodeGen::SetResult(int id, BeBlock* value)
|
|
{
|
|
BeIRCodeGenEntry entry;
|
|
entry.mKind = BeIRCodeGenEntryKind_Block;
|
|
entry.mBeBlock = value;
|
|
mResults.TryAdd(id, entry);
|
|
}
|
|
|
|
void BeIRCodeGen::SetResult(int id, BeMDNode* md)
|
|
{
|
|
BeIRCodeGenEntry entry;
|
|
entry.mKind = BeIRCodeGenEntryKind_Metadata;
|
|
entry.mBeMetadata = md;
|
|
mResults.TryAdd(id, entry);
|
|
}
|
|
|
|
int64 BeIRCodeGen::ReadSLEB128()
|
|
{
|
|
int64 val = 0;
|
|
int64 shift = 0;
|
|
uint8 byteVal;
|
|
do
|
|
{
|
|
byteVal = mStream->Read();
|
|
val |= ((int64)(byteVal & 0x7f)) << shift;
|
|
shift += 7;
|
|
} while (byteVal >= 128);
|
|
// Sign extend negative numbers.
|
|
if ((byteVal & 0x40) && (shift < 64))
|
|
val |= (-1ULL) << shift;
|
|
return val;
|
|
}
|
|
|
|
void BeIRCodeGen::Read(StringImpl& str)
|
|
{
|
|
BE_MEM_START;
|
|
int len = (int)ReadSLEB128();
|
|
str.Append('?', len);
|
|
mStream->Read((void*)str.c_str(), len);
|
|
BE_MEM_END("String");
|
|
}
|
|
|
|
void BeIRCodeGen::Read(int& i)
|
|
{
|
|
BE_MEM_START;
|
|
i = (int)ReadSLEB128();
|
|
BE_MEM_END("int");
|
|
}
|
|
|
|
void BeIRCodeGen::Read(int64& i)
|
|
{
|
|
BE_MEM_START;
|
|
i = ReadSLEB128();
|
|
BE_MEM_END("int64");
|
|
}
|
|
|
|
void BeIRCodeGen::Read(Val128& i)
|
|
{
|
|
i.mLow = (uint64)ReadSLEB128();
|
|
i.mHigh = (uint64)ReadSLEB128();
|
|
}
|
|
|
|
void BeIRCodeGen::Read(bool& val)
|
|
{
|
|
BE_MEM_START;
|
|
val = mStream->Read() != 0;
|
|
BE_MEM_END("bool");
|
|
}
|
|
|
|
void BeIRCodeGen::Read(int8& val)
|
|
{
|
|
val = mStream->Read();
|
|
}
|
|
|
|
void BeIRCodeGen::Read(BeIRTypeEntry*& type)
|
|
{
|
|
BE_MEM_START;
|
|
int typeId = (int)ReadSLEB128();
|
|
type = &GetTypeEntry(typeId);
|
|
BE_MEM_END("BeIRTypeEntry");
|
|
}
|
|
|
|
void BeIRCodeGen::Read(BeType*& beType)
|
|
{
|
|
BE_MEM_START;
|
|
|
|
BfIRType::TypeKind typeKind = (BfIRType::TypeKind)mStream->Read();
|
|
if (typeKind == BfIRType::TypeKind::TypeKind_None)
|
|
{
|
|
beType = NULL;
|
|
BE_MEM_END("BeType");
|
|
return;
|
|
}
|
|
|
|
if (typeKind == BfIRType::TypeKind::TypeKind_Stream)
|
|
{
|
|
int streamId = (int)ReadSLEB128();
|
|
if (streamId == -1)
|
|
{
|
|
beType = NULL;
|
|
BE_MEM_END("BeType");
|
|
return;
|
|
}
|
|
auto& result = mResults[streamId];
|
|
BF_ASSERT(result.mKind == BeIRCodeGenEntryKind_Type);
|
|
beType = result.mBeType;
|
|
BE_MEM_END("BeType");
|
|
return;
|
|
}
|
|
|
|
if (typeKind == BfIRType::TypeKind::TypeKind_SizedArray)
|
|
{
|
|
CMD_PARAM(BeType*, elementType);
|
|
CMD_PARAM(int, length);
|
|
beType = mBeContext->CreateSizedArrayType(elementType, length);
|
|
return;
|
|
}
|
|
|
|
int typeId = (int)ReadSLEB128();
|
|
|
|
if (typeKind == BfIRType::TypeKind::TypeKind_TypeCode)
|
|
{
|
|
bool isSigned = false;
|
|
beType = GetBeType((BfTypeCode)typeId, isSigned);
|
|
return;
|
|
}
|
|
|
|
auto& typeEntry = GetTypeEntry(typeId);
|
|
if (typeKind == BfIRType::TypeKind::TypeKind_TypeId)
|
|
beType = typeEntry.mBeType;
|
|
else if (typeKind == BfIRType::TypeKind::TypeKind_TypeInstId)
|
|
beType = typeEntry.mInstBeType;
|
|
else if (typeKind == BfIRType::TypeKind::TypeKind_TypeInstPtrId)
|
|
beType = mBeContext->GetPointerTo(typeEntry.mInstBeType);
|
|
BE_MEM_END("BeType");
|
|
}
|
|
|
|
void BeIRCodeGen::Read(BeFunctionType*& beType)
|
|
{
|
|
BE_MEM_START;
|
|
int streamId = (int)ReadSLEB128();
|
|
auto& result = mResults[streamId];
|
|
BF_ASSERT(result.mKind == BeIRCodeGenEntryKind_Type);
|
|
beType = (BeFunctionType*)result.mBeType;
|
|
BE_MEM_END("BeFunctionType");
|
|
}
|
|
|
|
void BeIRCodeGen::Read(BeValue*& beValue)
|
|
{
|
|
BE_MEM_START;
|
|
|
|
BfIRParamType paramType = (BfIRParamType)mStream->Read();
|
|
if (paramType == BfIRParamType_None)
|
|
{
|
|
beValue = NULL;
|
|
BE_MEM_END("ParamType_None");
|
|
}
|
|
else if (paramType == BfIRParamType_Const)
|
|
{
|
|
BfTypeCode typeCode = (BfTypeCode)mStream->Read();
|
|
BfConstType constType = (BfConstType)typeCode;
|
|
if (constType == BfConstType_GlobalVar)
|
|
{
|
|
CMD_PARAM(int, streamId);
|
|
if (streamId == -1)
|
|
{
|
|
int streamId = mCmdCount++;
|
|
|
|
CMD_PARAM(BeType*, varType);
|
|
CMD_PARAM(bool, isConstant);
|
|
BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read();
|
|
CMD_PARAM(BeConstant*, initializer);
|
|
CMD_PARAM(String, name);
|
|
CMD_PARAM(bool, isTLS);
|
|
|
|
BF_ASSERT(varType != NULL);
|
|
|
|
auto globalVariable = mBeModule->mGlobalVariables.Alloc();
|
|
globalVariable->mModule = mBeModule;
|
|
globalVariable->mType = varType;
|
|
globalVariable->mIsConstant = isConstant;
|
|
globalVariable->mLinkageType = linkageType;
|
|
globalVariable->mInitializer = initializer;
|
|
globalVariable->mName = name;
|
|
globalVariable->mIsTLS = isTLS;
|
|
globalVariable->mAlign = varType->mAlign;
|
|
globalVariable->mUnnamedAddr = false;
|
|
globalVariable->mStorageKind = BfIRStorageKind_Normal;
|
|
if (initializer != NULL)
|
|
BF_ASSERT(varType->mAlign > 0);
|
|
|
|
SetResult(streamId, globalVariable);
|
|
beValue = globalVariable;
|
|
}
|
|
else
|
|
beValue = GetBeValue(streamId);
|
|
beValue->mRefCount++;
|
|
BE_MEM_END("ParamType_Const_GlobalVar");
|
|
return;
|
|
}
|
|
else if ((constType == BfConstType_BitCast) || (constType == BfConstType_BitCastNull))
|
|
{
|
|
CMD_PARAM(BeConstant*, target);
|
|
CMD_PARAM(BeType*, toType);
|
|
|
|
auto castedVal = mBeModule->mAlloc.Alloc<BeCastConstant>();
|
|
castedVal->mInt64 = target->mInt64;
|
|
castedVal->mType = toType;
|
|
castedVal->mTarget = target;
|
|
BF_ASSERT(target->GetType() != NULL);
|
|
BF_ASSERT(!target->GetType()->IsComposite());
|
|
beValue = castedVal;
|
|
BE_MEM_END("ParamType_Const_BitCast");
|
|
return;
|
|
}
|
|
else if (constType == BfConstType_GEP32_1)
|
|
{
|
|
CMD_PARAM(BeConstant*, target);
|
|
CMD_PARAM(int, idx0);
|
|
|
|
BF_ASSERT(target->GetType()->IsPointer());
|
|
auto gepConstant = mBeModule->mAlloc.Alloc<BeGEP1Constant>();
|
|
gepConstant->mTarget = target;
|
|
gepConstant->mIdx0 = idx0;
|
|
|
|
beValue = gepConstant;
|
|
BE_MEM_END("ParamType_Const_GEP32_1");
|
|
return;
|
|
}
|
|
else if (constType == BfConstType_GEP32_2)
|
|
{
|
|
CMD_PARAM(BeConstant*, target);
|
|
CMD_PARAM(int, idx0);
|
|
CMD_PARAM(int, idx1);
|
|
|
|
BF_ASSERT(target->GetType()->IsPointer());
|
|
auto gepConstant = mBeModule->mAlloc.Alloc<BeGEP2Constant>();
|
|
gepConstant->mTarget = target;
|
|
gepConstant->mIdx0 = idx0;
|
|
gepConstant->mIdx1 = idx1;
|
|
|
|
beValue = gepConstant;
|
|
BE_MEM_END("ParamType_Const_GEP32_2");
|
|
return;
|
|
}
|
|
else if (constType == BfConstType_ExtractValue)
|
|
{
|
|
CMD_PARAM(BeConstant*, target);
|
|
CMD_PARAM(int, idx0);
|
|
|
|
auto gepConstant = mBeModule->mAlloc.Alloc<BeExtractValueConstant>();
|
|
gepConstant->mTarget = target;
|
|
gepConstant->mIdx0 = idx0;
|
|
|
|
beValue = gepConstant;
|
|
BE_MEM_END("ParamType_Const_ExtractValue");
|
|
return;
|
|
}
|
|
else if (constType == BfConstType_PtrToInt)
|
|
{
|
|
CMD_PARAM(BeConstant*, target);
|
|
BfTypeCode toTypeCode = (BfTypeCode)mStream->Read();
|
|
BF_ASSERT(target->GetType()->IsPointer());
|
|
|
|
bool isSigned = false;
|
|
BeType* toType = GetBeType(toTypeCode, isSigned);
|
|
|
|
auto castedVal = mBeModule->mAlloc.Alloc<BeCastConstant>();
|
|
castedVal->mInt64 = target->mInt64;
|
|
castedVal->mType = toType;
|
|
castedVal->mTarget = target;
|
|
BF_ASSERT(target->GetType() != NULL);
|
|
beValue = castedVal;
|
|
BE_MEM_END("ParamType_Const_PtrToInt");
|
|
return;
|
|
}
|
|
else if (constType == BfConstType_IntToPtr)
|
|
{
|
|
CMD_PARAM(BeConstant*, target);
|
|
CMD_PARAM(BeType*, toType);
|
|
|
|
auto castedVal = mBeModule->mAlloc.Alloc<BeCastConstant>();
|
|
castedVal->mInt64 = target->mInt64;
|
|
castedVal->mType = toType;
|
|
castedVal->mTarget = target;
|
|
BF_ASSERT(target->GetType() != NULL);
|
|
BF_ASSERT(!target->GetType()->IsComposite());
|
|
BF_ASSERT(toType->IsPointer());
|
|
beValue = castedVal;
|
|
BE_MEM_END("ParamType_Const_IntToPtr");
|
|
return;
|
|
}
|
|
else if (constType == BfConstType_AggZero)
|
|
{
|
|
CMD_PARAM(BeType*, type);
|
|
auto beConst = mBeModule->mAlloc.Alloc<BeConstant>();
|
|
beConst->mType = type;
|
|
beValue = beConst;
|
|
BE_MEM_END("ParamType_Const_AggZero");
|
|
return;
|
|
}
|
|
else if (constType == BfConstType_Agg)
|
|
{
|
|
CMD_PARAM(BeType*, type);
|
|
CMD_PARAM(CmdParamVec<BeConstant*>, values);
|
|
|
|
if (type->IsSizedArray())
|
|
{
|
|
auto arrayType = (BeSizedArrayType*)type;
|
|
int fillCount = (int)(arrayType->mLength - values.size());
|
|
if (fillCount > 0)
|
|
{
|
|
auto lastValue = values.back();
|
|
for (int i = 0; i < fillCount; i++)
|
|
values.push_back(lastValue);
|
|
}
|
|
}
|
|
else if (type->IsVector())
|
|
{
|
|
auto vecType = (BeVectorType*)type;
|
|
int fillCount = (int)(vecType->mLength - values.size());
|
|
if (fillCount > 0)
|
|
{
|
|
auto lastValue = values.back();
|
|
for (int i = 0; i < fillCount; i++)
|
|
values.push_back(lastValue);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
BF_ASSERT(type->IsStruct());
|
|
}
|
|
|
|
auto constStruct = mBeModule->mOwnedValues.Alloc<BeStructConstant>();
|
|
constStruct->mType = type;
|
|
for (int i = 0; i < (int)values.size(); i++)
|
|
{
|
|
auto val = values[i];
|
|
BeConstant* constant = BeValueDynCast<BeConstant>(val);
|
|
|
|
if (type->IsSizedArray())
|
|
{
|
|
auto arrayType = (BeSizedArrayType*)type;
|
|
auto memberType = constant->GetType();
|
|
if (memberType != arrayType->mElementType)
|
|
Fail("ConstAgg array member type mismatch");
|
|
}
|
|
else if (type->IsVector())
|
|
{
|
|
auto vecType = (BeVectorType*)type;
|
|
auto memberType = constant->GetType();
|
|
if (memberType != vecType->mElementType)
|
|
Fail("ConstAgg vector member type mismatch");
|
|
}
|
|
else
|
|
{
|
|
BF_ASSERT(type->IsStruct());
|
|
auto structType = (BeStructType*)type;
|
|
auto valType = constant->GetType();
|
|
if (structType->mIsOpaque)
|
|
{
|
|
Fail("ConstAgg with opaque struct");
|
|
}
|
|
else if (valType != structType->mMembers[i].mType)
|
|
{
|
|
if (valType->IsSizedArray())
|
|
{
|
|
auto valSizedType = (BeSizedArrayType*)valType;
|
|
if (valSizedType->mSize == 0)
|
|
{
|
|
constant->mType = structType->mMembers[i].mType;
|
|
constStruct->mMemberValues.Add(constant);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
Fail("ConstAgg struct member type mismatch");
|
|
}
|
|
}
|
|
|
|
constStruct->mMemberValues.Add(constant);
|
|
}
|
|
beValue = constStruct;
|
|
|
|
BE_MEM_END("ParamType_Const_Array");
|
|
return;
|
|
}
|
|
else if (constType == BfConstType_ArrayZero8)
|
|
{
|
|
CMD_PARAM(int, count);
|
|
auto beType = mBeContext->CreateSizedArrayType(mBeContext->GetPrimitiveType(BeTypeCode_Int8), count);
|
|
auto beConst = mBeModule->mAlloc.Alloc<BeConstant>();
|
|
beConst->mType = beType;
|
|
beValue = beConst;
|
|
return;
|
|
}
|
|
else if (constType == BfConstType_Undef)
|
|
{
|
|
CMD_PARAM(BeType*, type);
|
|
auto constUndef = mBeModule->mOwnedValues.Alloc<BeUndefConstant>();
|
|
constUndef->mType = type;
|
|
beValue = constUndef;
|
|
return;
|
|
}
|
|
else if (constType == BfConstType_TypeOf)
|
|
{
|
|
CMD_PARAM(BeType*, type);
|
|
beValue = mReflectDataMap[type];
|
|
BF_ASSERT(beValue != NULL);
|
|
return;
|
|
}
|
|
else if (constType == BfConstType_TypeOf_WithData)
|
|
{
|
|
CMD_PARAM(BeType*, type);
|
|
CMD_PARAM(BeValue*, value);
|
|
mReflectDataMap[type] = value;
|
|
beValue = value;
|
|
return;
|
|
}
|
|
|
|
bool isSigned = false;
|
|
BeType* llvmConstType = GetBeType(typeCode, isSigned);
|
|
|
|
if (typeCode == BfTypeCode_Float)
|
|
{
|
|
float f;
|
|
mStream->Read(&f, sizeof(float));
|
|
beValue = mBeModule->GetConstant(llvmConstType, f);
|
|
BE_MEM_END("ParamType_Single");
|
|
}
|
|
else if (typeCode == BfTypeCode_Double)
|
|
{
|
|
double d;
|
|
mStream->Read(&d, sizeof(double));
|
|
beValue = mBeModule->GetConstant(llvmConstType, d);
|
|
BE_MEM_END("ParamType_Const_Double");
|
|
}
|
|
else if (typeCode == BfTypeCode_Boolean)
|
|
{
|
|
CMD_PARAM(bool, boolVal);
|
|
beValue = mBeModule->GetConstant(llvmConstType, boolVal);
|
|
BE_MEM_END("ParamType_Const_Boolean");
|
|
}
|
|
else if (typeCode == BfTypeCode_None)
|
|
{
|
|
beValue = NULL;
|
|
BE_MEM_END("ParamType_Const_None");
|
|
}
|
|
else if (typeCode == BfTypeCode_NullPtr)
|
|
{
|
|
CMD_PARAM(BeType*, nullType);
|
|
beValue = mBeModule->GetConstantNull((BePointerType*)nullType);
|
|
BE_MEM_END("ParamType_Const_NullPtr");
|
|
}
|
|
else if (BfIRBuilder::IsInt(typeCode))
|
|
{
|
|
int64 intVal = ReadSLEB128();
|
|
auto constVal = mBeModule->GetConstant(llvmConstType, intVal);
|
|
beValue = constVal;
|
|
BE_MEM_END("ParamType_Const_Int");
|
|
}
|
|
else
|
|
{
|
|
BF_FATAL("Unhandled");
|
|
}
|
|
}
|
|
else if (paramType == BfIRParamType_Arg)
|
|
{
|
|
int argIdx = mStream->Read();
|
|
beValue = mBeModule->GetArgument(argIdx);
|
|
BE_MEM_END("ParamType_Arg");
|
|
}
|
|
else if (paramType == BfIRParamType_StreamId_Abs8)
|
|
{
|
|
int cmdId = mStream->Read();
|
|
auto& result = mResults[cmdId];
|
|
BF_ASSERT(result.mKind == BeIRCodeGenEntryKind_Value);
|
|
beValue = result.mBeValue;
|
|
BE_MEM_END("ParamType_StreamId");
|
|
}
|
|
else if (paramType == BfIRParamType_StreamId_Rel)
|
|
{
|
|
int cmdId = mCmdCount - (int)ReadSLEB128();
|
|
auto& result = mResults[cmdId];
|
|
BF_ASSERT(result.mKind == BeIRCodeGenEntryKind_Value);
|
|
beValue = result.mBeValue;
|
|
BE_MEM_END("ParamType_StreamId");
|
|
}
|
|
else
|
|
{
|
|
int cmdId = mCmdCount - (paramType - BfIRParamType_StreamId_Back1) - 1;
|
|
auto& result = mResults[cmdId];
|
|
BF_ASSERT(result.mKind == BeIRCodeGenEntryKind_Value);
|
|
beValue = result.mBeValue;
|
|
BE_MEM_END("ParamType_StreamId");
|
|
}
|
|
|
|
if (beValue != NULL)
|
|
beValue->mRefCount++;
|
|
}
|
|
|
|
void BeIRCodeGen::Read(BeConstant*& llvmConstant)
|
|
{
|
|
BE_MEM_START;
|
|
BeValue* value;
|
|
Read(value);
|
|
if (value == NULL)
|
|
{
|
|
llvmConstant = NULL;
|
|
}
|
|
else
|
|
{
|
|
BF_ASSERT(BeValueDynCast<BeConstant>(value));
|
|
llvmConstant = (BeConstant*)value;
|
|
}
|
|
BE_MEM_END("BeConstant");
|
|
}
|
|
|
|
void BeIRCodeGen::Read(BeFunction*& beFunc)
|
|
{
|
|
BE_MEM_START;
|
|
int streamId = (int)ReadSLEB128();
|
|
if (streamId == -1)
|
|
{
|
|
beFunc = NULL;
|
|
return;
|
|
}
|
|
auto& result = mResults[streamId];
|
|
BF_ASSERT(result.mKind == BeIRCodeGenEntryKind_Value);
|
|
BF_ASSERT(BeValueDynCast<BeFunction>(result.mBeValue));
|
|
beFunc = (BeFunction*)result.mBeValue;
|
|
BE_MEM_END("BeFunction");
|
|
|
|
beFunc->mRefCount++;
|
|
}
|
|
|
|
void BeIRCodeGen::Read(BeBlock*& beBlock)
|
|
{
|
|
BE_MEM_START;
|
|
int streamId = (int)ReadSLEB128();
|
|
auto& result = mResults[streamId];
|
|
BF_ASSERT(result.mKind == BeIRCodeGenEntryKind_Block);
|
|
beBlock = (BeBlock*)result.mBeType;
|
|
BE_MEM_END("BeBlock");
|
|
|
|
beBlock->mRefCount++;
|
|
}
|
|
|
|
void BeIRCodeGen::Read(BeMDNode*& llvmMD)
|
|
{
|
|
BE_MEM_START;
|
|
int streamId = (int)ReadSLEB128();
|
|
if (streamId == -1)
|
|
{
|
|
llvmMD = NULL;
|
|
return;
|
|
}
|
|
auto& result = mResults[streamId];
|
|
BF_ASSERT(result.mKind == BeIRCodeGenEntryKind_Metadata);
|
|
llvmMD = result.mBeMetadata;
|
|
BE_MEM_END("BeMDNode");
|
|
|
|
if (llvmMD != NULL)
|
|
llvmMD->mRefCount++;
|
|
}
|
|
|
|
void BeIRCodeGen::HandleNextCmd()
|
|
{
|
|
int curId = mCmdCount;
|
|
|
|
BfIRCmd cmd = (BfIRCmd)mStream->Read();
|
|
mCmdCount++;
|
|
|
|
#ifdef CODEGEN_TRACK
|
|
gBEMemReporter.BeginSection(gIRCmdNames[cmd]);
|
|
gBEMemReporter.Add(1);
|
|
#endif
|
|
|
|
switch (cmd)
|
|
{
|
|
case BfIRCmd_Module_Start:
|
|
{
|
|
CMD_PARAM(String, moduleName);
|
|
CMD_PARAM(int, ptrSize);
|
|
CMD_PARAM(bool, isOptimized);
|
|
|
|
BF_ASSERT(mBeModule == NULL);
|
|
mPtrSize = ptrSize;
|
|
mIsOptimized = isOptimized;
|
|
mBeContext = new BeContext();
|
|
mBeModule = new BeModule(moduleName, mBeContext);
|
|
mBeModule->mBeIRCodeGen = this;
|
|
mBeContext->mPointerSize = ptrSize;
|
|
|
|
for (auto constInt : mConfigConsts)
|
|
{
|
|
auto constVal = mBeModule->mAlloc.Alloc<BeConstant>();
|
|
constVal->mType = mBeContext->GetPrimitiveType(BeTypeCode_Int32);
|
|
constVal->mInt64 = constInt;
|
|
mBeModule->mConfigConsts32.Add(constVal);
|
|
|
|
constVal = mBeModule->mAlloc.Alloc<BeConstant>();
|
|
constVal->mType = mBeContext->GetPrimitiveType(BeTypeCode_Int64);
|
|
constVal->mInt64 = constInt;
|
|
mBeModule->mConfigConsts64.Add(constVal);
|
|
}
|
|
}
|
|
break;
|
|
case BfIRCmd_Module_SetTargetTriple:
|
|
{
|
|
CMD_PARAM(String, targetTriple);
|
|
CMD_PARAM(String, targetCPU);
|
|
mBeModule->mTargetTriple = targetTriple;
|
|
mBeModule->mTargetCPU = targetCPU;
|
|
}
|
|
break;
|
|
case BfIRCmd_Module_AddModuleFlag:
|
|
{
|
|
CMD_PARAM(String, flag);
|
|
CMD_PARAM(int, val);
|
|
//mBeModule->addModuleFlag(BeModule::Warning, flag, val);
|
|
}
|
|
break;
|
|
case BfIRCmd_WriteIR:
|
|
{
|
|
/*CMD_PARAM(String, fileName);
|
|
std::error_code ec;
|
|
Beraw_fd_ostream outStream(fileName.c_str(), ec, Besys::fs::OpenFlags::F_Text);
|
|
if (ec)
|
|
{
|
|
Fail("Failed writing IR '" + fileName + "': " + ec.message());
|
|
}
|
|
else
|
|
mBeModule->print(outStream, NULL);*/
|
|
}
|
|
break;
|
|
case BfIRCmd_SetType:
|
|
{
|
|
CMD_PARAM(int, typeId);
|
|
CMD_PARAM(BeType*, type);
|
|
auto& typeEntry = GetTypeEntry(typeId);
|
|
typeEntry.mBeType = type;
|
|
if (typeEntry.mInstBeType == NULL)
|
|
typeEntry.mInstBeType = type;
|
|
}
|
|
break;
|
|
case BfIRCmd_SetInstType:
|
|
{
|
|
CMD_PARAM(int, typeId);
|
|
CMD_PARAM(BeType*, type);
|
|
GetTypeEntry(typeId).mInstBeType = type;
|
|
}
|
|
break;
|
|
case BfIRCmd_PrimitiveType:
|
|
{
|
|
BfTypeCode typeCode = (BfTypeCode)mStream->Read();
|
|
bool isSigned = false;
|
|
SetResult(curId, GetBeType(typeCode, isSigned));
|
|
}
|
|
break;
|
|
case BfIRCmd_CreateStruct:
|
|
{
|
|
CMD_PARAM(String, typeName);
|
|
SetResult(curId, mBeContext->CreateStruct(typeName));
|
|
}
|
|
break;
|
|
case BfIRCmd_CreateAnonymousStruct:
|
|
{
|
|
CMD_PARAM(CmdParamVec<BeType*>, members);
|
|
BeStructType* structType = mBeContext->CreateStruct(members);
|
|
SetResult(curId, structType);
|
|
}
|
|
break;
|
|
case BfIRCmd_StructSetBody:
|
|
{
|
|
CMD_PARAM(BeType*, type);
|
|
CMD_PARAM(CmdParamVec<BeType*>, members);
|
|
CMD_PARAM(int, instSize);
|
|
CMD_PARAM(int, instAlign);
|
|
CMD_PARAM(bool, isPacked);
|
|
BF_ASSERT(type->mTypeCode == BeTypeCode_Struct);
|
|
auto structType = (BeStructType*)type;
|
|
mBeContext->SetStructBody(structType, members, isPacked);
|
|
structType->mSize = instSize;
|
|
structType->mAlign = instAlign;
|
|
}
|
|
break;
|
|
case BfIRCmd_Type:
|
|
{
|
|
CMD_PARAM(BeIRTypeEntry*, typeEntry);
|
|
auto type = typeEntry->mBeType;
|
|
SetResult(curId, type);
|
|
}
|
|
break;
|
|
case BfIRCmd_TypeInst:
|
|
{
|
|
CMD_PARAM(BeIRTypeEntry*, typeEntry);
|
|
SetResult(curId, typeEntry->mInstBeType);
|
|
}
|
|
break;
|
|
case BfIRCmd_TypeInstPtr:
|
|
{
|
|
CMD_PARAM(BeIRTypeEntry*, typeEntry);
|
|
SetResult(curId, mBeContext->GetPointerTo(typeEntry->mInstBeType));
|
|
}
|
|
break;
|
|
case BfIRCmd_GetType:
|
|
{
|
|
CMD_PARAM(BeValue*, value);
|
|
auto type = value->GetType();
|
|
SetResult(curId, type);
|
|
}
|
|
break;
|
|
case BfIRCmd_GetPointerToFuncType:
|
|
{
|
|
CMD_PARAM(BeFunctionType*, funcType);
|
|
SetResult(curId, mBeContext->GetPointerTo(funcType));
|
|
}
|
|
break;
|
|
case BfIRCmd_GetPointerToType:
|
|
{
|
|
CMD_PARAM(BeType*, type);
|
|
SetResult(curId, mBeContext->GetPointerTo(type));
|
|
}
|
|
break;
|
|
case BfIRCmd_GetSizedArrayType:
|
|
{
|
|
CMD_PARAM(BeType*, elementType);
|
|
CMD_PARAM(int, length);
|
|
SetResult(curId, mBeContext->CreateSizedArrayType(elementType, length));
|
|
}
|
|
break;
|
|
case BfIRCmd_GetVectorType:
|
|
{
|
|
CMD_PARAM(BeType*, elementType);
|
|
CMD_PARAM(int, length);
|
|
SetResult(curId, mBeContext->CreateVectorType(elementType, length));
|
|
}
|
|
break;
|
|
case BfIRCmd_CreateConstAgg:
|
|
{
|
|
CMD_PARAM(BeType*, type);
|
|
CMD_PARAM(CmdParamVec<BeValue*>, values);
|
|
|
|
auto constStruct = mBeModule->mOwnedValues.Alloc<BeStructConstant>();
|
|
constStruct->mType = type;
|
|
|
|
if (type->IsStruct())
|
|
{
|
|
FixValues((BeStructType*)type, values);
|
|
|
|
BF_ASSERT(((BeStructType*)type)->mMembers.size() == values.size());
|
|
for (int i = 0; i < (int)values.size(); i++)
|
|
{
|
|
auto val = values[i];
|
|
BF_ASSERT(mBeContext->AreTypesEqual(((BeStructType*)type)->mMembers[i].mType, val->GetType()));
|
|
constStruct->mMemberValues.push_back(BeValueDynCast<BeConstant>(val));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
BF_ASSERT(type->IsSizedArray());
|
|
auto arrayType = (BeSizedArrayType*)type;
|
|
|
|
int fillCount = (int)(arrayType->mLength - values.size());
|
|
if (fillCount > 0)
|
|
{
|
|
auto lastValue = values.back();
|
|
for (int i = 0; i < fillCount; i++)
|
|
values.push_back(lastValue);
|
|
}
|
|
|
|
BF_ASSERT(arrayType->mLength == values.size());
|
|
for (int i = 0; i < (int)values.size(); i++)
|
|
{
|
|
auto val = values[i];
|
|
BF_ASSERT(mBeContext->AreTypesEqual(((BeSizedArrayType*)type)->mElementType, val->GetType()));
|
|
constStruct->mMemberValues.push_back(BeValueDynCast<BeConstant>(val));
|
|
}
|
|
}
|
|
SetResult(curId, constStruct);
|
|
}
|
|
break;
|
|
case BfIRCmd_CreateConstStructZero:
|
|
{
|
|
CMD_PARAM(BeType*, type);
|
|
auto beConst = mBeModule->mAlloc.Alloc<BeConstant>();
|
|
beConst->mType = type;
|
|
SetResult(curId, beConst);
|
|
}
|
|
break;
|
|
case BfIRCmd_CreateConstString:
|
|
{
|
|
CMD_PARAM(String, str);
|
|
auto constStruct = mBeModule->mOwnedValues.Alloc<BeStringConstant>();
|
|
constStruct->mString = str;
|
|
auto charType = mBeContext->GetPrimitiveType(BeTypeCode_Int8);
|
|
constStruct->mType = mBeContext->CreateSizedArrayType(charType, str.length() + 1);
|
|
SetResult(curId, constStruct);
|
|
}
|
|
break;
|
|
case BfIRCmd_ConfigConst:
|
|
{
|
|
CMD_PARAM(int, constIdx);
|
|
BfTypeCode typeCode = (BfTypeCode)mStream->Read();
|
|
if (typeCode == BfTypeCode_IntPtr)
|
|
typeCode = (mPtrSize == 4) ? BfTypeCode_Int32 : BfTypeCode_Int64;
|
|
BeConstant* constVal = (typeCode == BfTypeCode_Int32) ?
|
|
mBeModule->mConfigConsts32[constIdx] :
|
|
mBeModule->mConfigConsts64[constIdx];
|
|
SetResult(curId, constVal);
|
|
}
|
|
break;
|
|
case BfIRCmd_SetName:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
CMD_PARAM(String, name);
|
|
val->SetName(name);
|
|
}
|
|
break;
|
|
case BfIRCmd_CreateUndefValue:
|
|
{
|
|
CMD_PARAM(BeType*, type);
|
|
SetResult(curId, mBeModule->CreateUndefValue(type));
|
|
}
|
|
break;
|
|
case BfIRCmd_NumericCast:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
CMD_PARAM(bool, valIsSigned);
|
|
|
|
BfTypeCode typeCode = (BfTypeCode)mStream->Read();
|
|
auto valType = val->GetType();
|
|
if ((!valType->IsIntable()) && (!valType->IsFloat()))
|
|
{
|
|
Fail("Invalid NumericCast target");
|
|
}
|
|
|
|
BfTypeCode valTypeCode = GetTypeCode(valType, valIsSigned);
|
|
|
|
if (auto srcCastConstant = BeValueDynCast<BeCastConstant>(val))
|
|
{
|
|
BeType* toType = GetBeType(typeCode, valIsSigned);
|
|
|
|
auto castedVal = mBeModule->mAlloc.Alloc<BeCastConstant>();
|
|
castedVal->mInt64 = srcCastConstant->mInt64;
|
|
castedVal->mType = toType;
|
|
castedVal->mTarget = srcCastConstant->mTarget;
|
|
|
|
SetResult(curId, castedVal);
|
|
break;
|
|
}
|
|
|
|
bool toSigned = false;
|
|
auto toBeType = GetBeType(typeCode, toSigned);
|
|
BeValue* retVal = mBeModule->CreateNumericCast(val, toBeType, valIsSigned, toSigned);
|
|
SetResult(curId, retVal);
|
|
}
|
|
break;
|
|
case BfIRCmd_CmpEQ:
|
|
{
|
|
CMD_PARAM(BeValue*, lhs);
|
|
CMD_PARAM(BeValue*, rhs);
|
|
if (lhs->GetType() != rhs->GetType())
|
|
Fail("Type mismatch for CmpEQ");
|
|
SetResult(curId, mBeModule->CreateCmp(BeCmpKind_EQ, lhs, rhs));
|
|
}
|
|
break;
|
|
case BfIRCmd_CmpNE:
|
|
{
|
|
CMD_PARAM(BeValue*, lhs);
|
|
CMD_PARAM(BeValue*, rhs);
|
|
SetResult(curId, mBeModule->CreateCmp(BeCmpKind_NE, lhs, rhs));
|
|
}
|
|
break;
|
|
case BfIRCmd_CmpSLT:
|
|
{
|
|
CMD_PARAM(BeValue*, lhs);
|
|
CMD_PARAM(BeValue*, rhs);
|
|
SetResult(curId, mBeModule->CreateCmp(BeCmpKind_SLT, lhs, rhs));
|
|
}
|
|
break;
|
|
case BfIRCmd_CmpULT:
|
|
{
|
|
CMD_PARAM(BeValue*, lhs);
|
|
CMD_PARAM(BeValue*, rhs);
|
|
SetResult(curId, mBeModule->CreateCmp(BeCmpKind_ULT, lhs, rhs));
|
|
}
|
|
break;
|
|
case BfIRCmd_CmpSLE:
|
|
{
|
|
CMD_PARAM(BeValue*, lhs);
|
|
CMD_PARAM(BeValue*, rhs);
|
|
SetResult(curId, mBeModule->CreateCmp(BeCmpKind_SLE, lhs, rhs));
|
|
}
|
|
break;
|
|
case BfIRCmd_CmpULE:
|
|
{
|
|
CMD_PARAM(BeValue*, lhs);
|
|
CMD_PARAM(BeValue*, rhs);
|
|
SetResult(curId, mBeModule->CreateCmp(BeCmpKind_ULE, lhs, rhs));
|
|
}
|
|
break;
|
|
case BfIRCmd_CmpSGT:
|
|
{
|
|
CMD_PARAM(BeValue*, lhs);
|
|
CMD_PARAM(BeValue*, rhs);
|
|
SetResult(curId, mBeModule->CreateCmp(BeCmpKind_SGT, lhs, rhs));
|
|
}
|
|
break;
|
|
case BfIRCmd_CmpUGT:
|
|
{
|
|
CMD_PARAM(BeValue*, lhs);
|
|
CMD_PARAM(BeValue*, rhs);
|
|
SetResult(curId, mBeModule->CreateCmp(BeCmpKind_UGT, lhs, rhs));
|
|
}
|
|
break;
|
|
case BfIRCmd_CmpSGE:
|
|
{
|
|
CMD_PARAM(BeValue*, lhs);
|
|
CMD_PARAM(BeValue*, rhs);
|
|
SetResult(curId, mBeModule->CreateCmp(BeCmpKind_SGE, lhs, rhs));
|
|
}
|
|
break;
|
|
case BfIRCmd_CmpUGE:
|
|
{
|
|
CMD_PARAM(BeValue*, lhs);
|
|
CMD_PARAM(BeValue*, rhs);
|
|
SetResult(curId, mBeModule->CreateCmp(BeCmpKind_UGE, lhs, rhs));
|
|
}
|
|
break;
|
|
case BfIRCmd_Add:
|
|
{
|
|
CMD_PARAM(BeValue*, lhs);
|
|
CMD_PARAM(BeValue*, rhs);
|
|
CMD_PARAM(int8, overflowCheckKind);
|
|
SetResult(curId, mBeModule->CreateBinaryOp(BeBinaryOpKind_Add, lhs, rhs, (BfOverflowCheckKind)overflowCheckKind));
|
|
}
|
|
break;
|
|
case BfIRCmd_Sub:
|
|
{
|
|
CMD_PARAM(BeValue*, lhs);
|
|
CMD_PARAM(BeValue*, rhs);
|
|
CMD_PARAM(int8, overflowCheckKind);
|
|
SetResult(curId, mBeModule->CreateBinaryOp(BeBinaryOpKind_Subtract, lhs, rhs, (BfOverflowCheckKind)overflowCheckKind));
|
|
}
|
|
break;
|
|
case BfIRCmd_Mul:
|
|
{
|
|
CMD_PARAM(BeValue*, lhs);
|
|
CMD_PARAM(BeValue*, rhs);
|
|
CMD_PARAM(int8, overflowCheckKind);
|
|
SetResult(curId, mBeModule->CreateBinaryOp(BeBinaryOpKind_Multiply, lhs, rhs, (BfOverflowCheckKind)overflowCheckKind));
|
|
}
|
|
break;
|
|
case BfIRCmd_SDiv:
|
|
{
|
|
CMD_PARAM(BeValue*, lhs);
|
|
CMD_PARAM(BeValue*, rhs);
|
|
SetResult(curId, mBeModule->CreateBinaryOp(BeBinaryOpKind_SDivide, lhs, rhs));
|
|
}
|
|
break;
|
|
case BfIRCmd_UDiv:
|
|
{
|
|
CMD_PARAM(BeValue*, lhs);
|
|
CMD_PARAM(BeValue*, rhs);
|
|
SetResult(curId, mBeModule->CreateBinaryOp(BeBinaryOpKind_UDivide, lhs, rhs));
|
|
}
|
|
break;
|
|
case BfIRCmd_SRem:
|
|
{
|
|
CMD_PARAM(BeValue*, lhs);
|
|
CMD_PARAM(BeValue*, rhs);
|
|
SetResult(curId, mBeModule->CreateBinaryOp(BeBinaryOpKind_SModulus, lhs, rhs));
|
|
}
|
|
break;
|
|
case BfIRCmd_URem:
|
|
{
|
|
CMD_PARAM(BeValue*, lhs);
|
|
CMD_PARAM(BeValue*, rhs);
|
|
SetResult(curId, mBeModule->CreateBinaryOp(BeBinaryOpKind_UModulus, lhs, rhs));
|
|
}
|
|
break;
|
|
case BfIRCmd_And:
|
|
{
|
|
CMD_PARAM(BeValue*, lhs);
|
|
CMD_PARAM(BeValue*, rhs);
|
|
SetResult(curId, mBeModule->CreateBinaryOp(BeBinaryOpKind_BitwiseAnd, lhs, rhs));
|
|
}
|
|
break;
|
|
case BfIRCmd_Or:
|
|
{
|
|
CMD_PARAM(BeValue*, lhs);
|
|
CMD_PARAM(BeValue*, rhs);
|
|
SetResult(curId, mBeModule->CreateBinaryOp(BeBinaryOpKind_BitwiseOr, lhs, rhs));
|
|
}
|
|
break;
|
|
case BfIRCmd_Xor:
|
|
{
|
|
CMD_PARAM(BeValue*, lhs);
|
|
CMD_PARAM(BeValue*, rhs);
|
|
SetResult(curId, mBeModule->CreateBinaryOp(BeBinaryOpKind_ExclusiveOr, lhs, rhs));
|
|
}
|
|
break;
|
|
case BfIRCmd_Shl:
|
|
{
|
|
CMD_PARAM(BeValue*, lhs);
|
|
CMD_PARAM(BeValue*, rhs);
|
|
SetResult(curId, mBeModule->CreateBinaryOp(BeBinaryOpKind_LeftShift, lhs, rhs));
|
|
}
|
|
break;
|
|
case BfIRCmd_AShr:
|
|
{
|
|
CMD_PARAM(BeValue*, lhs);
|
|
CMD_PARAM(BeValue*, rhs);
|
|
SetResult(curId, mBeModule->CreateBinaryOp(BeBinaryOpKind_ARightShift, lhs, rhs));
|
|
}
|
|
break;
|
|
case BfIRCmd_LShr:
|
|
{
|
|
CMD_PARAM(BeValue*, lhs);
|
|
CMD_PARAM(BeValue*, rhs);
|
|
SetResult(curId, mBeModule->CreateBinaryOp(BeBinaryOpKind_RightShift, lhs, rhs));
|
|
}
|
|
break;
|
|
case BfIRCmd_Neg:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
|
|
auto negInst = mBeModule->AllocInst<BeNegInst>();
|
|
negInst->mValue = val;
|
|
SetResult(curId, negInst);
|
|
}
|
|
break;
|
|
case BfIRCmd_Not:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
|
|
auto negInst = mBeModule->AllocInst<BeNotInst>();
|
|
negInst->mValue = val;
|
|
SetResult(curId, negInst);
|
|
}
|
|
break;
|
|
case BfIRCmd_BitCast:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
CMD_PARAM(BeType*, toType);
|
|
if (auto funcVal = BeValueDynCast<BeFunction>(val))
|
|
{
|
|
auto beConst = mBeModule->mAlloc.Alloc<BeConstant>();
|
|
beConst->mTarget = funcVal;
|
|
BF_ASSERT(funcVal->mType != NULL);
|
|
beConst->mType = toType;
|
|
SetResult(curId, beConst);
|
|
break;
|
|
}
|
|
|
|
SetResult(curId, mBeModule->CreateBitCast(val, toType));
|
|
}
|
|
break;
|
|
case BfIRCmd_PtrToInt:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
auto typeCode = (BfTypeCode)mStream->Read();
|
|
bool isSigned = false;
|
|
auto beType = GetBeType(typeCode, isSigned);
|
|
|
|
BF_ASSERT(beType != NULL);
|
|
auto numericCastInst = mBeModule->AllocInst<BeNumericCastInst>();
|
|
numericCastInst->mValue = val;
|
|
numericCastInst->mValSigned = false;
|
|
numericCastInst->mToType = beType;
|
|
numericCastInst->mToSigned = isSigned;
|
|
SetResult(curId, numericCastInst);
|
|
}
|
|
break;
|
|
case BfIRCmd_IntToPtr:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
CMD_PARAM(BeType*, toType);
|
|
|
|
auto bitcastInst = mBeModule->AllocInst<BeBitCastInst>();
|
|
bitcastInst->mValue = val;
|
|
bitcastInst->mToType = toType;
|
|
SetResult(curId, bitcastInst);
|
|
}
|
|
break;
|
|
case BfIRCmd_InboundsGEP1_32:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
CMD_PARAM(int, idx0);
|
|
BF_ASSERT(val->GetType()->IsPointer());
|
|
BeType* int32Type = mBeContext->GetPrimitiveType(BeTypeCode_Int32);
|
|
SetResult(curId, mBeModule->CreateGEP(val, mBeModule->GetConstant(int32Type, (int64)idx0), NULL));
|
|
}
|
|
break;
|
|
case BfIRCmd_InboundsGEP2_32:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
CMD_PARAM(int, idx0);
|
|
CMD_PARAM(int, idx1);
|
|
BF_ASSERT(val->GetType()->IsPointer());
|
|
BeType* int32Type = mBeContext->GetPrimitiveType(BeTypeCode_Int32);
|
|
SetResult(curId, mBeModule->CreateGEP(val, mBeModule->GetConstant(int32Type, (int64)idx0), mBeModule->GetConstant(int32Type, (int64)idx1)));
|
|
}
|
|
break;
|
|
case BfIRCmd_InBoundsGEP1:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
CMD_PARAM(BeValue*, idx0);
|
|
BF_ASSERT(val->GetType()->IsPointer());
|
|
SetResult(curId, mBeModule->CreateGEP(val, idx0, NULL));
|
|
}
|
|
break;
|
|
case BfIRCmd_InBoundsGEP2:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
CMD_PARAM(BeValue*, idx0);
|
|
CMD_PARAM(BeValue*, idx1);
|
|
BF_ASSERT(val->GetType()->IsPointer());
|
|
SetResult(curId, mBeModule->CreateGEP(val, idx0, idx1));
|
|
}
|
|
break;
|
|
case BfIRCmd_IsNull:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
BF_ASSERT(val->GetType()->IsPointer());
|
|
SetResult(curId, mBeModule->CreateCmp(BeCmpKind_EQ, val, mBeModule->GetConstantNull((BePointerType*)val->GetType())));
|
|
}
|
|
break;
|
|
case BfIRCmd_IsNotNull:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
BF_ASSERT(val->GetType()->IsPointer());
|
|
SetResult(curId, mBeModule->CreateCmp(BeCmpKind_NE, val, mBeModule->GetConstantNull((BePointerType*)val->GetType())));
|
|
}
|
|
break;
|
|
case BfIRCmd_ExtractValue:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
CMD_PARAM(int, idx);
|
|
|
|
BF_ASSERT(val->GetType()->IsComposite());
|
|
|
|
auto extractValueInst = mBeModule->AllocInst<BeExtractValueInst>();
|
|
extractValueInst->mAggVal = val;
|
|
extractValueInst->mIdx = idx;
|
|
SetResult(curId, extractValueInst);
|
|
}
|
|
break;
|
|
case BfIRCmd_InsertValue:
|
|
{
|
|
CMD_PARAM(BeValue*, agg);
|
|
CMD_PARAM(BeValue*, val);
|
|
CMD_PARAM(int, idx);
|
|
|
|
auto insertValueInst = mBeModule->AllocInst<BeInsertValueInst>();
|
|
insertValueInst->mAggVal = agg;
|
|
insertValueInst->mMemberVal = val;
|
|
insertValueInst->mIdx = idx;
|
|
SetResult(curId, insertValueInst);
|
|
}
|
|
break;
|
|
case BfIRCmd_Alloca:
|
|
{
|
|
CMD_PARAM(BeType*, type);
|
|
if (type->IsStruct())
|
|
{
|
|
BF_ASSERT(!((BeStructType*)type)->mIsOpaque);
|
|
}
|
|
|
|
auto allocaInst = mBeModule->CreateAlloca(type);
|
|
allocaInst->mAlign = type->mAlign;
|
|
SetResult(curId, allocaInst);
|
|
}
|
|
break;
|
|
case BfIRCmd_AllocaArray:
|
|
{
|
|
CMD_PARAM(BeType*, type);
|
|
CMD_PARAM(BeValue*, arraySize);
|
|
|
|
if (auto constant = BeValueDynCast<BeConstant>(arraySize))
|
|
{
|
|
//BF_ASSERT(constant->mInt64 >= 0);
|
|
}
|
|
|
|
auto allocaInst = mBeModule->AllocInst<BeAllocaInst>();
|
|
allocaInst->mType = type;
|
|
allocaInst->mAlign = type->mAlign;
|
|
allocaInst->mArraySize = arraySize;
|
|
|
|
SetResult(curId, allocaInst);
|
|
}
|
|
break;
|
|
case BfIRCmd_SetAllocaAlignment:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
CMD_PARAM(int, alignment);
|
|
auto inst = BeValueDynCast<BeAllocaInst>(val);
|
|
|
|
inst->mAlign = alignment;
|
|
//TODO: Implement
|
|
/*inst->setAlignment(alignment);*/
|
|
}
|
|
break;
|
|
case BfIRCmd_AliasValue:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
auto inst = mBeModule->AllocInst<BeAliasValueInst>();
|
|
inst->mPtr = val;
|
|
SetResult(curId, inst);
|
|
}
|
|
break;
|
|
case BfIRCmd_LifetimeStart:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
auto inst = mBeModule->AllocInst<BeLifetimeStartInst>();
|
|
inst->mPtr = val;
|
|
SetResult(curId, inst);
|
|
}
|
|
break;
|
|
case BfIRCmd_LifetimeEnd:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
#ifdef _DEBUG
|
|
val->mLifetimeEnded = true;
|
|
#endif
|
|
auto inst = mBeModule->AllocInst<BeLifetimeEndInst>();
|
|
inst->mPtr = val;
|
|
SetResult(curId, inst);
|
|
}
|
|
break;
|
|
case BfIRCmd_LifetimeSoftEnd:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
auto inst = mBeModule->AllocInst<BeLifetimeSoftEndInst>();
|
|
inst->mPtr = val;
|
|
SetResult(curId, inst);
|
|
}
|
|
break;
|
|
case BfIRCmd_LifetimeExtend:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
auto inst = mBeModule->AllocInst<BeLifetimeExtendInst>();
|
|
inst->mPtr = val;
|
|
SetResult(curId, inst);
|
|
}
|
|
break;
|
|
case BfIRCmd_ValueScopeStart:
|
|
{
|
|
auto inst = mBeModule->AllocInst<BeValueScopeStartInst>();
|
|
SetResult(curId, inst);
|
|
}
|
|
break;
|
|
case BfIRCmd_ValueScopeRetain:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
auto inst = mBeModule->AllocInst<BeValueScopeRetainInst>();
|
|
inst->mValue = val;
|
|
}
|
|
break;
|
|
case BfIRCmd_ValueScopeSoftEnd:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
auto inst = mBeModule->AllocInst<BeValueScopeEndInst>();
|
|
inst->mScopeStart = (BeValueScopeStartInst*)val;
|
|
inst->mIsSoft = true;
|
|
//TODO: Is this always correct? This keeps there from being nops inserted on block opens ( { )
|
|
inst->mDbgLoc = NULL;
|
|
}
|
|
break;
|
|
case BfIRCmd_ValueScopeHardEnd:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
auto inst = mBeModule->AllocInst<BeValueScopeEndInst>();
|
|
inst->mScopeStart = (BeValueScopeStartInst*)val;
|
|
inst->mIsSoft = false;
|
|
//TODO: Is this always correct? This keeps there from being nops inserted on block opens ( { )
|
|
inst->mDbgLoc = NULL;
|
|
}
|
|
break;
|
|
case BfIRCmd_SetAllocaNoChkStkHint:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
auto inst = BeValueDynCast<BeAllocaInst>(val);
|
|
inst->mNoChkStk = true;
|
|
}
|
|
break;
|
|
case BfIRCmd_SetAllocaForceMem:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
auto inst = BeValueDynCast<BeAllocaInst>(val);
|
|
inst->mForceMem = true;
|
|
}
|
|
break;
|
|
case BfIRCmd_Load:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
#ifdef _DEBUG
|
|
auto ptrType = val->GetType();
|
|
BF_ASSERT(ptrType->IsPointer());
|
|
// We call via a function pointer so there's never a reason to allow loading of a funcPtr
|
|
BF_ASSERT(((BePointerType*)ptrType)->mElementType->mTypeCode != BeTypeCode_Function);
|
|
|
|
// Disallow loading from a NULL constant
|
|
if (val->GetTypeId() == BeConstant::TypeId)
|
|
{
|
|
if (auto constant = BeValueDynCast<BeConstant>(val))
|
|
{
|
|
BF_ASSERT(constant->mTarget != NULL);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
CMD_PARAM(bool, isVolatile);
|
|
SetResult(curId, mBeModule->CreateLoad(val, isVolatile));
|
|
}
|
|
break;
|
|
case BfIRCmd_AlignedLoad:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
CMD_PARAM(int, alignment);
|
|
CMD_PARAM(bool, isVolatile);
|
|
#ifdef _DEBUG
|
|
// Disallow loading from a NULL constant
|
|
if (val->GetTypeId() == BeConstant::TypeId)
|
|
{
|
|
if (auto constant = BeValueDynCast<BeConstant>(val))
|
|
{
|
|
BF_ASSERT(constant->mTarget != NULL);
|
|
}
|
|
}
|
|
|
|
auto ptrType = val->GetType();
|
|
BF_ASSERT(ptrType->IsPointer());
|
|
#endif
|
|
SetResult(curId, mBeModule->CreateAlignedLoad(val, alignment, isVolatile));
|
|
}
|
|
break;
|
|
case BfIRCmd_Store:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
CMD_PARAM(BeValue*, ptr);
|
|
|
|
#ifdef _DEBUG
|
|
auto ptrType = ptr->GetType();
|
|
auto valType = val->GetType();
|
|
|
|
if ((!ptrType->IsPointer()) || (!mBeContext->AreTypesEqual(((BePointerType*)ptrType)->mElementType, valType)))
|
|
{
|
|
String errStr;
|
|
errStr += "BfIRCmd_Store Match Failure:\n";
|
|
BeDumpContext dumpCtx;
|
|
errStr += "Val: ";
|
|
dumpCtx.ToString(errStr, val);
|
|
errStr += "\nPtr: ";
|
|
dumpCtx.ToString(errStr, ptr);
|
|
FatalError(errStr);
|
|
}
|
|
#endif
|
|
|
|
CMD_PARAM(bool, isVolatile);
|
|
SetResult(curId, mBeModule->CreateStore(val, ptr, isVolatile));
|
|
}
|
|
break;
|
|
case BfIRCmd_AlignedStore:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
CMD_PARAM(BeValue*, ptr);
|
|
CMD_PARAM(int, alignment);
|
|
CMD_PARAM(bool, isVolatile);
|
|
|
|
#ifdef _DEBUG
|
|
auto ptrType = ptr->GetType();
|
|
auto valType = val->GetType();
|
|
if ((!ptrType->IsPointer()) || (!mBeContext->AreTypesEqual(((BePointerType*)ptrType)->mElementType, valType)))
|
|
{
|
|
String errStr;
|
|
errStr += "BfIRCmd_Store Match Failure:\n";
|
|
BeDumpContext dumpCtx;
|
|
errStr += "Val: ";
|
|
dumpCtx.ToString(errStr, val);
|
|
errStr += "\nPtr: ";
|
|
dumpCtx.ToString(errStr, ptr);
|
|
FatalError(errStr);
|
|
}
|
|
#endif
|
|
|
|
SetResult(curId, mBeModule->CreateAlignedStore(val, ptr, alignment, isVolatile));
|
|
}
|
|
break;
|
|
case BfIRCmd_MemSet:
|
|
{
|
|
auto inst = mBeModule->AllocInst<BeMemSetInst>();
|
|
Read(inst->mAddr);
|
|
Read(inst->mVal);
|
|
Read(inst->mSize);
|
|
Read(inst->mAlignment);
|
|
SetResult(curId, inst);
|
|
}
|
|
break;
|
|
case BfIRCmd_Fence:
|
|
{
|
|
BfIRFenceType fenceType = (BfIRFenceType)mStream->Read();
|
|
mBeModule->AllocInst<BeFenceInst>();
|
|
}
|
|
break;
|
|
case BfIRCmd_StackSave:
|
|
{
|
|
SetResult(curId, mBeModule->AllocInst<BeStackSaveInst>());
|
|
}
|
|
break;
|
|
case BfIRCmd_StackRestore:
|
|
{
|
|
CMD_PARAM(BeValue*, stackVal);
|
|
auto stackRestoreInst = mBeModule->AllocInst<BeStackRestoreInst>();
|
|
stackRestoreInst->mStackVal = stackVal;
|
|
SetResult(curId, stackRestoreInst);
|
|
}
|
|
break;
|
|
case BfIRCmd_GlobalVariable:
|
|
{
|
|
CMD_PARAM(BeType*, varType);
|
|
CMD_PARAM(bool, isConstant);
|
|
BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read();
|
|
CMD_PARAM(StringT<256>, name);
|
|
CMD_PARAM(bool, isTLS);
|
|
CMD_PARAM(BeConstant*, initializer);
|
|
|
|
BF_ASSERT(varType != NULL);
|
|
|
|
auto globalVariable = mBeModule->mGlobalVariables.Alloc();
|
|
globalVariable->mModule = mBeModule;
|
|
globalVariable->mType = varType;
|
|
globalVariable->mIsConstant = isConstant;
|
|
globalVariable->mLinkageType = linkageType;
|
|
globalVariable->mInitializer = initializer;
|
|
globalVariable->mName = name;
|
|
globalVariable->mIsTLS = isTLS;
|
|
globalVariable->mUnnamedAddr = false;
|
|
globalVariable->mStorageKind = BfIRStorageKind_Normal;
|
|
if (initializer != NULL)
|
|
{
|
|
globalVariable->mAlign = varType->mAlign;
|
|
BF_ASSERT(varType->mAlign > 0);
|
|
BF_ASSERT(mBeContext->AreTypesEqual(varType, initializer->GetType()));
|
|
}
|
|
else
|
|
globalVariable->mAlign = -1;
|
|
|
|
SetResult(curId, globalVariable);
|
|
}
|
|
break;
|
|
case BfIRCmd_GlobalVar_SetUnnamedAddr:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
CMD_PARAM(bool, unnamedAddr);
|
|
|
|
BF_ASSERT(BeValueDynCast<BeGlobalVariable>(val) != NULL);
|
|
|
|
((BeGlobalVariable*)val)->mUnnamedAddr = true;
|
|
}
|
|
break;
|
|
case BfIRCmd_GlobalVar_SetInitializer:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
CMD_PARAM(BeConstant*, initializer);
|
|
|
|
BF_ASSERT(BeValueDynCast<BeGlobalVariable>(val) != NULL);
|
|
|
|
auto globalVariable = (BeGlobalVariable*)val;
|
|
globalVariable->mInitializer = initializer;
|
|
|
|
if (globalVariable->mInitializer != NULL)
|
|
{
|
|
globalVariable->mAlign = globalVariable->mType->mAlign;
|
|
BF_ASSERT(globalVariable->mAlign != -1);
|
|
}
|
|
}
|
|
break;
|
|
case BfIRCmd_GlobalVar_SetAlignment:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
CMD_PARAM(int, alignment);
|
|
|
|
BF_ASSERT(BeValueDynCast<BeGlobalVariable>(val) != NULL);
|
|
|
|
auto globalVariable = (BeGlobalVariable*)val;
|
|
globalVariable->mAlign = alignment;
|
|
BF_ASSERT(alignment > 0);
|
|
|
|
if (globalVariable->mInitializer != NULL)
|
|
{
|
|
BF_ASSERT(globalVariable->mAlign != -1);
|
|
}
|
|
}
|
|
break;
|
|
case BfIRCmd_GlobalVar_SetStorageKind:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
CMD_PARAM(int, storageKind);
|
|
|
|
BF_ASSERT(BeValueDynCast<BeGlobalVariable>(val) != NULL);
|
|
|
|
auto globalVariable = (BeGlobalVariable*)val;
|
|
globalVariable->mStorageKind = (BfIRStorageKind)storageKind;
|
|
}
|
|
break;
|
|
case BfIRCmd_GlobalStringPtr:
|
|
{
|
|
CMD_PARAM(String, str);
|
|
|
|
auto constStruct = mBeModule->mOwnedValues.Alloc<BeStringConstant>();
|
|
constStruct->mString = str;
|
|
auto charType = mBeContext->GetPrimitiveType(BeTypeCode_Int8);
|
|
constStruct->mType = mBeContext->CreateSizedArrayType(charType, str.length() + 1);
|
|
|
|
auto globalVariable = mBeModule->mGlobalVariables.Alloc();
|
|
globalVariable->mModule = mBeModule;
|
|
globalVariable->mType = constStruct->mType;
|
|
globalVariable->mIsConstant = true;
|
|
globalVariable->mLinkageType = BfIRLinkageType_Internal;
|
|
globalVariable->mInitializer = constStruct;
|
|
globalVariable->mName = StrFormat("__str%d", (int)mBeModule->mGlobalVariables.size() - 1);
|
|
globalVariable->mIsTLS = false;
|
|
globalVariable->mAlign = 1;
|
|
globalVariable->mUnnamedAddr = false;
|
|
|
|
auto castedVal = mBeModule->mAlloc.Alloc<BeCastConstant>();
|
|
castedVal->mType = mBeContext->GetPointerTo(charType);
|
|
castedVal->mTarget = globalVariable;
|
|
SetResult(curId, castedVal);
|
|
|
|
//SetResult(curId, globalVariable);
|
|
}
|
|
break;
|
|
case BfIRCmd_SetReflectTypeData:
|
|
{
|
|
CMD_PARAM(BeType*, type);
|
|
CMD_PARAM(BeValue*, value);
|
|
mReflectDataMap[type] = value;
|
|
}
|
|
break;
|
|
case BfIRCmd_CreateBlock:
|
|
{
|
|
CMD_PARAM(String, name);
|
|
CMD_PARAM(bool, addNow);
|
|
auto block = mBeModule->CreateBlock(name);
|
|
if (addNow)
|
|
mBeModule->AddBlock(mActiveFunction, block);
|
|
|
|
SetResult(curId, block);
|
|
}
|
|
break;
|
|
case BfIRCmd_MaybeChainNewBlock:
|
|
{
|
|
CMD_PARAM(String, name);
|
|
auto newBlock = mBeModule->GetInsertBlock();
|
|
if (!newBlock->IsEmpty())
|
|
{
|
|
auto bb = mBeModule->CreateBlock(name);
|
|
mBeModule->CreateBr(bb);
|
|
mBeModule->AddBlock(mActiveFunction, bb);
|
|
mBeModule->SetInsertPoint(bb);
|
|
newBlock = bb;
|
|
}
|
|
SetResult(curId, newBlock);
|
|
}
|
|
break;
|
|
case BfIRCmd_AddBlock:
|
|
{
|
|
CMD_PARAM(BeBlock*, block);
|
|
mBeModule->AddBlock(mActiveFunction, block);
|
|
}
|
|
break;
|
|
case BfIRCmd_DropBlocks:
|
|
{
|
|
CMD_PARAM(BeBlock*, startingBlock);
|
|
auto& basicBlockList = mActiveFunction->mBlocks;
|
|
int postExitBlockIdx = -1;
|
|
|
|
/*auto itr = basicBlockList.begin();
|
|
while (itr != basicBlockList.end())
|
|
{
|
|
auto block = *itr;
|
|
if (block == startingBlock)
|
|
{
|
|
basicBlockList.erase(itr, basicBlockList.end());
|
|
break;
|
|
}
|
|
++itr;
|
|
}*/
|
|
|
|
for (int i = 0; i < (int)basicBlockList.size(); i++)
|
|
{
|
|
if (basicBlockList[i] == startingBlock)
|
|
{
|
|
basicBlockList.RemoveRange(i, basicBlockList.size() - i);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case BfIRCmd_MergeBlockDown:
|
|
{
|
|
CMD_PARAM(BeBlock*, fromBlock);
|
|
CMD_PARAM(BeBlock*, intoBlock);
|
|
for (auto inst : fromBlock->mInstructions)
|
|
inst->mParentBlock = intoBlock;
|
|
if (!fromBlock->mInstructions.IsEmpty())
|
|
intoBlock->mInstructions.Insert(0, &fromBlock->mInstructions[0], fromBlock->mInstructions.size());
|
|
mBeModule->RemoveBlock(mActiveFunction, fromBlock);
|
|
}
|
|
break;
|
|
case BfIRCmd_GetInsertBlock:
|
|
{
|
|
SetResult(curId, mBeModule->mActiveBlock);
|
|
}
|
|
break;
|
|
case BfIRCmd_SetInsertPoint:
|
|
{
|
|
CMD_PARAM(BeBlock*, block);
|
|
mBeModule->SetInsertPoint(block);
|
|
}
|
|
break;
|
|
case BfIRCmd_SetInsertPointAtStart:
|
|
{
|
|
CMD_PARAM(BeBlock*, block);
|
|
mBeModule->SetInsertPointAtStart(block);
|
|
}
|
|
break;
|
|
case BfIRCmd_EraseFromParent:
|
|
{
|
|
CMD_PARAM(BeBlock*, block);
|
|
mBeModule->RemoveBlock(mActiveFunction, block);
|
|
}
|
|
break;
|
|
case BfIRCmd_DeleteBlock:
|
|
{
|
|
CMD_PARAM(BeBlock*, block);
|
|
}
|
|
break;
|
|
case BfIRCmd_EraseInstFromParent:
|
|
{
|
|
CMD_PARAM(BeValue*, instVal);
|
|
|
|
BeInst* inst = (BeInst*)instVal;
|
|
bool wasRemoved = inst->mParentBlock->mInstructions.Remove(inst);
|
|
BF_ASSERT(wasRemoved);
|
|
#ifdef _DEBUG
|
|
inst->mWasRemoved = true;
|
|
#endif
|
|
}
|
|
break;
|
|
case BfIRCmd_CreateBr:
|
|
{
|
|
CMD_PARAM(BeBlock*, block);
|
|
mBeModule->CreateBr(block);
|
|
}
|
|
break;
|
|
case BfIRCmd_CreateBr_Fake:
|
|
{
|
|
CMD_PARAM(BeBlock*, block);
|
|
auto inst = mBeModule->CreateBr(block);
|
|
inst->mIsFake = true;
|
|
}
|
|
break;
|
|
case BfIRCmd_CreateBr_NoCollapse:
|
|
{
|
|
CMD_PARAM(BeBlock*, block);
|
|
auto inst = mBeModule->CreateBr(block);
|
|
inst->mNoCollapse = true;
|
|
}
|
|
break;
|
|
case BfIRCmd_CreateCondBr:
|
|
{
|
|
CMD_PARAM(BeValue*, condVal);
|
|
CMD_PARAM(BeBlock*, trueBlock);
|
|
CMD_PARAM(BeBlock*, falseBlock);
|
|
mBeModule->CreateCondBr(condVal, trueBlock, falseBlock);
|
|
}
|
|
break;
|
|
case BfIRCmd_MoveBlockToEnd:
|
|
{
|
|
CMD_PARAM(BeBlock*, block);
|
|
mBeModule->RemoveBlock(mActiveFunction, block);
|
|
mBeModule->AddBlock(mActiveFunction, block);
|
|
}
|
|
break;
|
|
case BfIRCmd_CreateSwitch:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
CMD_PARAM(BeBlock*, dest);
|
|
CMD_PARAM(int, numCases);
|
|
|
|
auto switchInst = mBeModule->AllocInstOwned<BeSwitchInst>();
|
|
switchInst->mValue = val;
|
|
switchInst->mDefaultBlock = dest;
|
|
switchInst->mCases.Reserve(numCases);
|
|
SetResult(curId, switchInst);
|
|
}
|
|
break;
|
|
case BfIRCmd_AddSwitchCase:
|
|
{
|
|
CMD_PARAM(BeValue*, switchVal);
|
|
CMD_PARAM(BeValue*, caseVal);
|
|
CMD_PARAM(BeBlock*, caseBlock);
|
|
|
|
BeSwitchCase switchCase;
|
|
switchCase.mValue = (BeConstant*)caseVal;
|
|
switchCase.mBlock = caseBlock;
|
|
((BeSwitchInst*)switchVal)->mCases.push_back(switchCase);
|
|
}
|
|
break;
|
|
case BfIRCmd_SetSwitchDefaultDest:
|
|
{
|
|
CMD_PARAM(BeValue*, switchVal);
|
|
CMD_PARAM(BeBlock*, caseBlock);
|
|
((BeSwitchInst*)switchVal)->mDefaultBlock = caseBlock;
|
|
}
|
|
break;
|
|
case BfIRCmd_CreatePhi:
|
|
{
|
|
CMD_PARAM(BeType*, type);
|
|
CMD_PARAM(int, incomingCount);
|
|
|
|
auto phiInst = mBeModule->AllocInstOwned<BePhiInst>();
|
|
phiInst->mType = type;
|
|
SetResult(curId, phiInst);
|
|
}
|
|
break;
|
|
case BfIRCmd_AddPhiIncoming:
|
|
{
|
|
CMD_PARAM(BeValue*, phiValue);
|
|
CMD_PARAM(BeValue*, value);
|
|
CMD_PARAM(BeBlock*, comingFrom);
|
|
|
|
BF_ASSERT(phiValue->GetType() == value->GetType());
|
|
|
|
auto phiIncoming = mBeModule->mAlloc.Alloc<BePhiIncoming>();
|
|
phiIncoming->mBlock = comingFrom;
|
|
phiIncoming->mValue = value;
|
|
|
|
((BePhiInst*)phiValue)->mIncoming.push_back(phiIncoming);
|
|
}
|
|
break;
|
|
case BfIRCmd_GetIntrinsic:
|
|
{
|
|
CMD_PARAM(String, intrinName);
|
|
CMD_PARAM(int, intrinId);
|
|
CMD_PARAM(BeType*, returnType);
|
|
CMD_PARAM(CmdParamVec<BeType*>, paramTypes);
|
|
|
|
auto intrin = mBeModule->mAlloc.Alloc<BeIntrinsic>();
|
|
intrin->mName = intrinName;
|
|
intrin->mKind = (BfIRIntrinsic)intrinId;
|
|
intrin->mReturnType = returnType;
|
|
SetResult(curId, intrin);
|
|
}
|
|
break;
|
|
case BfIRCmd_CreateFunctionType:
|
|
{
|
|
CMD_PARAM(BeType*, resultType);
|
|
CMD_PARAM(CmdParamVec<BeType*>, paramTypes);
|
|
CMD_PARAM(bool, isVarArg);
|
|
auto functionType = mBeContext->CreateFunctionType(resultType, paramTypes, isVarArg);
|
|
SetResult(curId, functionType);
|
|
}
|
|
break;
|
|
case BfIRCmd_CreateFunction:
|
|
{
|
|
CMD_PARAM(BeFunctionType*, type);
|
|
BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read();
|
|
CMD_PARAM(String, name);
|
|
SetResult(curId, mBeModule->CreateFunction(type, linkageType, name));
|
|
}
|
|
break;
|
|
case BfIRCmd_SetFunctionName:
|
|
{
|
|
CMD_PARAM(BeValue*, func);
|
|
CMD_PARAM(String, name);
|
|
BeFunction* beFunc = BeValueDynCast<BeFunction>(func);
|
|
beFunc->mName = name;
|
|
}
|
|
break;
|
|
case BfIRCmd_EnsureFunctionPatchable:
|
|
{
|
|
}
|
|
break;
|
|
case BfIRCmd_RemapBindFunction:
|
|
{
|
|
CMD_PARAM(BeValue*, func);
|
|
// We need to store this value to a data segment so we get a symbol we can remap during hot swap
|
|
// We actually do this to ensure that we don't bind to the NEW method but rather the old one- so
|
|
// delegate equality checks still work
|
|
|
|
BeFunction* beFunc = BeValueDynCast<BeFunction>(func);
|
|
if (beFunc != NULL)
|
|
{
|
|
if (beFunc->mRemapBindVar == NULL)
|
|
{
|
|
auto globalVariable = mBeModule->mGlobalVariables.Alloc();
|
|
globalVariable->mModule = mBeModule;
|
|
globalVariable->mType = beFunc->mType;
|
|
globalVariable->mIsConstant = true;
|
|
globalVariable->mLinkageType = BfIRLinkageType_External;
|
|
globalVariable->mInitializer = beFunc;
|
|
globalVariable->mName = StrFormat("bf_hs_preserve@%s_%s", beFunc->mName.c_str(), mBeModule->mModuleName.c_str());
|
|
globalVariable->mIsTLS = false;
|
|
globalVariable->mAlign = 8;
|
|
globalVariable->mUnnamedAddr = false;
|
|
beFunc->mRemapBindVar = globalVariable;
|
|
|
|
/*if (mBeModule->mDbgModule != NULL)
|
|
{
|
|
auto dbgGlobalVariable = mBeModule->mDbgModule->mGlobalVariables.Alloc();
|
|
dbgGlobalVariable->mContext = mBeContext;
|
|
dbgGlobalVariable->mName = name;
|
|
dbgGlobalVariable->mLinkageName = globalVariable->mName;
|
|
dbgGlobalVariable->mFile = (BeDbgFile*)file;
|
|
dbgGlobalVariable->mLineNum = lineNum;
|
|
dbgGlobalVariable->mType = (BeDbgType*)type;
|
|
dbgGlobalVariable->mIsLocalToUnit = isLocalToUnit;
|
|
dbgGlobalVariable->mValue = val;
|
|
dbgGlobalVariable->mDecl = decl;
|
|
}*/
|
|
}
|
|
|
|
SetResult(curId, mBeModule->CreateLoad(beFunc->mRemapBindVar, false));
|
|
}
|
|
else
|
|
SetResult(curId, func);
|
|
}
|
|
break;
|
|
case BfIRCmd_SetActiveFunction:
|
|
{
|
|
CMD_PARAM(BeFunction*, func);
|
|
mActiveFunction = func;
|
|
mBeModule->mActiveFunction = func;
|
|
}
|
|
break;
|
|
case BfIRCmd_CreateCall:
|
|
{
|
|
CMD_PARAM(BeValue*, func);
|
|
CMD_PARAM(CmdParamVec<BeValue*>, args);
|
|
|
|
#ifdef BE_EXTRA_CHECKS
|
|
auto funcPtrType = func->GetType();
|
|
if (funcPtrType != NULL)
|
|
{
|
|
BF_ASSERT(funcPtrType->IsPointer());
|
|
auto funcType = (BeFunctionType*)((BePointerType*)funcPtrType)->mElementType;
|
|
BF_ASSERT(funcType->mTypeCode == BeTypeCode_Function);
|
|
|
|
bool argsMatched = true;
|
|
if (!funcType->mIsVarArg)
|
|
{
|
|
if (funcType->mParams.size() != args.size())
|
|
{
|
|
argsMatched = false;
|
|
}
|
|
else
|
|
{
|
|
int argIdx = 0;
|
|
for (int argIdx = 0; argIdx < (int)args.size(); argIdx++)
|
|
{
|
|
if (args[argIdx] == NULL)
|
|
argsMatched = false;
|
|
else if (funcType->mParams[argIdx].mType != args[argIdx]->GetType())
|
|
argsMatched = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!argsMatched)
|
|
{
|
|
String errStr;
|
|
errStr += "BfIRCmd_CreateCall Match Failure:\n";
|
|
BeDumpContext dumpCtx;
|
|
dumpCtx.ToString(errStr, func);
|
|
errStr += "\n";
|
|
dumpCtx.ToString(errStr, funcType);
|
|
errStr += "\n";
|
|
for (int argIdx = 0; argIdx < (int)args.size(); argIdx++)
|
|
{
|
|
errStr += StrFormat("ARG #%d: ", argIdx);
|
|
dumpCtx.ToString(errStr, args[argIdx]);
|
|
errStr += "\n";
|
|
}
|
|
FatalError(errStr);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
BF_ASSERT(func->GetTypeId() == BeIntrinsic::TypeId);
|
|
}
|
|
#endif
|
|
SetResult(curId, mBeModule->CreateCall(func, args));
|
|
}
|
|
break;
|
|
case BfIRCmd_SetCallCallingConv:
|
|
{
|
|
CMD_PARAM(BeValue*, callInst);
|
|
BfIRCallingConv callingConv = (BfIRCallingConv)mStream->Read();
|
|
((BeCallInst*)callInst)->mCallingConv = callingConv;
|
|
}
|
|
break;
|
|
case BfIRCmd_SetFuncCallingConv:
|
|
{
|
|
CMD_PARAM(BeFunction*, func);
|
|
BfIRCallingConv callingConv = (BfIRCallingConv)mStream->Read();
|
|
func->mCallingConv = callingConv;
|
|
}
|
|
break;
|
|
case BfIRCmd_SetTailCall:
|
|
{
|
|
CMD_PARAM(BeValue*, callInstVal);
|
|
BeCallInst* callInst = (BeCallInst*)callInstVal;
|
|
callInst->mTailCall = true;
|
|
}
|
|
break;
|
|
case BfIRCmd_SetCallAttribute:
|
|
{
|
|
CMD_PARAM(BeValue*, callInstVal);
|
|
CMD_PARAM(int, paramIdx);
|
|
BfIRAttribute attribute = (BfIRAttribute)mStream->Read();
|
|
BeCallInst* callInst = (BeCallInst*)callInstVal;
|
|
if (attribute == BfIRAttribute_NoReturn)
|
|
callInst->mNoReturn = true;
|
|
}
|
|
break;
|
|
case BfIRCmd_CreateRet:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
#ifdef BE_EXTRA_CHECKS
|
|
auto retType = val->GetType();
|
|
auto funcType = mActiveFunction->GetFuncType();
|
|
BF_ASSERT(retType == funcType->mReturnType);
|
|
#endif
|
|
SetResult(curId, mBeModule->CreateRet(val));
|
|
}
|
|
break;
|
|
case BfIRCmd_CreateSetRet:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
CMD_PARAM(int, returnTypeId);
|
|
SetResult(curId, mBeModule->CreateSetRet(val, returnTypeId));
|
|
}
|
|
break;
|
|
case BfIRCmd_CreateRetVoid:
|
|
{
|
|
mBeModule->CreateRetVoid();
|
|
}
|
|
break;
|
|
case BfIRCmd_CreateUnreachable:
|
|
{
|
|
mBeModule->AllocInst<BeUnreachableInst>();
|
|
}
|
|
break;
|
|
case BfIRCmd_Call_AddAttribute:
|
|
{
|
|
CMD_PARAM(BeValue*, callInstVal);
|
|
CMD_PARAM(int, argIdx);
|
|
BfIRAttribute attribute = (BfIRAttribute)mStream->Read();
|
|
BeCallInst* callInst = (BeCallInst*)callInstVal;
|
|
if (argIdx > 0)
|
|
{
|
|
if (attribute == BfIRAttribute_StructRet)
|
|
{
|
|
auto valType = callInst->mArgs[argIdx - 1].mValue->GetType();
|
|
BF_ASSERT(valType->IsPointer());
|
|
callInst->mArgs[argIdx - 1].mStructRet = true;
|
|
}
|
|
else if (attribute == BfIRAttribute_ZExt)
|
|
callInst->mArgs[argIdx - 1].mZExt = true;
|
|
else if (attribute == BfIRAttribute_NoAlias)
|
|
callInst->mArgs[argIdx - 1].mNoAlias = true;
|
|
else if (attribute == BfIRAttribute_NoCapture)
|
|
callInst->mArgs[argIdx - 1].mNoCapture = true;
|
|
else if (attribute == BfIRAttribute_ByVal)
|
|
{
|
|
}
|
|
else
|
|
BF_FATAL("Unhandled");
|
|
}
|
|
else
|
|
{
|
|
if (attribute == BfIRAttribute_NoReturn)
|
|
callInst->mNoReturn = true;
|
|
else
|
|
BF_FATAL("Unhandled");
|
|
}
|
|
}
|
|
break;
|
|
case BfIRCmd_Call_AddAttribute1:
|
|
{
|
|
CMD_PARAM(BeValue*, inst);
|
|
CMD_PARAM(int, argIdx);
|
|
BfIRAttribute attribute = (BfIRAttribute)mStream->Read();
|
|
CMD_PARAM(int, arg);
|
|
|
|
BeCallInst* callInst = BeValueDynCast<BeCallInst>(inst);
|
|
if (callInst != NULL)
|
|
{
|
|
if (argIdx > 0)
|
|
{
|
|
if (attribute == BfIRAttribute_Dereferencable)
|
|
{
|
|
callInst->mArgs[argIdx - 1].mDereferenceableSize = arg;
|
|
if (auto func = BeValueDynCast<BeFunction>(callInst->mFunc))
|
|
{
|
|
BF_ASSERT(func->mParams[argIdx - 1].mDereferenceableSize == arg);
|
|
}
|
|
}
|
|
else if (attribute == BfIRAttribute_ByVal)
|
|
{
|
|
callInst->mArgs[argIdx - 1].mByRefSize = arg;
|
|
if (auto func = BeValueDynCast<BeFunction>(callInst->mFunc))
|
|
{
|
|
BF_ASSERT((func->mParams[argIdx - 1].mByValSize == arg) || (func->mParams[argIdx - 1].mByValSize == -1));
|
|
}
|
|
}
|
|
else
|
|
BF_FATAL("Unhandled");
|
|
}
|
|
else
|
|
{
|
|
BF_FATAL("Unhandled");
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case BfIRCmd_Func_AddAttribute:
|
|
{
|
|
CMD_PARAM(BeFunction*, func);
|
|
CMD_PARAM(int, argIdx);
|
|
BfIRAttribute attribute = (BfIRAttribute)mStream->Read();
|
|
if (argIdx > 0)
|
|
{
|
|
if (attribute == BfIRAttribute_StructRet)
|
|
func->mParams[argIdx - 1].mStructRet = true;
|
|
else if (attribute == BfIRAttribute_NoAlias)
|
|
func->mParams[argIdx - 1].mNoAlias = true;
|
|
else if (attribute == BfIRAttribute_NoCapture)
|
|
func->mParams[argIdx - 1].mNoCapture = true;
|
|
else if (attribute == BfIRAttribute_ZExt)
|
|
func->mParams[argIdx - 1].mZExt = true;
|
|
else
|
|
BF_FATAL("Unhandled");
|
|
}
|
|
else
|
|
{
|
|
if (attribute == BfIRAttribute_VarRet)
|
|
func->mIsVarReturn = true;
|
|
else if (attribute == BFIRAttribute_AlwaysInline)
|
|
func->mAlwaysInline = true;
|
|
else if (attribute == BFIRAttribute_NoUnwind)
|
|
func->mNoUnwind = true;
|
|
else if (attribute == BFIRAttribute_UWTable)
|
|
func->mUWTable = true;
|
|
else if (attribute == BfIRAttribute_NoReturn)
|
|
func->mNoReturn = true;
|
|
else if (attribute == BFIRAttribute_NoFramePointerElim)
|
|
func->mNoFramePointerElim = true;
|
|
else if (attribute == BFIRAttribute_DllExport)
|
|
func->mIsDLLExport = true;
|
|
else if (attribute == BFIRAttribute_DllImport)
|
|
func->mIsDLLImport = true;
|
|
else if (attribute == BFIRAttribute_NoRecurse)
|
|
{
|
|
}
|
|
else if (attribute == BFIRAttribute_Constructor)
|
|
{
|
|
}
|
|
else if (attribute == BFIRAttribute_Destructor)
|
|
{
|
|
}
|
|
else
|
|
BF_FATAL("Unhandled");
|
|
}
|
|
}
|
|
break;
|
|
case BfIRCmd_Func_AddAttribute1:
|
|
{
|
|
CMD_PARAM(BeFunction*, func);
|
|
CMD_PARAM(int, argIdx);
|
|
BfIRAttribute attribute = (BfIRAttribute)mStream->Read();
|
|
CMD_PARAM(int, arg);
|
|
// This is for adding things like Dereferencable, which we don't use
|
|
|
|
if (argIdx > 0)
|
|
{
|
|
if (attribute == BfIRAttribute_Dereferencable)
|
|
func->mParams[argIdx - 1].mDereferenceableSize = arg;
|
|
else if (attribute == BfIRAttribute_ByVal)
|
|
func->mParams[argIdx - 1].mByValSize = arg;
|
|
else
|
|
BF_FATAL("Unhandled");
|
|
}
|
|
else
|
|
BF_FATAL("Unhandled");
|
|
}
|
|
break;
|
|
case BfIRCmd_Func_SetParamName:
|
|
{
|
|
CMD_PARAM(BeFunction*, func);
|
|
CMD_PARAM(int, argIdx);
|
|
CMD_PARAM(String, name);
|
|
if (argIdx > 0)
|
|
func->mParams[argIdx - 1].mName = name;
|
|
}
|
|
break;
|
|
case BfIRCmd_Func_DeleteBody:
|
|
{
|
|
CMD_PARAM(BeFunction*, func);
|
|
func->mBlocks.Clear();
|
|
}
|
|
break;
|
|
case BfIRCmd_Func_SafeRename:
|
|
{
|
|
CMD_PARAM(BeFunction*, func);
|
|
func->mName += StrFormat("__RENAME%d", curId);
|
|
}
|
|
break;
|
|
case BfIRCmd_Func_SafeRenameFrom:
|
|
{
|
|
CMD_PARAM(BeFunction*, func);
|
|
CMD_PARAM(String, prevName);
|
|
if (func->mName == prevName)
|
|
func->mName += StrFormat("__RENAME%d", curId);
|
|
}
|
|
break;
|
|
case BfIRCmd_Func_SetLinkage:
|
|
{
|
|
CMD_PARAM(BeFunction*, func);
|
|
BfIRLinkageType linkageType = (BfIRLinkageType)mStream->Read();
|
|
func->mLinkageType = linkageType;
|
|
}
|
|
break;
|
|
case BfIRCmd_SaveDebugLocation:
|
|
{
|
|
mSavedDebugLocs.push_back(mBeModule->GetCurrentDebugLocation());
|
|
}
|
|
break;
|
|
case BfIRCmd_RestoreDebugLocation:
|
|
{
|
|
mBeModule->SetCurrentDebugLocation(mSavedDebugLocs[mSavedDebugLocs.size() - 1]);
|
|
mSavedDebugLocs.pop_back();
|
|
}
|
|
break;
|
|
case BfIRCmd_DupDebugLocation:
|
|
{
|
|
mBeModule->DupCurrentDebugLocation();
|
|
}
|
|
break;
|
|
case BfIRCmd_ClearDebugLocation:
|
|
{
|
|
mBeModule->SetCurrentDebugLocation(NULL);
|
|
}
|
|
break;
|
|
case BfIRCmd_ClearDebugLocationInst:
|
|
{
|
|
CMD_PARAM(BeValue*, instValue);
|
|
auto inst = (BeInst*)instValue;
|
|
inst->mDbgLoc = NULL;
|
|
}
|
|
break;
|
|
case BfIRCmd_ClearDebugLocationInstLast:
|
|
{
|
|
if ((mBeModule->mActiveBlock != NULL) && (!mBeModule->mActiveBlock->mInstructions.IsEmpty()))
|
|
{
|
|
auto inst = mBeModule->mActiveBlock->mInstructions.back();
|
|
inst->mDbgLoc = NULL;
|
|
}
|
|
}
|
|
break;
|
|
case BfIRCmd_UpdateDebugLocation:
|
|
{
|
|
CMD_PARAM(BeValue*, instValue);
|
|
auto inst = (BeInst*)instValue;
|
|
inst->mDbgLoc = mBeModule->mCurDbgLoc;
|
|
}
|
|
break;
|
|
case BfIRCmd_SetCurrentDebugLocation:
|
|
{
|
|
CMD_PARAM(int, line);
|
|
CMD_PARAM(int, column);
|
|
CMD_PARAM(BeMDNode*, diScope);
|
|
CMD_PARAM(BeMDNode*, diInlinedAt);
|
|
BF_ASSERT(diScope != NULL);
|
|
mBeModule->SetCurrentDebugLocation(line - 1, column - 1, diScope, (BeDbgLoc*)diInlinedAt);
|
|
}
|
|
break;
|
|
case BfIRCmd_Nop:
|
|
{
|
|
mBeModule->CreateNop();
|
|
}
|
|
break;
|
|
case BfIRCmd_EnsureInstructionAt:
|
|
{
|
|
mBeModule->AllocInst<BeEnsureInstructionAtInst>();
|
|
}
|
|
break;
|
|
case BfIRCmd_StatementStart:
|
|
{
|
|
}
|
|
break;
|
|
case BfIRCmd_ObjectAccessCheck:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
CMD_PARAM(bool, useAsm);
|
|
|
|
auto inst = mBeModule->AllocInst<BeObjectAccessCheckInst>();
|
|
inst->mValue = val;
|
|
|
|
SetResult(curId, mBeModule->GetInsertBlock());
|
|
}
|
|
break;
|
|
case BfIRCmd_Comptime_Error:
|
|
{
|
|
CMD_PARAM(int32, error);
|
|
|
|
auto inst = mBeModule->AllocInst<BeComptimeError>();
|
|
inst->mError = error;
|
|
SetResult(curId, inst);
|
|
}
|
|
break;
|
|
case BfIRCmd_Comptime_GetBfType:
|
|
{
|
|
CMD_PARAM(int32, typeId);
|
|
CMD_PARAM(BeType*, resultType);
|
|
|
|
auto inst = mBeModule->AllocInst<BeComptimeGetType>();
|
|
inst->mTypeId = typeId;
|
|
inst->mResultType = resultType;
|
|
SetResult(curId, inst);
|
|
}
|
|
break;
|
|
case BfIRCmd_Comptime_GetReflectType:
|
|
{
|
|
CMD_PARAM(int32, typeId);
|
|
CMD_PARAM(BeType*, resultType);
|
|
|
|
auto inst = mBeModule->AllocInst<BeComptimeGetReflectType>();
|
|
inst->mTypeId = typeId;
|
|
inst->mResultType = resultType;
|
|
SetResult(curId, inst);
|
|
}
|
|
break;
|
|
case BfIRCmd_Comptime_DynamicCastCheck:
|
|
{
|
|
CMD_PARAM(BeValue*, value);
|
|
CMD_PARAM(int32, typeId);
|
|
CMD_PARAM(BeType*, resultType);
|
|
|
|
auto inst = mBeModule->AllocInst<BeComptimeDynamicCastCheck>();
|
|
inst->mValue = value;
|
|
inst->mTypeId = typeId;
|
|
inst->mResultType = resultType;
|
|
SetResult(curId, inst);
|
|
}
|
|
break;
|
|
case BfIRCmd_Comptime_GetVirtualFunc:
|
|
{
|
|
CMD_PARAM(BeValue*, value);
|
|
CMD_PARAM(int32, virtualTableIdx);
|
|
CMD_PARAM(BeType*, resultType);
|
|
|
|
auto inst = mBeModule->AllocInst<BeComptimeGetVirtualFunc>();
|
|
inst->mValue = value;
|
|
inst->mVirtualTableIdx = virtualTableIdx;
|
|
inst->mResultType = resultType;
|
|
SetResult(curId, inst);
|
|
}
|
|
break;
|
|
case BfIRCmd_Comptime_GetInterfaceFunc:
|
|
{
|
|
CMD_PARAM(BeValue*, value);
|
|
CMD_PARAM(int32, ifaceTypeId);
|
|
CMD_PARAM(int32, methodIdx);
|
|
CMD_PARAM(BeType*, resultType);
|
|
|
|
auto inst = mBeModule->AllocInst<BeComptimeGetInterfaceFunc>();
|
|
inst->mValue = value;
|
|
inst->mIFaceTypeId = ifaceTypeId;
|
|
inst->mMethodIdx = methodIdx;
|
|
inst->mResultType = resultType;
|
|
SetResult(curId, inst);
|
|
}
|
|
break;
|
|
|
|
case BfIRCmd_DbgInit:
|
|
{
|
|
/*mDIBuilder = new BeDIBuilder(*mBeModule); */
|
|
mBeModule->mDbgModule = new BeDbgModule();
|
|
mBeModule->mDbgModule->mBeModule = mBeModule;
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgFinalize:
|
|
{
|
|
/*for (auto typeEntryPair : mTypes)
|
|
{
|
|
auto& typeEntry = typeEntryPair.second;
|
|
if (typeEntry.mInstDIType != NULL)
|
|
typeEntry.mInstDIType->resolveCycles();
|
|
}
|
|
mDIBuilder->finalize();*/
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgCreateCompileUnit:
|
|
{
|
|
CMD_PARAM(int, lang);
|
|
CMD_PARAM(String, fileName);
|
|
CMD_PARAM(String, directory);
|
|
CMD_PARAM(String, producer);
|
|
CMD_PARAM(bool, isOptimized);
|
|
CMD_PARAM(String, flags);
|
|
CMD_PARAM(int, runtimeVer);
|
|
CMD_PARAM(bool, linesOnly);
|
|
|
|
mBeModule->mDbgModule->mFileName = fileName;
|
|
mBeModule->mDbgModule->mDirectory = directory;
|
|
mBeModule->mDbgModule->mProducer = producer;
|
|
|
|
//mDebugging = fileName == "TestToots";
|
|
|
|
SetResult(curId, mBeModule->mDbgModule);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgCreateFile:
|
|
{
|
|
CMD_PARAM(String, fileName);
|
|
CMD_PARAM(String, directory);
|
|
CMD_PARAM(Val128, md5Hash);
|
|
|
|
auto dbgFile = mBeModule->mDbgModule->mFiles.Alloc();
|
|
dbgFile->mFileName = fileName;
|
|
dbgFile->mDirectory = directory;
|
|
dbgFile->mMD5Hash = md5Hash;
|
|
dbgFile->mIdx = (int)mBeModule->mDbgModule->mFiles.size() - 1;
|
|
|
|
SetResult(curId, dbgFile);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgGetCurrentLocation:
|
|
{
|
|
SetResult(curId, mBeModule->mCurDbgLoc);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgSetType:
|
|
{
|
|
CMD_PARAM(int, typeId);
|
|
CMD_PARAM(BeMDNode*, type);
|
|
auto& typeEntry = GetTypeEntry(typeId);
|
|
typeEntry.mDIType = BeValueDynCast<BeDbgType>(type);
|
|
if (typeEntry.mInstDIType == NULL)
|
|
typeEntry.mInstDIType = BeValueDynCast<BeDbgType>(type);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgSetInstType:
|
|
{
|
|
CMD_PARAM(int, typeId);
|
|
CMD_PARAM(BeMDNode*, type);
|
|
GetTypeEntry(typeId).mInstDIType = BeValueDynCast<BeDbgType>(type);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgGetType:
|
|
{
|
|
CMD_PARAM(int, typeId);
|
|
|
|
if (mBeModule->mCeMachine != NULL)
|
|
{
|
|
auto dbgType = mBeModule->mDbgModule->mTypes.Alloc<BeDbgTypeId>();
|
|
dbgType->mTypeId = typeId;
|
|
SetResult(curId, dbgType);
|
|
}
|
|
else
|
|
SetResult(curId, GetTypeEntry(typeId).mDIType);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgGetTypeInst:
|
|
{
|
|
CMD_PARAM(int, typeId);
|
|
auto result = GetTypeEntry(typeId).mInstDIType;
|
|
//BF_ASSERT(result);
|
|
SetResult(curId, result);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgTrackDITypes:
|
|
{
|
|
CMD_PARAM(int, typeId);
|
|
auto& typeEntry = GetTypeEntry(typeId);
|
|
|
|
/*if (typeEntry.mDIType != NULL)
|
|
BeMetadataTracking::track(*(BeMetadata**)&typeEntry.mDIType);
|
|
if (typeEntry.mInstDIType != NULL)
|
|
BeMetadataTracking::track(*(BeMetadata**)&typeEntry.mInstDIType);*/
|
|
//NotImpl();
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgCreateNamespace:
|
|
{
|
|
CMD_PARAM(BeMDNode*, scope);
|
|
CMD_PARAM(String, name);
|
|
CMD_PARAM(BeMDNode*, file);
|
|
CMD_PARAM(int, lineNum);
|
|
|
|
auto dbgNamespace = mBeModule->mOwnedValues.Alloc<BeDbgNamespace>();
|
|
dbgNamespace->mScope = scope;
|
|
dbgNamespace->mName = name;
|
|
SetResult(curId, dbgNamespace);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgCreateImportedModule:
|
|
{
|
|
CMD_PARAM(BeMDNode*, context);
|
|
CMD_PARAM(BeMDNode*, namespaceNode);
|
|
CMD_PARAM(int, lineNum);
|
|
/*SetResult(curId, mDIBuilder->createImportedModule((BeDIScope*)context, (BeDINamespace*)namespaceNode, lineNum));*/
|
|
//NotImpl();
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgCreateBasicType:
|
|
{
|
|
CMD_PARAM(String, name);
|
|
CMD_PARAM(int64, sizeInBits);
|
|
CMD_PARAM(int64, alignInBits);
|
|
CMD_PARAM(int, encoding);
|
|
|
|
auto dbgType = mBeModule->mDbgModule->mTypes.Alloc<BeDbgBasicType>();
|
|
dbgType->mName = name;
|
|
dbgType->mSize = (int)(sizeInBits / 8);
|
|
dbgType->mAlign = (int)(alignInBits / 8);
|
|
dbgType->mEncoding = encoding;
|
|
|
|
SetResult(curId, dbgType);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgCreateStructType:
|
|
{
|
|
CMD_PARAM(BeMDNode*, context);
|
|
CMD_PARAM(String, name);
|
|
CMD_PARAM(BeMDNode*, file);
|
|
CMD_PARAM(int, lineNum);
|
|
CMD_PARAM(int64, sizeInBits);
|
|
CMD_PARAM(int64, alignInBits);
|
|
CMD_PARAM(int, flags);
|
|
CMD_PARAM(BeMDNode*, derivedFrom);
|
|
CMD_PARAM(CmdParamVec<BeMDNode*>, members);
|
|
|
|
auto dbgType = mBeModule->mDbgModule->mTypes.Alloc<BeDbgStructType>();
|
|
dbgType->mScope = context;
|
|
dbgType->mName = name;
|
|
dbgType->mSize = (int)(sizeInBits / 8);
|
|
dbgType->mAlign = (int)(alignInBits / 8);
|
|
dbgType->mDerivedFrom = BeValueDynCast<BeDbgType>(derivedFrom);
|
|
dbgType->mDefFile = (BeDbgFile*)file;
|
|
dbgType->mDefLine = lineNum - 1;
|
|
dbgType->mIsFullyDefined = true;
|
|
dbgType->SetMembers(members);
|
|
|
|
SetResult(curId, dbgType);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgCreateEnumerationType:
|
|
{
|
|
CMD_PARAM(BeMDNode*, context);
|
|
CMD_PARAM(String, name);
|
|
CMD_PARAM(BeMDNode*, file);
|
|
CMD_PARAM(int, lineNum);
|
|
CMD_PARAM(int64, sizeInBits);
|
|
CMD_PARAM(int64, alignInBits);
|
|
CMD_PARAM(CmdParamVec<BeMDNode*>, members);
|
|
CMD_PARAM(BeMDNode*, underlyingType);
|
|
|
|
auto dbgType = mBeModule->mDbgModule->mTypes.Alloc<BeDbgEnumType>();
|
|
dbgType->mScope = context;
|
|
dbgType->mName = name;
|
|
dbgType->mSize = (int)(sizeInBits / 8);
|
|
dbgType->mAlign = (int)(alignInBits / 8);
|
|
dbgType->mIsFullyDefined = true;
|
|
dbgType->mElementType = BeValueDynCast<BeDbgType>(underlyingType);
|
|
for (auto member : members)
|
|
{
|
|
if (auto enumMember = BeValueDynCast<BeDbgEnumMember>(member))
|
|
{
|
|
dbgType->mMembers.push_back(enumMember);
|
|
}
|
|
else
|
|
NotImpl();
|
|
}
|
|
|
|
//dbgType->mDefFile = (BeDbgFile*)file;
|
|
//dbgType->mDefLine = line - 1;
|
|
SetResult(curId, dbgType);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgCreatePointerType:
|
|
{
|
|
CMD_PARAM(BeMDNode*, elementTypeNode);
|
|
|
|
BeDbgType* elementType = BeValueDynCast<BeDbgType>(elementTypeNode);
|
|
if (elementType == NULL)
|
|
{
|
|
if (auto dbgTypeId = BeValueDynCast<BeDbgTypeId>(elementTypeNode))
|
|
{
|
|
auto bfElementType = mBeModule->mCeMachine->mCeModule->mContext->mTypes[dbgTypeId->mTypeId];
|
|
auto bfPtrType = mBeModule->mCeMachine->mCeModule->CreatePointerType(bfElementType);
|
|
|
|
auto dbgType = mBeModule->mDbgModule->mTypes.Alloc<BeDbgTypeId>();
|
|
dbgType->mTypeId = bfPtrType->mTypeId;
|
|
SetResult(curId, dbgType);
|
|
break;
|
|
}
|
|
}
|
|
|
|
BeDbgType* useType = elementType->FindDerivedType(BeDbgPointerType::TypeId);
|
|
if (useType == NULL)
|
|
{
|
|
auto dbgType = mBeModule->mDbgModule->mTypes.Alloc<BeDbgPointerType>();
|
|
dbgType->mElement = elementType;
|
|
dbgType->mSize = mPtrSize;
|
|
dbgType->mAlign = mPtrSize;
|
|
elementType->mDerivedTypes.PushFront(dbgType, &mBeModule->mAlloc);
|
|
useType = dbgType;
|
|
}
|
|
|
|
SetResult(curId, useType);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgCreateReferenceType:
|
|
{
|
|
CMD_PARAM(BeMDNode*, elementTypeNode);
|
|
|
|
BeDbgType* elementType = BeValueDynCast<BeDbgType>(elementTypeNode);
|
|
if (elementType == NULL)
|
|
{
|
|
if (auto dbgTypeId = BeValueDynCast<BeDbgTypeId>(elementTypeNode))
|
|
{
|
|
auto bfElementType = mBeModule->mCeMachine->mCeModule->mContext->mTypes[dbgTypeId->mTypeId];
|
|
auto bfPtrType = mBeModule->mCeMachine->mCeModule->CreateRefType(bfElementType);
|
|
|
|
auto dbgType = mBeModule->mDbgModule->mTypes.Alloc<BeDbgTypeId>();
|
|
dbgType->mTypeId = bfPtrType->mTypeId;
|
|
SetResult(curId, dbgType);
|
|
break;
|
|
}
|
|
}
|
|
|
|
auto useType = mBeModule->mDbgModule->CreateReferenceType(elementType);
|
|
SetResult(curId, useType);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgCreateConstType:
|
|
{
|
|
CMD_PARAM(BeMDNode*, elementTypeNode);
|
|
|
|
BeDbgType* elementType = BeValueDynCast<BeDbgType>(elementTypeNode);
|
|
if (elementType == NULL)
|
|
{
|
|
auto dbgType = mBeModule->mDbgModule->mTypes.Alloc<BeDbgConstType>();
|
|
dbgType->mElement = elementTypeNode;
|
|
SetResult(curId, dbgType);
|
|
break;
|
|
}
|
|
|
|
BeDbgType* useType = elementType->FindDerivedType(BeDbgConstType::TypeId);
|
|
if (useType == NULL)
|
|
{
|
|
auto dbgType = mBeModule->mDbgModule->mTypes.Alloc<BeDbgConstType>();
|
|
dbgType->mElement = elementType;
|
|
elementType->mDerivedTypes.PushFront(dbgType, &mBeModule->mAlloc);
|
|
useType = dbgType;
|
|
}
|
|
|
|
SetResult(curId, useType);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgCreateArtificialType:
|
|
{
|
|
CMD_PARAM(BeMDNode*, diType);
|
|
|
|
//auto dbgType = mBeModule->mOwnedValues.Alloc<BeDbgArtificialType>();
|
|
//dbgType->mElement = (BeDbgType*)diType;
|
|
|
|
// Does the artificial thing do anything for us actually?
|
|
auto dbgType = diType;
|
|
|
|
SetResult(curId, dbgType);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgCreateArrayType:
|
|
{
|
|
CMD_PARAM(int64, sizeInBits);
|
|
CMD_PARAM(int64, alignInBits);
|
|
CMD_PARAM(BeMDNode*, elementType);
|
|
CMD_PARAM(int64, numElements);
|
|
|
|
auto dbgArray = mBeModule->mDbgModule->mTypes.Alloc<BeDbgArrayType>();
|
|
dbgArray->mSize = (int)(sizeInBits / 8);
|
|
dbgArray->mAlign = (int)(alignInBits / 8);
|
|
dbgArray->mElement = BeValueDynCast<BeDbgType>(elementType);
|
|
dbgArray->mNumElements = numElements;
|
|
|
|
SetResult(curId, dbgArray);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgCreateReplaceableCompositeType:
|
|
{
|
|
CMD_PARAM(int, tag);
|
|
CMD_PARAM(String, name);
|
|
CMD_PARAM(BeMDNode*, scope);
|
|
CMD_PARAM(BeMDNode*, file);
|
|
CMD_PARAM(int, line);
|
|
CMD_PARAM(int64, sizeInBits);
|
|
CMD_PARAM(int64, alignInBits);
|
|
CMD_PARAM(int, flags);
|
|
|
|
if (tag == llvm::dwarf::DW_TAG_structure_type)
|
|
{
|
|
auto dbgType = mBeModule->mDbgModule->mTypes.Alloc<BeDbgStructType>();
|
|
dbgType->mScope = scope;
|
|
dbgType->mName = name;
|
|
dbgType->mSize = (int)(sizeInBits / 8);
|
|
dbgType->mAlign = (int)(alignInBits / 8);
|
|
dbgType->mDefFile = (BeDbgFile*)file;
|
|
dbgType->mDefLine = line - 1;
|
|
SetResult(curId, dbgType);
|
|
}
|
|
else if (tag == llvm::dwarf::DW_TAG_enumeration_type)
|
|
{
|
|
auto dbgType = mBeModule->mDbgModule->mTypes.Alloc<BeDbgEnumType>();
|
|
dbgType->mScope = scope;
|
|
dbgType->mName = name;
|
|
dbgType->mSize = (int)(sizeInBits / 8);
|
|
dbgType->mAlign = (int)(alignInBits / 8);
|
|
//dbgType->mDefFile = (BeDbgFile*)file;
|
|
//dbgType->mDefLine = line - 1;
|
|
SetResult(curId, dbgType);
|
|
}
|
|
else
|
|
NotImpl();
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgCreateForwardDecl:
|
|
{
|
|
CMD_PARAM(int, tag);
|
|
CMD_PARAM(String, name);
|
|
CMD_PARAM(BeMDNode*, scope);
|
|
CMD_PARAM(BeMDNode*, file);
|
|
CMD_PARAM(int, line);
|
|
|
|
if (tag == llvm::dwarf::DW_TAG_structure_type)
|
|
{
|
|
auto dbgType = mBeModule->mDbgModule->mTypes.Alloc<BeDbgStructType>();
|
|
dbgType->mScope = scope;
|
|
dbgType->mName = name;
|
|
dbgType->mDefFile = (BeDbgFile*)file;
|
|
dbgType->mDefLine = line;
|
|
SetResult(curId, dbgType);
|
|
}
|
|
else if (tag == llvm::dwarf::DW_TAG_enumeration_type)
|
|
{
|
|
auto dbgType = mBeModule->mDbgModule->mTypes.Alloc<BeDbgEnumType>();
|
|
dbgType->mScope = scope;
|
|
dbgType->mName = name;
|
|
SetResult(curId, dbgType);
|
|
}
|
|
else
|
|
NotImpl();
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgCreateSizedForwardDecl:
|
|
{
|
|
CMD_PARAM(int, tag);
|
|
CMD_PARAM(String, name);
|
|
CMD_PARAM(BeMDNode*, scope);
|
|
CMD_PARAM(BeMDNode*, file);
|
|
CMD_PARAM(int, line);
|
|
CMD_PARAM(int64, sizeInBits);
|
|
CMD_PARAM(int64, alignInBits);
|
|
|
|
if (tag == llvm::dwarf::DW_TAG_structure_type)
|
|
{
|
|
auto dbgType = mBeModule->mDbgModule->mTypes.Alloc<BeDbgStructType>();
|
|
dbgType->mDefFile = (BeDbgFile*)file;
|
|
dbgType->mDefLine = line;
|
|
dbgType->mScope = scope;
|
|
dbgType->mName = name;
|
|
dbgType->mSize = (int)(sizeInBits / 8);
|
|
dbgType->mAlign = (int)(alignInBits / 8);
|
|
SetResult(curId, dbgType);
|
|
}
|
|
else if (tag == llvm::dwarf::DW_TAG_enumeration_type)
|
|
{
|
|
auto dbgType = mBeModule->mDbgModule->mTypes.Alloc<BeDbgEnumType>();
|
|
dbgType->mScope = scope;
|
|
dbgType->mName = name;
|
|
dbgType->mSize = (int)(sizeInBits / 8);
|
|
dbgType->mAlign = (int)(alignInBits / 8);
|
|
SetResult(curId, dbgType);
|
|
}
|
|
else
|
|
NotImpl();
|
|
}
|
|
break;
|
|
case BeIRCmd_DbgSetTypeSize:
|
|
{
|
|
CMD_PARAM(BeMDNode*, mdType);
|
|
CMD_PARAM(int64, sizeInBits);
|
|
CMD_PARAM(int64, alignInBits);
|
|
|
|
if (auto dbgType = BeValueDynCast<BeDbgType>(mdType))
|
|
{
|
|
dbgType->mSize = (int)(sizeInBits / 8);
|
|
dbgType->mAlign = (int)(alignInBits / 8);
|
|
}
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgReplaceAllUses:
|
|
{
|
|
CMD_PARAM(BeMDNode*, diPrevNode);
|
|
CMD_PARAM(BeMDNode*, diNewNode);
|
|
/*diPrevNode->replaceAllUsesWith(diNewNode); */
|
|
NotImpl();
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgDeleteTemporary:
|
|
{
|
|
CMD_PARAM(BeMDNode*, diNode);
|
|
/*BeMDNode::deleteTemporary(diNode);*/
|
|
NotImpl();
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgMakePermanent:
|
|
{
|
|
CMD_PARAM(BeMDNode*, diNode);
|
|
CMD_PARAM(BeMDNode*, diBaseType);
|
|
CMD_PARAM(CmdParamVec<BeMDNode*>, members);
|
|
|
|
if (auto dbgType = BeValueDynCast<BeDbgStructType>(diNode))
|
|
{
|
|
dbgType->SetMembers(members);
|
|
}
|
|
else if (auto dbgType = BeValueDynCast<BeDbgEnumType>(diNode))
|
|
{
|
|
dbgType->mElementType = BeValueDynCast<BeDbgType>(diBaseType);
|
|
dbgType->SetMembers(members);
|
|
}
|
|
else
|
|
NotImpl();
|
|
SetResult(curId, diNode);
|
|
break;
|
|
}
|
|
case BfIRCmd_CreateEnumerator:
|
|
{
|
|
CMD_PARAM(String, name);
|
|
CMD_PARAM(int64, val);
|
|
|
|
auto enumValue = mBeModule->mOwnedValues.Alloc<BeDbgEnumMember>();
|
|
enumValue->mName = name;
|
|
enumValue->mValue = val;
|
|
SetResult(curId, enumValue);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgCreateMemberType:
|
|
{
|
|
CMD_PARAM(BeMDNode*, scope);
|
|
CMD_PARAM(String, name);
|
|
CMD_PARAM(BeMDNode*, file);
|
|
CMD_PARAM(int, lineNumber);
|
|
CMD_PARAM(int64, sizeInBits);
|
|
CMD_PARAM(int64, alignInBits);
|
|
CMD_PARAM(int64, offsetInBits);
|
|
CMD_PARAM(int, flags);
|
|
CMD_PARAM(BeMDNode*, type);
|
|
|
|
BF_ASSERT(type != NULL);
|
|
|
|
auto dbgMember = mBeModule->mOwnedValues.Alloc<BeDbgStructMember>();
|
|
dbgMember->mName = name;
|
|
dbgMember->mType = BeValueDynCast<BeDbgType>(type);
|
|
dbgMember->mOffset = (int)(offsetInBits / 8);
|
|
dbgMember->mFlags = flags;
|
|
|
|
SetResult(curId, dbgMember);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgStaticCreateMemberType:
|
|
{
|
|
CMD_PARAM(BeMDNode*, scope);
|
|
CMD_PARAM(String, name);
|
|
CMD_PARAM(BeMDNode*, file);
|
|
CMD_PARAM(int, lineNumber);
|
|
CMD_PARAM(BeMDNode*, type);
|
|
CMD_PARAM(int, flags);
|
|
CMD_PARAM(BeConstant*, val);
|
|
|
|
BF_ASSERT(type != NULL);
|
|
|
|
auto dbgMember = mBeModule->mOwnedValues.Alloc<BeDbgStructMember>();
|
|
dbgMember->mName = name;
|
|
dbgMember->mType = BeValueDynCast<BeDbgType>(type);
|
|
dbgMember->mOffset = -1;
|
|
dbgMember->mStaticValue = val;
|
|
dbgMember->mFlags = flags;
|
|
dbgMember->mIsStatic = true;
|
|
|
|
SetResult(curId, dbgMember);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgCreateInheritance:
|
|
{
|
|
CMD_PARAM(BeMDNode*, type);
|
|
CMD_PARAM(BeMDNode*, baseType);
|
|
CMD_PARAM(int64, baseOffset);
|
|
CMD_PARAM(int, flags);
|
|
|
|
auto dbgInheritance = mBeModule->mAlloc.Alloc<BeDbgInheritance>();
|
|
dbgInheritance->mBaseType = BeValueDynCast<BeDbgType>(baseType);
|
|
|
|
SetResult(curId, dbgInheritance);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgCreateMethod:
|
|
{
|
|
CMD_PARAM(BeMDNode*, context);
|
|
CMD_PARAM(String, name);
|
|
CMD_PARAM(String, linkageName);
|
|
CMD_PARAM(BeMDNode*, file);
|
|
CMD_PARAM(int, lineNum);
|
|
CMD_PARAM(BeMDNode*, type);
|
|
CMD_PARAM(bool, isLocalToUnit);
|
|
CMD_PARAM(bool, isDefinition);
|
|
CMD_PARAM(int, vk);
|
|
CMD_PARAM(int, vIndex);
|
|
CMD_PARAM(BeMDNode*, vTableHolder);
|
|
CMD_PARAM(int, flags);
|
|
CMD_PARAM(bool, isOptimized);
|
|
CMD_PARAM(BeValue*, fn);
|
|
CMD_PARAM(CmdParamVec<BeMDNode*>, genericArgs);
|
|
CMD_PARAM(CmdParamVec<BeConstant*>, genericConstValueArgs);
|
|
|
|
auto dbgFunc = mBeModule->mOwnedValues.Alloc<BeDbgFunction>();
|
|
dbgFunc->mScope = context;
|
|
dbgFunc->mFile = (BeDbgFile*)file;
|
|
dbgFunc->mLine = lineNum - 1;
|
|
dbgFunc->mType = (BeDbgFunctionType*)type;
|
|
dbgFunc->mName = name;
|
|
dbgFunc->mLinkageName = linkageName;
|
|
dbgFunc->mValue = (BeFunction*)fn;
|
|
dbgFunc->mIsLocalToUnit = isLocalToUnit;
|
|
dbgFunc->mVK = vk;
|
|
dbgFunc->mVIndex = vIndex;
|
|
dbgFunc->mIsStaticMethod = (flags & llvm::DINode::FlagStaticMember) != 0;
|
|
dbgFunc->mFlags = flags;
|
|
|
|
for (auto arg : genericArgs)
|
|
{
|
|
BF_ASSERT(arg != NULL);
|
|
dbgFunc->mGenericArgs.Add(BeValueDynCast<BeDbgType>(arg));
|
|
}
|
|
for (auto genericConstValue : genericConstValueArgs)
|
|
dbgFunc->mGenericConstValueArgs.Add(genericConstValue);
|
|
|
|
if (dbgFunc->mValue != NULL)
|
|
dbgFunc->mValue->mDbgFunction = dbgFunc;
|
|
dbgFunc->mIdx = (int)mBeModule->mDbgModule->mFuncs.size();
|
|
mBeModule->mDbgModule->mFuncs.push_back(dbgFunc);
|
|
|
|
SetResult(curId, dbgFunc);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgCreateFunction:
|
|
{
|
|
CMD_PARAM(BeMDNode*, context);
|
|
CMD_PARAM(String, name);
|
|
CMD_PARAM(String, linkageName);
|
|
CMD_PARAM(BeMDNode*, file);
|
|
CMD_PARAM(int, lineNum);
|
|
CMD_PARAM(BeMDNode*, type);
|
|
CMD_PARAM(bool, isLocalToUnit);
|
|
CMD_PARAM(bool, isDefinition);
|
|
CMD_PARAM(int, scopeLine);
|
|
CMD_PARAM(int, flags);
|
|
CMD_PARAM(bool, isOptimized);
|
|
CMD_PARAM(BeValue*, fn);
|
|
|
|
auto dbgFunc = mBeModule->mOwnedValues.Alloc<BeDbgFunction>();
|
|
dbgFunc->mScope = context;
|
|
dbgFunc->mFile = (BeDbgFile*)file;
|
|
dbgFunc->mLine = lineNum - 1;
|
|
dbgFunc->mType = (BeDbgFunctionType*)type;
|
|
dbgFunc->mName = name;
|
|
dbgFunc->mLinkageName = linkageName;
|
|
dbgFunc->mValue = (BeFunction*)fn;
|
|
dbgFunc->mIsLocalToUnit = isLocalToUnit;
|
|
dbgFunc->mFlags = flags;
|
|
|
|
/*if (auto dbgStructType = BeValueDynCast<BeDbgStructType>(context))
|
|
{
|
|
// This will get added to the struct later
|
|
}
|
|
else
|
|
{
|
|
}*/
|
|
if (dbgFunc->mValue != NULL)
|
|
dbgFunc->mValue->mDbgFunction = dbgFunc;
|
|
dbgFunc->mIdx = (int)mBeModule->mDbgModule->mFuncs.size();
|
|
mBeModule->mDbgModule->mFuncs.push_back(dbgFunc);
|
|
|
|
SetResult(curId, dbgFunc);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgCreateParameterVariable:
|
|
{
|
|
CMD_PARAM(BeMDNode*, scope);
|
|
CMD_PARAM(String, name);
|
|
CMD_PARAM(int, argNo);
|
|
CMD_PARAM(BeMDNode*, file);
|
|
CMD_PARAM(int, lineNum);
|
|
CMD_PARAM(BeMDNode*, type);
|
|
CMD_PARAM(bool, alwaysPreserve);
|
|
CMD_PARAM(int, flags);
|
|
|
|
BF_ASSERT(type != NULL);
|
|
|
|
auto dbgFunc = (BeDbgFunction*)scope;
|
|
|
|
auto dbgVar = mBeModule->mOwnedValues.Alloc<BeDbgVariable>();
|
|
dbgVar->mName = name;
|
|
dbgVar->mType = type;
|
|
dbgVar->mParamNum = argNo - 1;
|
|
|
|
int argIdx = argNo - 1;
|
|
|
|
//for (int i = ; i <= argNo - 1; i++)
|
|
while (argIdx >= (int)dbgFunc->mVariables.size())
|
|
dbgFunc->mVariables.push_back(NULL);
|
|
if (dbgFunc->mVariables[argIdx] == NULL)
|
|
dbgFunc->mVariables[argIdx] = dbgVar;
|
|
else
|
|
{
|
|
BF_ASSERT(dbgFunc->mVariables[argIdx]->mParamNum == -1);
|
|
dbgFunc->mVariables.Insert(argIdx, dbgVar);
|
|
}
|
|
//mActiveFunction->mDbgFunction->mVariables.push_back(dbgVar);
|
|
|
|
//dbgVar->mValue = mBeModule->GetArgument(argNo - 1);
|
|
|
|
SetResult(curId, dbgVar);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgCreateSubroutineType:
|
|
{
|
|
CMD_PARAM(CmdParamVec<BeMDNode*>, elements);
|
|
|
|
auto dbgFuncType = mBeModule->mOwnedValues.Alloc<BeDbgFunctionType>();
|
|
if (!elements.empty())
|
|
{
|
|
dbgFuncType->mReturnType = BeValueDynCast<BeDbgType>(elements[0]);
|
|
for (int i = 1; i < (int)elements.size(); i++)
|
|
dbgFuncType->mParams.push_back(BeValueDynCast<BeDbgType>(elements[i]));
|
|
}
|
|
|
|
SetResult(curId, dbgFuncType);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgCreateAutoVariable:
|
|
{
|
|
CMD_PARAM(BeMDNode*, scope);
|
|
CMD_PARAM(String, name);
|
|
CMD_PARAM(BeMDNode*, file);
|
|
CMD_PARAM(int, lineNo);
|
|
CMD_PARAM(BeMDNode*, type);
|
|
CMD_PARAM(int, initType);
|
|
|
|
BF_ASSERT(type != NULL);
|
|
|
|
auto dbgVar = mBeModule->mOwnedValues.Alloc<BeDbgVariable>();
|
|
dbgVar->mName = name;
|
|
dbgVar->mType = type;
|
|
dbgVar->mScope = scope;
|
|
dbgVar->mInitType = (BfIRInitType)initType;
|
|
mActiveFunction->mDbgFunction->mVariables.push_back(dbgVar);
|
|
|
|
BF_ASSERT(name != "__CRASH_AUTOVARIABLE__");
|
|
|
|
SetResult(curId, dbgVar);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgInsertValueIntrinsic:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
CMD_PARAM(BeMDNode*, varInfo);
|
|
|
|
auto dbgVar = BeValueDynCast<BeDbgVariable>(varInfo);
|
|
//dbgVar->mValue = val;
|
|
//dbgVar->mDeclDbgLoc = mBeModule->mCurDbgLoc;
|
|
|
|
if (val == NULL)
|
|
{
|
|
val = mBeModule->GetConstant(mBeContext->GetPrimitiveType(BeTypeCode_Int32), (int64)0);
|
|
}
|
|
|
|
auto inst = mBeModule->AllocInst<BeDbgDeclareInst>();
|
|
inst->mValue = val;
|
|
inst->mDbgVar = dbgVar;
|
|
inst->mIsValue = true;
|
|
|
|
SetResult(curId, inst);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgInsertDeclare:
|
|
{
|
|
CMD_PARAM(BeValue*, val);
|
|
CMD_PARAM(BeMDNode*, varInfo);
|
|
CMD_PARAM(BeValue*, insertBefore);
|
|
|
|
auto dbgVar = BeValueDynCast<BeDbgVariable>(varInfo);
|
|
//dbgVar->mValue = val;
|
|
//dbgVar->mDeclDbgLoc = mBeModule->mCurDbgLoc;
|
|
|
|
auto inst = mBeModule->mAlloc.Alloc<BeDbgDeclareInst>();
|
|
inst->mValue = val;
|
|
inst->mDbgVar = dbgVar;
|
|
inst->mIsValue = false;
|
|
if (insertBefore == NULL)
|
|
mBeModule->AddInst(inst);
|
|
else
|
|
NotImpl();
|
|
|
|
SetResult(curId, inst);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgLifetimeEnd:
|
|
{
|
|
CMD_PARAM(BeMDNode*, varInfo);
|
|
auto inst = mBeModule->AllocInst<BeLifetimeEndInst>();
|
|
inst->mPtr = varInfo;
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgCreateGlobalVariable:
|
|
{
|
|
CMD_PARAM(BeMDNode*, context);
|
|
CMD_PARAM(String, name);
|
|
CMD_PARAM(String, linkageName);
|
|
CMD_PARAM(BeMDNode*, file);
|
|
CMD_PARAM(int, lineNum);
|
|
CMD_PARAM(BeMDNode*, type);
|
|
CMD_PARAM(bool, isLocalToUnit);
|
|
CMD_PARAM(BeConstant*, val);
|
|
CMD_PARAM(BeMDNode*, decl);
|
|
|
|
auto dbgGlobalVariable = mBeModule->mDbgModule->mGlobalVariables.Alloc();
|
|
dbgGlobalVariable->mContext = context;
|
|
dbgGlobalVariable->mName = name;
|
|
dbgGlobalVariable->mLinkageName = linkageName;
|
|
dbgGlobalVariable->mFile = (BeDbgFile*)file;
|
|
dbgGlobalVariable->mLineNum = lineNum;
|
|
dbgGlobalVariable->mType = type;
|
|
dbgGlobalVariable->mIsLocalToUnit = isLocalToUnit;
|
|
dbgGlobalVariable->mValue = val;
|
|
dbgGlobalVariable->mDecl = decl;
|
|
|
|
SetResult(curId, dbgGlobalVariable);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgCreateLexicalBlock:
|
|
{
|
|
CMD_PARAM(BeMDNode*, scope);
|
|
CMD_PARAM(BeMDNode*, file);
|
|
CMD_PARAM(int, lineNum);
|
|
CMD_PARAM(int, col);
|
|
|
|
auto dbgLexicalBlock = mBeModule->mOwnedValues.Alloc<BeDbgLexicalBlock>();
|
|
BF_ASSERT(BeValueDynCast<BeDbgFile>(file) != NULL);
|
|
dbgLexicalBlock->mFile = (BeDbgFile*)file;
|
|
dbgLexicalBlock->mScope = scope;
|
|
dbgLexicalBlock->mId = mBeModule->mCurLexBlockId++;
|
|
|
|
SetResult(curId, dbgLexicalBlock);
|
|
}
|
|
break;
|
|
case BfIRCmd_DbgCreateAnnotation:
|
|
{
|
|
CMD_PARAM(BeMDNode*, scope);
|
|
CMD_PARAM(String, name);
|
|
CMD_PARAM(BeValue*, value);
|
|
|
|
if (auto dbgFunc = BeValueDynCast<BeDbgFunction>(scope))
|
|
{
|
|
auto beType = value->GetType();
|
|
BeDbgType** dbgTypePtr;
|
|
if (mOnDemandTypeMap.TryAdd(beType, NULL, &dbgTypePtr))
|
|
{
|
|
auto dbgType = mBeModule->mDbgModule->mTypes.Alloc<BeDbgBasicType>();
|
|
dbgType->mSize = beType->mSize;
|
|
dbgType->mAlign = beType->mAlign;
|
|
dbgType->mEncoding = llvm::dwarf::DW_ATE_signed;
|
|
*dbgTypePtr = dbgType;
|
|
}
|
|
|
|
auto dbgVar = mBeModule->mOwnedValues.Alloc<BeDbgVariable>();
|
|
dbgVar->mName = "#" + name;
|
|
dbgVar->mType = *dbgTypePtr;
|
|
dbgVar->mValue = value;
|
|
dbgVar->mScope = scope;
|
|
dbgFunc->mVariables.Add(dbgVar);
|
|
|
|
auto inst = mBeModule->AllocInst<BeDbgDeclareInst>();
|
|
inst->mValue = value;
|
|
inst->mDbgVar = dbgVar;
|
|
inst->mIsValue = true;
|
|
}
|
|
else
|
|
NotImpl();
|
|
}
|
|
break;
|
|
default:
|
|
BF_FATAL("Unhandled");
|
|
break;
|
|
}
|
|
|
|
#ifdef CODEGEN_TRACK
|
|
gBEMemReporter.EndSection();
|
|
|
|
gBEMemReporterSize += mStream->GetReadPos() - curId;
|
|
#endif
|
|
}
|
|
|
|
void BeIRCodeGen::SetConfigConst(int idx, int value)
|
|
{
|
|
BF_ASSERT(idx == (int)mConfigConsts.size());
|
|
mConfigConsts.Add(value);
|
|
}
|
|
|
|
BeValue* BeIRCodeGen::GetBeValue(int id)
|
|
{
|
|
auto& result = mResults[id];
|
|
BF_ASSERT(result.mKind == BeIRCodeGenEntryKind_Value);
|
|
#ifdef BE_EXTRA_CHECKS
|
|
BF_ASSERT(!result.mBeValue->mLifetimeEnded);
|
|
BF_ASSERT(!result.mBeValue->mWasRemoved);
|
|
#endif
|
|
return result.mBeValue;
|
|
}
|
|
|
|
BeType* BeIRCodeGen::GetBeType(int id)
|
|
{
|
|
auto& result = mResults[id];
|
|
BF_ASSERT(result.mKind == BeIRCodeGenEntryKind_Type);
|
|
return result.mBeType;
|
|
}
|
|
|
|
BeBlock* BeIRCodeGen::GetBeBlock(int id)
|
|
{
|
|
auto& result = mResults[id];
|
|
BF_ASSERT(result.mKind == BeIRCodeGenEntryKind_Block);
|
|
return result.mBeBlock;
|
|
}
|
|
|
|
BeMDNode* BeIRCodeGen::GetBeMetadata(int id)
|
|
{
|
|
auto& result = mResults[id];
|
|
BF_ASSERT(result.mKind == BeIRCodeGenEntryKind_Metadata);
|
|
return result.mBeMetadata;
|
|
}
|
|
|
|
BeType* BeIRCodeGen::GetBeTypeById(int id)
|
|
{
|
|
return GetTypeEntry(id).mBeType;
|
|
}
|
|
|
|
BeState BeIRCodeGen::GetState()
|
|
{
|
|
BeState state;
|
|
state.mActiveFunction = mActiveFunction;
|
|
state.mSavedDebugLocs = mSavedDebugLocs;
|
|
state.mHasDebugLoc = mHasDebugLoc;
|
|
|
|
state.mActiveBlock = mBeModule->mActiveBlock;
|
|
state.mInsertPos = mBeModule->mInsertPos;
|
|
state.mCurDbgLoc = mBeModule->mCurDbgLoc;
|
|
state.mPrevDbgLocInline = mBeModule->mPrevDbgLocInline;
|
|
state.mLastDbgLoc = mBeModule->mLastDbgLoc;
|
|
|
|
return state;
|
|
}
|
|
|
|
void BeIRCodeGen::SetState(const BeState& state)
|
|
{
|
|
mActiveFunction = state.mActiveFunction;
|
|
mBeModule->mActiveFunction = mActiveFunction;
|
|
mSavedDebugLocs = state.mSavedDebugLocs;
|
|
mHasDebugLoc = state.mHasDebugLoc;
|
|
|
|
mBeModule->mActiveBlock = state.mActiveBlock;
|
|
mBeModule->mInsertPos = state.mInsertPos;
|
|
mBeModule->mCurDbgLoc = state.mCurDbgLoc;
|
|
mBeModule->mPrevDbgLocInline = state.mPrevDbgLocInline;
|
|
mBeModule->mLastDbgLoc = state.mLastDbgLoc;
|
|
} |