mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
2417 lines
No EOL
48 KiB
C++
2417 lines
No EOL
48 KiB
C++
#pragma once
|
|
|
|
#include "BeefySysLib/Common.h"
|
|
#include "BeefySysLib/util/HashSet.h"
|
|
#include "../BumpList.h"
|
|
#include "../Compiler/BfIRBuilder.h"
|
|
#include "BeContext.h"
|
|
#include "../X64.h"
|
|
|
|
NS_BF_BEGIN
|
|
|
|
class BeContext;
|
|
|
|
class BeValue;
|
|
class BeCallInst;
|
|
|
|
class BeValue;
|
|
class BeBlock;
|
|
class BeArgument;
|
|
class BeInst;
|
|
class BeNopInst;
|
|
class BeUnreachableInst;
|
|
class BeEnsureInstructionAtInst;
|
|
class BeUndefValueInst;
|
|
class BeExtractValueInst;
|
|
class BeInsertValueInst;
|
|
class BeNumericCastInst;
|
|
class BeBitCastInst;
|
|
class BeNegInst;
|
|
class BeNotInst;
|
|
class BeBinaryOpInst;
|
|
class BeCmpInst;
|
|
class BeObjectAccessCheckInst;
|
|
class BeAllocaInst;
|
|
class BeLifetimeExtendInst;
|
|
class BeAliasValueInst;
|
|
class BeLifetimeStartInst;
|
|
class BeLifetimeEndInst;
|
|
class BeLifetimeSoftEndInst;
|
|
class BeLifetimeFenceInst;
|
|
class BeValueScopeStartInst;
|
|
class BeValueScopeRetainInst;
|
|
class BeValueScopeEndInst;
|
|
class BeLoadInst;
|
|
class BeStoreInst;
|
|
class BeSetCanMergeInst;
|
|
class BeMemSetInst;
|
|
class BeFenceInst;
|
|
class BeStackSaveInst;
|
|
class BeStackRestoreInst;
|
|
class BeGEPInst;
|
|
class BeBrInst;
|
|
class BeCondBrInst;
|
|
class BePhiIncoming;
|
|
class BePhiInst;
|
|
class BeSwitchInst;
|
|
class BeRetInst;
|
|
class BeCallInst;
|
|
class CeMachine;
|
|
|
|
class BeDbgVariable;
|
|
class BeDbgDeclareInst;
|
|
|
|
class BeValueVisitor
|
|
{
|
|
public:
|
|
void VisitChild(BeValue* value);
|
|
|
|
virtual void Visit(BeValue* beValue) {}
|
|
virtual void Visit(BeBlock* beBlock) {}
|
|
virtual void Visit(BeArgument* beArgument) {}
|
|
virtual void Visit(BeInst* beInst) {}
|
|
virtual void Visit(BeNopInst* nopInst) {}
|
|
virtual void Visit(BeUnreachableInst* unreachableInst) {}
|
|
virtual void Visit(BeEnsureInstructionAtInst* ensureCodeAtInst) {}
|
|
virtual void Visit(BeUndefValueInst* undefValue) {}
|
|
virtual void Visit(BeExtractValueInst* extractValue) {}
|
|
virtual void Visit(BeInsertValueInst* insertValue) {}
|
|
virtual void Visit(BeNumericCastInst* castInst) {}
|
|
virtual void Visit(BeBitCastInst* castInst) {}
|
|
virtual void Visit(BeNegInst* negInst) {}
|
|
virtual void Visit(BeNotInst* notInst) {}
|
|
virtual void Visit(BeBinaryOpInst* binaryOpInst) {}
|
|
virtual void Visit(BeFenceInst* fenceInst) {}
|
|
virtual void Visit(BeStackSaveInst* stackSaveInst) {}
|
|
virtual void Visit(BeStackRestoreInst* stackRestoreInst) {}
|
|
virtual void Visit(BeCmpInst* cmpInst) {}
|
|
virtual void Visit(BeObjectAccessCheckInst* objectAccessCheckInst) {}
|
|
virtual void Visit(BeAllocaInst* allocaInst) {}
|
|
virtual void Visit(BeAliasValueInst* aliasValueInst) {}
|
|
virtual void Visit(BeLifetimeExtendInst* lifetimeExtendInst) {}
|
|
virtual void Visit(BeLifetimeStartInst* lifetimeStartInst) {}
|
|
virtual void Visit(BeLifetimeEndInst* lifetimeEndInst) {}
|
|
virtual void Visit(BeLifetimeSoftEndInst* lifetimeEndInst) {}
|
|
virtual void Visit(BeLifetimeFenceInst* lifetimeFenceInst) {}
|
|
virtual void Visit(BeValueScopeStartInst* valueScopeStartInst) {}
|
|
virtual void Visit(BeValueScopeRetainInst* valueScopeRetainInst) {}
|
|
virtual void Visit(BeValueScopeEndInst* valueScopeEndInst) {}
|
|
virtual void Visit(BeLoadInst* allocaInst) {}
|
|
virtual void Visit(BeStoreInst* storeInst) {}
|
|
virtual void Visit(BeSetCanMergeInst* setCanMergeInst) {}
|
|
virtual void Visit(BeMemSetInst* memSetInst) {}
|
|
virtual void Visit(BeGEPInst* gepInst) {}
|
|
virtual void Visit(BeBrInst* brInst) {}
|
|
virtual void Visit(BeCondBrInst* condBrInst) {}
|
|
virtual void Visit(BePhiIncoming* phiIncomingInst) {}
|
|
virtual void Visit(BePhiInst* phiInst) {}
|
|
virtual void Visit(BeSwitchInst* switchInst) {}
|
|
virtual void Visit(BeRetInst* retInst) {}
|
|
virtual void Visit(BeCallInst* callInst) {}
|
|
|
|
//virtual void Visit(BeDbgVariable* dbgVariable) {}
|
|
virtual void Visit(BeDbgDeclareInst* dbgDeclareInst) {}
|
|
};
|
|
|
|
class BeModule;
|
|
class BeFunction;
|
|
class BeDbgLoc;
|
|
|
|
class BeInliner : public BeValueVisitor
|
|
{
|
|
public:
|
|
BumpAllocator* mAlloc;
|
|
OwnedVector<BeValue>* mOwnedValueVec;
|
|
Dictionary<BeValue*, BeValue*> mValueMap;
|
|
Dictionary<BeDbgLoc*, BeDbgLoc*> mInlinedAtMap;
|
|
|
|
BeModule* mModule;
|
|
BeFunction* mSrcFunc;
|
|
BeFunction* mDestFunc;
|
|
BeCallInst* mCallInst;
|
|
BeBlock* mDestBlock;
|
|
BeDbgLoc* mSrcDbgLoc;
|
|
BeDbgLoc* mDestDbgLoc;
|
|
|
|
public:
|
|
BeInliner()
|
|
{
|
|
mSrcDbgLoc = NULL;
|
|
mDestDbgLoc = NULL;
|
|
}
|
|
|
|
BeValue* Remap(BeValue* srcValue);
|
|
BeDbgLoc* ExtendInlineDbgLoc(BeDbgLoc* srcInlineAt);
|
|
void AddInst(BeInst* destInst, BeInst* srcInst);
|
|
|
|
template <typename T>
|
|
T* AllocInst(T* srcInst)
|
|
{
|
|
auto inst = mAlloc->Alloc<T>();
|
|
AddInst(inst, srcInst);
|
|
return inst;
|
|
}
|
|
|
|
template <typename T>
|
|
T* AllocInstOwned(T* srcInst)
|
|
{
|
|
auto inst = mOwnedValueVec->Alloc<T>();
|
|
AddInst(inst, srcInst);
|
|
return inst;
|
|
}
|
|
|
|
virtual void Visit(BeValue* beValue) override;
|
|
virtual void Visit(BeBlock* beBlock) override;
|
|
virtual void Visit(BeArgument* beArgument) override;
|
|
virtual void Visit(BeInst* beInst) override;
|
|
virtual void Visit(BeNopInst* nopInst) override;
|
|
virtual void Visit(BeUnreachableInst* unreachableInst) override;
|
|
virtual void Visit(BeEnsureInstructionAtInst* ensureCodeAtInst) override;
|
|
virtual void Visit(BeUndefValueInst* undefValue) override;
|
|
virtual void Visit(BeExtractValueInst* extractValue) override;
|
|
virtual void Visit(BeInsertValueInst* insertValue) override;
|
|
virtual void Visit(BeNumericCastInst* castInst) override;
|
|
virtual void Visit(BeBitCastInst* castInst) override;
|
|
virtual void Visit(BeNegInst* negInst) override;
|
|
virtual void Visit(BeNotInst* notInst) override;
|
|
virtual void Visit(BeBinaryOpInst* binaryOpInst) override;
|
|
virtual void Visit(BeCmpInst* cmpInst) override;
|
|
virtual void Visit(BeFenceInst* fenceInst) override;
|
|
virtual void Visit(BeStackSaveInst* stackSaveInst) override;
|
|
virtual void Visit(BeStackRestoreInst* stackRestoreInst) override;
|
|
virtual void Visit(BeObjectAccessCheckInst* objectAccessCheckInst) override;
|
|
virtual void Visit(BeAllocaInst* allocaInst) override;
|
|
virtual void Visit(BeAliasValueInst* aliasValueInst) override;
|
|
virtual void Visit(BeLifetimeStartInst* lifetimeStartInst) override;
|
|
virtual void Visit(BeLifetimeExtendInst* lifetimeExtendInst) override;
|
|
virtual void Visit(BeLifetimeEndInst* lifetimeEndInst) override;
|
|
virtual void Visit(BeLifetimeSoftEndInst* lifetimeEndInst) override;
|
|
virtual void Visit(BeLifetimeFenceInst* lifetimeFenceInst) override;
|
|
virtual void Visit(BeValueScopeStartInst* valueScopeStartInst) override;
|
|
virtual void Visit(BeValueScopeRetainInst* valueScopeRetainInst) override;
|
|
virtual void Visit(BeValueScopeEndInst* valueScopeEndInst) override;
|
|
virtual void Visit(BeLoadInst* allocaInst) override;
|
|
virtual void Visit(BeStoreInst* storeInst) override;
|
|
virtual void Visit(BeSetCanMergeInst* setCanMergeInst) override;
|
|
virtual void Visit(BeMemSetInst* memSetInst) override;
|
|
virtual void Visit(BeGEPInst* gepInst) override;
|
|
virtual void Visit(BeBrInst* brInst) override;
|
|
virtual void Visit(BeCondBrInst* condBrInst) override;
|
|
virtual void Visit(BePhiIncoming* phiIncomingInst) override;
|
|
virtual void Visit(BePhiInst* phiInst) override;
|
|
virtual void Visit(BeSwitchInst* switchInst) override;
|
|
virtual void Visit(BeRetInst* retInst) override;
|
|
virtual void Visit(BeCallInst* callInst) override;
|
|
|
|
virtual void Visit(BeDbgDeclareInst* dbgDeclareInst) override;
|
|
};
|
|
|
|
class BeValue : public BeHashble
|
|
{
|
|
public:
|
|
int mRefCount;
|
|
#ifdef _DEBUG
|
|
bool mLifetimeEnded;
|
|
bool mWasRemoved;
|
|
BeValue()
|
|
{
|
|
mLifetimeEnded = false;
|
|
mWasRemoved = false;
|
|
mRefCount = 0;
|
|
}
|
|
#else
|
|
BeValue()
|
|
{
|
|
mRefCount = 0;
|
|
}
|
|
#endif
|
|
|
|
virtual ~BeValue()
|
|
{
|
|
}
|
|
|
|
static const int TypeId = 0;
|
|
virtual void Accept(BeValueVisitor* beVisitor) = 0;
|
|
virtual bool TypeIdIsA(int typeId) = 0;
|
|
virtual BeValue* DynCast(int typeId)
|
|
{
|
|
if (TypeIdIsA(typeId))
|
|
return this;
|
|
return NULL;
|
|
}
|
|
static bool ClassIsA(int typeId)
|
|
{
|
|
return typeId == 0;
|
|
}
|
|
virtual int GetTypeId() { return TypeId; }
|
|
|
|
public:
|
|
virtual BeType* GetType()
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
virtual void SetName(const StringImpl& name)
|
|
{
|
|
}
|
|
};
|
|
|
|
#define BE_VALUE_TYPE(name, TBase) static const int TypeId = __LINE__; \
|
|
virtual void Accept(BeValueVisitor* beVisitor) override { beVisitor->Visit(this); } \
|
|
static bool ClassIsA(int typeId) { return (typeId == TypeId) || TBase::ClassIsA(typeId); } \
|
|
virtual bool TypeIdIsA(int typeId) override { return ClassIsA(typeId); } \
|
|
virtual int GetTypeId() override { return TypeId; } \
|
|
TBase* ToBase() { return (TBase*)this; }
|
|
|
|
template <typename T>
|
|
T* BeValueDynCast(BeValue* value)
|
|
{
|
|
if (value == NULL)
|
|
return NULL;
|
|
BeValue* result = value->DynCast(T::TypeId);
|
|
return (T*)result;
|
|
}
|
|
|
|
template <typename T>
|
|
T* BeValueDynCastExact(BeValue* value)
|
|
{
|
|
if (value == NULL)
|
|
return NULL;
|
|
if (value->GetTypeId() != T::TypeId)
|
|
return NULL;
|
|
return (T*)value;
|
|
}
|
|
|
|
class BeBlock;
|
|
class BeInst;
|
|
class BeModule;
|
|
class BeDbgLoc;
|
|
class BeMDNode;
|
|
class BeGlobalVariable;
|
|
|
|
class BeConstant;
|
|
|
|
struct BeConstData
|
|
{
|
|
struct ConstantEntry
|
|
{
|
|
int mIdx;
|
|
BeConstant* mConstant;
|
|
};
|
|
|
|
Array<uint8> mData;
|
|
Array<ConstantEntry> mConsts;
|
|
};
|
|
|
|
class BeConstant : public BeValue
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeConstant, BeValue);
|
|
|
|
BeType* mType;
|
|
union
|
|
{
|
|
bool mBool;
|
|
int64 mInt64;
|
|
int32 mInt32;
|
|
int16 mInt16;
|
|
int8 mInt8;
|
|
uint64 mUInt64;
|
|
uint32 mUInt32;
|
|
uint16 mUInt16;
|
|
uint8 mUInt8;
|
|
uint8 mChar;
|
|
uint32 mChar32;
|
|
double mDouble;
|
|
//BeType* mTypeParam;
|
|
//BeGlobalVariable* mGlobalVar;
|
|
BeConstant* mTarget;
|
|
};
|
|
|
|
bool IsNull()
|
|
{
|
|
if (mType->mTypeCode == BeTypeCode_NullPtr)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
virtual BeType* GetType();
|
|
virtual void GetData(BeConstData& data);
|
|
virtual void HashContent(BeHashContext& hashCtx) override;
|
|
};
|
|
|
|
class BeCastConstant : public BeConstant
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeCastConstant, BeConstant);
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mType->HashReference(hashCtx);
|
|
mTarget->HashReference(hashCtx);
|
|
}
|
|
|
|
virtual void GetData(BeConstData& data) override
|
|
{
|
|
mTarget->GetData(data);
|
|
}
|
|
};
|
|
|
|
class BeGEP1Constant : public BeConstant
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeGEP1Constant, BeConstant);
|
|
int mIdx0;
|
|
|
|
virtual BeType* GetType();
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mTarget->HashReference(hashCtx);
|
|
hashCtx.Mixin(mIdx0);
|
|
}
|
|
};
|
|
|
|
class BeGEP2Constant : public BeConstant
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeGEP2Constant, BeConstant);
|
|
int mIdx0;
|
|
int mIdx1;
|
|
|
|
virtual BeType* GetType();
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mTarget->HashReference(hashCtx);
|
|
hashCtx.Mixin(mIdx0);
|
|
hashCtx.Mixin(mIdx1);
|
|
}
|
|
};
|
|
|
|
class BeExtractValueConstant : public BeConstant
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeExtractValueConstant, BeConstant);
|
|
int mIdx0;
|
|
|
|
virtual BeType* GetType();
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mTarget->HashReference(hashCtx);
|
|
hashCtx.Mixin(mIdx0);
|
|
}
|
|
};
|
|
|
|
class BeStructConstant : public BeConstant
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeStructConstant, BeConstant);
|
|
|
|
SizedArray<BeConstant*, 4> mMemberValues;
|
|
|
|
virtual void GetData(BeConstData& data) override;
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
hashCtx.Mixin(mType);
|
|
hashCtx.Mixin(mMemberValues.size());
|
|
for (auto member : mMemberValues)
|
|
member->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeUndefConstant : public BeConstant
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeUndefConstant, BeConstant);
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(mType);
|
|
hashCtx.Mixin(TypeId);
|
|
}
|
|
};
|
|
|
|
class BeStringConstant : public BeConstant
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeStringConstant, BeConstant);
|
|
|
|
String mString;
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
hashCtx.MixinStr(mString);
|
|
}
|
|
};
|
|
|
|
class BeGlobalVariable : public BeConstant
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeGlobalVariable, BeConstant);
|
|
|
|
BeModule* mModule;
|
|
String mName;
|
|
BeConstant* mInitializer;
|
|
BfIRLinkageType mLinkageType;
|
|
BfIRStorageKind mStorageKind;
|
|
bool mIsConstant;
|
|
bool mIsTLS;
|
|
int mAlign;
|
|
bool mUnnamedAddr;
|
|
|
|
virtual BeType* GetType();
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
hashCtx.MixinStr(mName);
|
|
if (mInitializer != NULL)
|
|
mInitializer->HashReference(hashCtx);
|
|
hashCtx.Mixin(mLinkageType);
|
|
hashCtx.Mixin(mStorageKind);
|
|
hashCtx.Mixin(mIsConstant);
|
|
hashCtx.Mixin(mIsTLS);
|
|
hashCtx.Mixin(mAlign);
|
|
hashCtx.Mixin(mUnnamedAddr);
|
|
}
|
|
|
|
virtual void GetData(BeConstData& data) override
|
|
{
|
|
data.mConsts.Add({ (int)data.mData.size(), this });
|
|
data.mData.Insert(data.mData.size(), (uint8)0, 8);
|
|
}
|
|
};
|
|
|
|
class BeFunctionParam
|
|
{
|
|
public:
|
|
String mName;
|
|
bool mStructRet;
|
|
bool mNoAlias;
|
|
bool mNoCapture;
|
|
bool mZExt;
|
|
int mDereferenceableSize;
|
|
int mByValSize;
|
|
|
|
BeFunctionParam()
|
|
{
|
|
mStructRet = false;
|
|
mNoAlias = false;
|
|
mNoCapture = false;
|
|
mZExt = false;
|
|
mDereferenceableSize = -1;
|
|
mByValSize = -1;
|
|
}
|
|
};
|
|
|
|
class BeDbgFunction;
|
|
|
|
class BeIntrinsic : public BeValue
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeIntrinsic, BeValue);
|
|
|
|
String mName;
|
|
BfIRIntrinsic mKind;
|
|
BeType* mReturnType;
|
|
|
|
BeIntrinsic()
|
|
{
|
|
mReturnType = NULL;
|
|
}
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
hashCtx.Mixin(mKind);
|
|
}
|
|
};
|
|
|
|
class BeFunction : public BeConstant
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeFunction, BeConstant);
|
|
|
|
BeModule* mModule;
|
|
#ifdef _DEBUG
|
|
StringT<256> mName;
|
|
#else
|
|
String mName;
|
|
#endif
|
|
BfIRLinkageType mLinkageType;
|
|
bool mIsVarReturn;
|
|
bool mAlwaysInline;
|
|
bool mNoUnwind;
|
|
bool mUWTable;
|
|
bool mNoReturn;
|
|
bool mDidInlinePass;
|
|
bool mNoFramePointerElim;
|
|
bool mIsDLLExport;
|
|
bool mIsDLLImport;
|
|
BfIRCallingConv mCallingConv;
|
|
Array<BeBlock*> mBlocks;
|
|
Array<BeFunctionParam> mParams;
|
|
BeDbgFunction* mDbgFunction;
|
|
BeGlobalVariable* mRemapBindVar;
|
|
|
|
public:
|
|
BeFunction()
|
|
{
|
|
mCallingConv = BfIRCallingConv_CDecl;
|
|
mLinkageType = BfIRLinkageType_External;
|
|
mModule = NULL;
|
|
mDbgFunction = NULL;
|
|
mIsVarReturn = false;
|
|
mAlwaysInline = false;
|
|
mDidInlinePass = false;
|
|
mNoUnwind = false;
|
|
mUWTable = false;
|
|
mNoReturn = false;
|
|
mNoFramePointerElim = false;
|
|
mIsDLLExport = false;
|
|
mIsDLLImport = false;
|
|
mRemapBindVar = NULL;
|
|
}
|
|
|
|
BeFunctionType* GetFuncType()
|
|
{
|
|
BF_ASSERT(mType->IsPointer());
|
|
return (BeFunctionType*)(((BePointerType*)mType)->mElementType);
|
|
}
|
|
|
|
bool IsDecl()
|
|
{
|
|
return mBlocks.size() == 0;
|
|
}
|
|
|
|
bool HasStructRet()
|
|
{
|
|
return (!mParams.IsEmpty()) && (mParams[0].mStructRet);
|
|
}
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override;
|
|
};
|
|
|
|
class BeBlock : public BeValue
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeBlock, BeValue);
|
|
|
|
String mName;
|
|
Array<BeInst*> mInstructions;
|
|
BeFunction* mFunction;
|
|
|
|
public:
|
|
bool IsEmpty();
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override;
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
class BeInst : public BeValue
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeInst, BeValue);
|
|
|
|
BeBlock* mParentBlock;
|
|
const char* mName;
|
|
BeDbgLoc* mDbgLoc;
|
|
|
|
public:
|
|
BeContext* GetContext();
|
|
BeModule* GetModule();
|
|
|
|
virtual bool CanBeReferenced()
|
|
{
|
|
return GetType() != NULL;
|
|
}
|
|
|
|
virtual void SetName(const StringImpl& name) override;
|
|
|
|
BeInst()
|
|
{
|
|
mParentBlock = NULL;
|
|
mName = NULL;
|
|
mDbgLoc = NULL;
|
|
}
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) = 0;
|
|
virtual void HashContent(BeHashContext& hashCtx) override;
|
|
};
|
|
|
|
class BeNopInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeNopInst, BeInst);
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
}
|
|
};
|
|
|
|
class BeUnreachableInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeUnreachableInst, BeInst);
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
}
|
|
};
|
|
|
|
class BeEnsureInstructionAtInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeEnsureInstructionAtInst, BeInst);
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
}
|
|
};
|
|
|
|
class BeUndefValueInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeUndefValueInst, BeInst);
|
|
|
|
BeType* mType;
|
|
|
|
virtual BeType* GetType() override;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mType->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeExtractValueInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeExtractValueInst, BeInst);
|
|
|
|
BeValue* mAggVal;
|
|
int mIdx;
|
|
|
|
virtual BeType* GetType() override;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mAggVal->HashReference(hashCtx);
|
|
hashCtx.Mixin(mIdx);
|
|
}
|
|
};
|
|
|
|
class BeInsertValueInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeInsertValueInst, BeInst);
|
|
|
|
BeValue* mAggVal;
|
|
BeValue* mMemberVal;
|
|
int mIdx;
|
|
|
|
virtual BeType* GetType() override;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mAggVal->HashReference(hashCtx);
|
|
mMemberVal->HashReference(hashCtx);
|
|
hashCtx.Mixin(mIdx);
|
|
}
|
|
};
|
|
|
|
class BeNumericCastInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeNumericCastInst, BeInst);
|
|
|
|
BeValue* mValue;
|
|
BeType* mToType;
|
|
bool mValSigned;
|
|
bool mToSigned;
|
|
|
|
virtual BeType* GetType() override;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mValue->HashReference(hashCtx);
|
|
mToType->HashReference(hashCtx);
|
|
hashCtx.Mixin(mValSigned);
|
|
hashCtx.Mixin(mToSigned);
|
|
}
|
|
};
|
|
|
|
class BeBitCastInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeBitCastInst, BeInst);
|
|
|
|
BeValue* mValue;
|
|
BeType* mToType;
|
|
|
|
virtual BeType* GetType() override;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mValue->HashReference(hashCtx);
|
|
mToType->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeNegInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeNegInst, BeInst);
|
|
|
|
BeValue* mValue;
|
|
virtual BeType* GetType() override;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mValue->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeNotInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeNotInst, BeInst);
|
|
|
|
BeValue* mValue;
|
|
virtual BeType* GetType() override;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mValue->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
enum BeBinaryOpKind
|
|
{
|
|
BeBinaryOpKind_None,
|
|
BeBinaryOpKind_Add,
|
|
BeBinaryOpKind_Subtract,
|
|
BeBinaryOpKind_Multiply,
|
|
BeBinaryOpKind_SDivide,
|
|
BeBinaryOpKind_UDivide,
|
|
BeBinaryOpKind_SModulus,
|
|
BeBinaryOpKind_UModulus,
|
|
BeBinaryOpKind_BitwiseAnd,
|
|
BeBinaryOpKind_BitwiseOr,
|
|
BeBinaryOpKind_ExclusiveOr,
|
|
BeBinaryOpKind_LeftShift,
|
|
BeBinaryOpKind_RightShift,
|
|
BeBinaryOpKind_ARightShift,
|
|
BeBinaryOpKind_Equality,
|
|
BeBinaryOpKind_InEquality,
|
|
BeBinaryOpKind_GreaterThan,
|
|
BeBinaryOpKind_LessThan,
|
|
BeBinaryOpKind_GreaterThanOrEqual,
|
|
BeBinaryOpKind_LessThanOrEqual,
|
|
};
|
|
|
|
class BeBinaryOpInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeBinaryOpInst, BeInst);
|
|
|
|
BeBinaryOpKind mOpKind;
|
|
BfOverflowCheckKind mOverflowCheckKind;
|
|
BeValue* mLHS;
|
|
BeValue* mRHS;
|
|
|
|
virtual BeType* GetType() override;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
hashCtx.Mixin(mOpKind);
|
|
hashCtx.Mixin(mOverflowCheckKind);
|
|
mLHS->HashReference(hashCtx);
|
|
mRHS->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
enum BeCmpKind
|
|
{
|
|
BeCmpKind_None,
|
|
|
|
BeCmpKind_SLT,
|
|
BeCmpKind_ULT,
|
|
BeCmpKind_SLE,
|
|
BeCmpKind_ULE,
|
|
BeCmpKind_EQ,
|
|
BeCmpKind_NE,
|
|
BeCmpKind_SGT,
|
|
BeCmpKind_UGT,
|
|
BeCmpKind_SGE,
|
|
BeCmpKind_UGE,
|
|
BeCmpKind_NB,
|
|
BeCmpKind_NO,
|
|
};
|
|
|
|
class BeCmpInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeCmpInst, BeInst);
|
|
|
|
BeValue* mLHS;
|
|
BeValue* mRHS;
|
|
BeCmpKind mCmpKind;
|
|
|
|
virtual BeType* GetType() override;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mLHS->HashReference(hashCtx);
|
|
mRHS->HashReference(hashCtx);
|
|
hashCtx.Mixin(mCmpKind);
|
|
}
|
|
};
|
|
|
|
class BeObjectAccessCheckInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeObjectAccessCheckInst, BeInst);
|
|
|
|
BeValue* mValue;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mValue->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeAllocaInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeAllocaInst, BeInst);
|
|
|
|
BeType* mType;
|
|
BeValue* mArraySize;
|
|
int mAlign;
|
|
bool mNoChkStk;
|
|
bool mForceMem;
|
|
|
|
public:
|
|
virtual BeType* GetType() override;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mType->HashReference(hashCtx);
|
|
if (mArraySize != NULL)
|
|
mArraySize->HashReference(hashCtx);
|
|
hashCtx.Mixin(mAlign);
|
|
hashCtx.Mixin(mNoChkStk);
|
|
hashCtx.Mixin(mForceMem);
|
|
}
|
|
};
|
|
|
|
class BeAliasValueInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeAliasValueInst, BeInst);
|
|
|
|
BeValue* mPtr;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mPtr->HashReference(hashCtx);
|
|
}
|
|
|
|
virtual BeType* GetType() override
|
|
{
|
|
return mPtr->GetType();
|
|
}
|
|
};
|
|
|
|
class BeLifetimeStartInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeLifetimeStartInst, BeInst);
|
|
|
|
BeValue* mPtr;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mPtr->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeLifetimeEndInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeLifetimeEndInst, BeInst);
|
|
|
|
BeValue* mPtr;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mPtr->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeLifetimeSoftEndInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeLifetimeSoftEndInst, BeInst);
|
|
|
|
BeValue* mPtr;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mPtr->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeLifetimeFenceInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeLifetimeFenceInst, BeInst);
|
|
|
|
BeBlock* mFenceBlock; // Lifetime is blocked from extending into the end of this block
|
|
BeValue* mPtr;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mFenceBlock->HashReference(hashCtx);
|
|
mPtr->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeLifetimeExtendInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeLifetimeExtendInst, BeInst);
|
|
|
|
BeValue* mPtr;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mPtr->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeValueScopeStartInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeValueScopeStartInst, BeInst);
|
|
|
|
virtual BeType* GetType() override;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
}
|
|
};
|
|
|
|
class BeValueScopeRetainInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeValueScopeRetainInst, BeInst);
|
|
|
|
BeValue* mValue;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mValue->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeValueScopeEndInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeValueScopeEndInst, BeInst);
|
|
|
|
BeValueScopeStartInst* mScopeStart;
|
|
bool mIsSoft;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mScopeStart->HashReference(hashCtx);
|
|
hashCtx.Mixin(mIsSoft);
|
|
}
|
|
};
|
|
|
|
class BeLoadInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeLoadInst, BeInst);
|
|
|
|
BeValue* mTarget;
|
|
bool mIsVolatile;
|
|
|
|
public:
|
|
virtual BeType* GetType() override;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mTarget->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeStoreInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeStoreInst, BeInst);
|
|
|
|
BeValue* mVal;
|
|
BeValue* mPtr;
|
|
bool mIsVolatile;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mVal->HashReference(hashCtx);
|
|
mPtr->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeSetCanMergeInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeSetCanMergeInst, BeInst);
|
|
|
|
BeValue* mVal;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mVal->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeMemSetInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeGEPInst, BeInst);
|
|
|
|
BeValue* mAddr;
|
|
BeValue* mVal;
|
|
BeValue* mSize;
|
|
int mAlignment;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mAddr->HashReference(hashCtx);
|
|
mVal->HashReference(hashCtx);
|
|
mSize->HashReference(hashCtx);
|
|
hashCtx.Mixin(mAlignment);
|
|
}
|
|
};
|
|
|
|
class BeFenceInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeFenceInst, BeInst);
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
}
|
|
};
|
|
|
|
class BeStackSaveInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeStackSaveInst, BeInst);
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
}
|
|
|
|
virtual BeType* GetType() override
|
|
{
|
|
return GetContext()->GetPrimitiveType(BeTypeCode_NullPtr);
|
|
}
|
|
};
|
|
|
|
class BeStackRestoreInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeStackRestoreInst, BeInst);
|
|
|
|
BeValue* mStackVal;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mStackVal->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeGEPInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeGEPInst, BeInst);
|
|
|
|
BeValue* mPtr;
|
|
BeValue* mIdx0;
|
|
BeValue* mIdx1;
|
|
|
|
virtual BeType* GetType() override;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mPtr->HashReference(hashCtx);
|
|
mIdx0->HashReference(hashCtx);
|
|
if (mIdx1 != NULL)
|
|
mIdx1->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeBrInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeBrInst, BeInst);
|
|
|
|
BeBlock* mTargetBlock;
|
|
bool mNoCollapse;
|
|
bool mIsFake;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mTargetBlock->HashReference(hashCtx);
|
|
hashCtx.Mixin(mNoCollapse);
|
|
hashCtx.Mixin(mIsFake);
|
|
}
|
|
};
|
|
|
|
class BeCondBrInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeCondBrInst, BeInst);
|
|
|
|
BeValue* mCond;
|
|
BeBlock* mTrueBlock;
|
|
BeBlock* mFalseBlock;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mCond->HashReference(hashCtx);
|
|
mTrueBlock->HashReference(hashCtx);
|
|
mFalseBlock->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BePhiIncoming : public BeValue
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BePhiIncoming, BeValue);
|
|
|
|
BeBlock* mBlock;
|
|
BeValue* mValue;
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mBlock->HashReference(hashCtx);
|
|
mValue->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BePhiInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BePhiInst, BeInst);
|
|
|
|
BeType* mType;
|
|
SizedArray<BePhiIncoming*, 4> mIncoming;
|
|
|
|
virtual BeType* GetType() override;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mType->HashReference(hashCtx);
|
|
hashCtx.Mixin(mIncoming.size());
|
|
for (auto incoming : mIncoming)
|
|
{
|
|
incoming->mBlock->HashReference(hashCtx);
|
|
incoming->mValue->HashReference(hashCtx);
|
|
}
|
|
}
|
|
};
|
|
|
|
class BeSwitchCase
|
|
{
|
|
public:
|
|
BeConstant* mValue;
|
|
BeBlock* mBlock;
|
|
};
|
|
|
|
class BeSwitchInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeSwitchInst, BeInst);
|
|
|
|
BeValue* mValue;
|
|
BeBlock* mDefaultBlock;
|
|
Array<BeSwitchCase> mCases;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mValue->HashReference(hashCtx);
|
|
mDefaultBlock->HashReference(hashCtx);
|
|
for (auto& caseVal : mCases)
|
|
{
|
|
caseVal.mValue->HashReference(hashCtx);
|
|
caseVal.mBlock->HashReference(hashCtx);
|
|
}
|
|
}
|
|
};
|
|
|
|
class BeRetInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeRetInst, BeInst);
|
|
|
|
BeValue* mRetValue;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
if (mRetValue != NULL)
|
|
mRetValue->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeSetRetInst : public BeRetInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeSetRetInst, BeRetInst);
|
|
|
|
public:
|
|
int32 mReturnTypeId;
|
|
};
|
|
|
|
class BeCallInst : public BeInst
|
|
{
|
|
public:
|
|
struct Arg
|
|
{
|
|
BeValue* mValue;
|
|
int mDereferenceableSize;
|
|
int mByRefSize;
|
|
bool mStructRet;
|
|
bool mZExt;
|
|
bool mNoAlias;
|
|
bool mNoCapture;
|
|
Arg()
|
|
{
|
|
mValue = NULL;
|
|
mStructRet = false;
|
|
mZExt = false;
|
|
mNoAlias = false;
|
|
mNoCapture = false;
|
|
mDereferenceableSize = -1;
|
|
mByRefSize = -1;
|
|
}
|
|
};
|
|
|
|
public:
|
|
BE_VALUE_TYPE(BeCallInst, BeInst);
|
|
|
|
BeValue* mInlineResult;
|
|
BeValue* mFunc;
|
|
SizedArray<Arg, 4> mArgs;
|
|
BfIRCallingConv mCallingConv;
|
|
bool mNoReturn;
|
|
bool mTailCall;
|
|
|
|
virtual BeType* GetType() override;
|
|
|
|
BeCallInst()
|
|
{
|
|
mInlineResult = NULL;
|
|
mFunc = NULL;
|
|
mCallingConv = BfIRCallingConv_CDecl;
|
|
mNoReturn = false;
|
|
mTailCall = false;
|
|
}
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
if (mInlineResult != NULL)
|
|
mInlineResult->HashReference(hashCtx);
|
|
mFunc->HashReference(hashCtx);
|
|
for (auto& arg : mArgs)
|
|
{
|
|
arg.mValue->HashReference(hashCtx);
|
|
hashCtx.Mixin(arg.mStructRet);
|
|
hashCtx.Mixin(arg.mZExt);
|
|
hashCtx.Mixin(arg.mDereferenceableSize);
|
|
hashCtx.Mixin(arg.mByRefSize);
|
|
}
|
|
hashCtx.Mixin(mCallingConv);
|
|
hashCtx.Mixin(mNoReturn);
|
|
hashCtx.Mixin(mTailCall);
|
|
}
|
|
|
|
bool HasStructRet()
|
|
{
|
|
return (!mArgs.IsEmpty()) && (mArgs[0].mStructRet);
|
|
}
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
class BeComptimeError : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeComptimeError, BeInst);
|
|
|
|
public:
|
|
int mError;
|
|
|
|
public:
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
hashCtx.Mixin(mError);
|
|
}
|
|
};
|
|
|
|
class BeComptimeGetType : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeComptimeGetType, BeInst);
|
|
|
|
public:
|
|
int mTypeId;
|
|
BeType* mResultType;
|
|
|
|
public:
|
|
virtual BeType* GetType() override
|
|
{
|
|
return mResultType;
|
|
}
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
hashCtx.Mixin(mTypeId);
|
|
}
|
|
};
|
|
|
|
class BeComptimeGetReflectType : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeComptimeGetReflectType, BeInst);
|
|
|
|
public:
|
|
int mTypeId;
|
|
BeType* mResultType;
|
|
|
|
public:
|
|
virtual BeType* GetType() override
|
|
{
|
|
return mResultType;
|
|
}
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
hashCtx.Mixin(mTypeId);
|
|
}
|
|
};
|
|
|
|
class BeComptimeDynamicCastCheck : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeComptimeDynamicCastCheck, BeInst);
|
|
|
|
public:
|
|
BeValue* mValue;
|
|
int mTypeId;
|
|
BeType* mResultType;
|
|
|
|
public:
|
|
virtual BeType* GetType() override
|
|
{
|
|
return mResultType;
|
|
}
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mValue->HashReference(hashCtx);
|
|
hashCtx.Mixin(mTypeId);
|
|
}
|
|
};
|
|
|
|
class BeComptimeGetVirtualFunc : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeComptimeGetVirtualFunc, BeInst);
|
|
|
|
public:
|
|
BeValue* mValue;
|
|
int mVirtualTableIdx;
|
|
BeType* mResultType;
|
|
|
|
public:
|
|
virtual BeType* GetType() override
|
|
{
|
|
return mResultType;
|
|
}
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mValue->HashReference(hashCtx);
|
|
hashCtx.Mixin(mVirtualTableIdx);
|
|
}
|
|
};
|
|
|
|
class BeComptimeGetInterfaceFunc : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeComptimeGetInterfaceFunc, BeInst);
|
|
|
|
public:
|
|
BeValue* mValue;
|
|
int mIFaceTypeId;
|
|
int mMethodIdx;
|
|
BeType* mResultType;
|
|
|
|
public:
|
|
virtual BeType* GetType() override
|
|
{
|
|
return mResultType;
|
|
}
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mValue->HashReference(hashCtx);
|
|
hashCtx.Mixin(mIFaceTypeId);
|
|
hashCtx.Mixin(mMethodIdx);
|
|
}
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
class BeArgument : public BeValue
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeArgument, BeValue);
|
|
|
|
BeModule* mModule;
|
|
int mArgIdx;
|
|
|
|
virtual BeType* GetType() override;
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
hashCtx.Mixin(mArgIdx);
|
|
}
|
|
};
|
|
|
|
struct BeDumpContext
|
|
{
|
|
public:
|
|
Dictionary<BeValue*, String> mValueNameMap;
|
|
Dictionary<String, int> mSeenNames;
|
|
|
|
void ToString(StringImpl& str, BeValue* value, bool showType = true, bool mdDrillDown = false);
|
|
void ToString(StringImpl& str, BeType* type);
|
|
void ToString(StringImpl& str, BeDbgFunction* dbgFunction, bool showScope);
|
|
static void ToString(StringImpl& str, int val);
|
|
static void ToString(StringImpl& str, BeCmpKind cmpKind);
|
|
static void ToString(StringImpl& str, BeBinaryOpKind opKind);
|
|
|
|
String ToString(BeValue* value, bool showType = true, bool mdDrillDown = false);
|
|
String ToString(BeType* type);
|
|
String ToString(BeDbgFunction* dbgFunction);
|
|
static String ToString(int val);
|
|
static String ToString(BeCmpKind cmpKind);
|
|
static String ToString(BeBinaryOpKind opKind);
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
class BeDbgVariable;
|
|
|
|
class BeDbgDeclareInst : public BeInst
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeDbgDeclareInst, BeInst);
|
|
|
|
public:
|
|
BeDbgVariable* mDbgVar;
|
|
BeValue* mValue;
|
|
bool mIsValue;
|
|
|
|
virtual void HashInst(BeHashContext& hashCtx) override;
|
|
};
|
|
|
|
class BeMDNode : public BeValue
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeMDNode, BeValue);
|
|
|
|
public:
|
|
virtual ~BeMDNode()
|
|
{
|
|
}
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
}
|
|
};
|
|
|
|
class BeDbgFile;
|
|
|
|
class BeDbgLoc : public BeMDNode
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeDbgLoc, BeMDNode);
|
|
|
|
public:
|
|
int mLine;
|
|
int mColumn;
|
|
BeMDNode* mDbgScope;
|
|
BeDbgLoc* mDbgInlinedAt;
|
|
int mIdx;
|
|
bool mHadInline;
|
|
|
|
public:
|
|
BeDbgLoc()
|
|
{
|
|
}
|
|
|
|
int GetInlineDepth();
|
|
int GetInlineMatchDepth(BeDbgLoc* other);
|
|
BeDbgLoc* GetInlinedAt(int idx = 0);
|
|
BeDbgLoc* GetRoot();
|
|
BeDbgFunction* GetDbgFunc();
|
|
BeDbgFile* GetDbgFile();
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
hashCtx.Mixin(mLine);
|
|
hashCtx.Mixin(mColumn);
|
|
if (mDbgScope != NULL)
|
|
mDbgScope->HashReference(hashCtx);
|
|
else
|
|
hashCtx.Mixin(-1);
|
|
if (mDbgInlinedAt != NULL)
|
|
mDbgInlinedAt->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeDbgLexicalBlock : public BeMDNode
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeDbgLexicalBlock, BeMDNode);
|
|
|
|
public:
|
|
BeDbgFile* mFile;
|
|
BeMDNode* mScope;
|
|
BeBlock* mLastBeBlock;
|
|
int mId;
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override;
|
|
};
|
|
|
|
class BeDbgNamespace : public BeMDNode
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeDbgNamespace, BeMDNode);
|
|
|
|
public:
|
|
BeMDNode* mScope;
|
|
String mName;
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mScope->HashReference(hashCtx);
|
|
hashCtx.MixinStr(mName);
|
|
}
|
|
};
|
|
|
|
class BeDbgTypeId : public BeMDNode
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeDbgTypeId, BeMDNode);
|
|
|
|
public:
|
|
int mTypeId;
|
|
|
|
BeDbgTypeId()
|
|
{
|
|
mTypeId = -1;
|
|
}
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
hashCtx.Mixin(mTypeId);
|
|
}
|
|
};
|
|
|
|
class BeDbgType : public BeMDNode
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeDbgType, BeMDNode);
|
|
|
|
public:
|
|
int mSize;
|
|
int mAlign;
|
|
int mCvDeclTypeId;
|
|
int mCvDefTypeId;
|
|
BumpList<BeDbgType*> mDerivedTypes;
|
|
|
|
BeDbgType()
|
|
{
|
|
mSize = -1;
|
|
mAlign = -1;
|
|
mCvDeclTypeId = -1;
|
|
mCvDefTypeId = -1;
|
|
}
|
|
|
|
BeDbgType* FindDerivedType(int typeId)
|
|
{
|
|
for (auto derivedType : mDerivedTypes)
|
|
{
|
|
if (derivedType->GetTypeId() == typeId)
|
|
return derivedType;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
hashCtx.Mixin(mSize);
|
|
hashCtx.Mixin(mAlign);
|
|
}
|
|
};
|
|
|
|
class BeDbgBasicType : public BeDbgType
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeDbgBasicType, BeDbgType);
|
|
|
|
public:
|
|
String mName;
|
|
int mEncoding;
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
hashCtx.Mixin(mSize);
|
|
hashCtx.Mixin(mAlign);
|
|
hashCtx.MixinStr(mName);
|
|
hashCtx.Mixin(mEncoding);
|
|
}
|
|
};
|
|
|
|
class BeDbgArrayType : public BeDbgType
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeDbgArrayType, BeDbgType);
|
|
|
|
public:
|
|
BeDbgType* mElement;
|
|
int mNumElements;
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
hashCtx.Mixin(mSize);
|
|
hashCtx.Mixin(mAlign);
|
|
hashCtx.Mixin(mNumElements);
|
|
mElement->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeDbgArtificialType : public BeDbgType
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeDbgArtificialType, BeDbgType);
|
|
|
|
public:
|
|
BeDbgType* mElement;
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mElement->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeDbgConstType : public BeDbgType
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeDbgConstType, BeDbgType);
|
|
|
|
public:
|
|
BeMDNode* mElement;
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mElement->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeDbgReferenceType : public BeDbgType
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeDbgReferenceType, BeDbgType);
|
|
|
|
public:
|
|
BeDbgType* mElement;
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mElement->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeDbgPointerType : public BeDbgType
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeDbgPointerType, BeDbgType);
|
|
|
|
public:
|
|
BeDbgType* mElement;
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mElement->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeDbgInheritance : public BeMDNode
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeDbgInheritance, BeMDNode);
|
|
|
|
public:
|
|
BeDbgType* mBaseType;
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mBaseType->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeDbgStructMember : public BeMDNode
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeDbgStructMember, BeMDNode);
|
|
|
|
public:
|
|
String mName;
|
|
BeDbgType* mType;
|
|
int mFlags;
|
|
int mOffset;
|
|
bool mIsStatic;
|
|
BeValue* mStaticValue;
|
|
|
|
public:
|
|
BeDbgStructMember()
|
|
{
|
|
mType = NULL;
|
|
mFlags = 0;
|
|
mOffset = -1;
|
|
mIsStatic = false;
|
|
mStaticValue = NULL;
|
|
}
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
hashCtx.MixinStr(mName);
|
|
mType->HashReference(hashCtx);
|
|
hashCtx.Mixin(mFlags);
|
|
hashCtx.Mixin(mOffset);
|
|
hashCtx.Mixin(mIsStatic);
|
|
if (mStaticValue != NULL)
|
|
mStaticValue->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeDbgFunctionType : public BeMDNode
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeDbgFunctionType, BeMDNode);
|
|
|
|
public:
|
|
BeDbgType* mReturnType;
|
|
Array<BeDbgType*> mParams;
|
|
|
|
public:
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
if (mReturnType != NULL)
|
|
mReturnType->HashReference(hashCtx);
|
|
hashCtx.Mixin(mParams.size());
|
|
for (auto param : mParams)
|
|
param->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
/*class BeDbgVariableRange
|
|
{
|
|
public:
|
|
enum Kind
|
|
{
|
|
Kind_None,
|
|
Kind_Reg, // Direct reg usage
|
|
Kind_Indexed // [RBP+8] type usage (spilled)
|
|
};
|
|
|
|
public:
|
|
int mCodeStartOfs;
|
|
int mCodeRange;
|
|
Kind mKind;
|
|
X64CPURegister mReg;
|
|
int mOfs;
|
|
|
|
public:
|
|
BeDbgVariableRange()
|
|
{
|
|
mCodeStartOfs = -1;
|
|
mCodeRange = -1;
|
|
mKind = Kind_None;
|
|
mReg = X64Reg_None;
|
|
mOfs = 0;
|
|
}
|
|
};*/
|
|
|
|
class BeDbgVariableRange
|
|
{
|
|
public:
|
|
int mOffset;
|
|
int mLength;
|
|
};
|
|
|
|
class BeDbgVariableLoc
|
|
{
|
|
public:
|
|
enum Kind
|
|
{
|
|
Kind_None,
|
|
Kind_Reg, // Direct reg usage
|
|
Kind_Indexed, // [RBP+8] type usage (spilled)
|
|
Kind_SymbolAddr
|
|
};
|
|
|
|
Kind mKind;
|
|
X64CPURegister mReg;
|
|
int mOfs;
|
|
|
|
public:
|
|
BeDbgVariableLoc()
|
|
{
|
|
mKind = Kind_None;
|
|
mReg = X64Reg_None;
|
|
mOfs = 0;
|
|
}
|
|
};
|
|
|
|
class BeDbgVariable : public BeMDNode
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeDbgVariable, BeMDNode);
|
|
|
|
public:
|
|
String mName;
|
|
BeMDNode* mType;
|
|
BeValue* mValue;
|
|
int mParamNum;
|
|
BfIRInitType mInitType;
|
|
BfIRInitType mPendingInitType;
|
|
bool mPendingInitDef;
|
|
BeMDNode* mScope;
|
|
|
|
BeDbgLoc* mDeclDbgLoc;
|
|
BeDbgVariableLoc mPrimaryLoc;
|
|
BeDbgVariableLoc mSavedLoc;
|
|
int mDeclStart;
|
|
int mDeclEnd;
|
|
int mDeclMCBlockId;
|
|
bool mDeclLifetimeExtend;
|
|
bool mDbgLifeEnded;
|
|
bool mIsValue; // Value vs Addr
|
|
|
|
Array<BeDbgVariableRange> mSavedRanges;
|
|
Array<BeDbgVariableRange> mGaps;
|
|
|
|
public:
|
|
BeDbgVariable()
|
|
{
|
|
mType = NULL;
|
|
mValue = NULL;
|
|
mParamNum = -1;
|
|
mInitType = BfIRInitType_NotSet;
|
|
mPendingInitType = BfIRInitType_NotNeeded;
|
|
mPendingInitDef = false;
|
|
mScope = NULL;
|
|
mDeclDbgLoc = NULL;
|
|
mDeclStart = -1;
|
|
mDeclEnd = -1;
|
|
mDeclMCBlockId = -1;
|
|
mIsValue = false;
|
|
mDbgLifeEnded = false;
|
|
mDeclLifetimeExtend = false;
|
|
}
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
hashCtx.MixinStr(mName);
|
|
mType->HashReference(hashCtx);
|
|
if (mValue != NULL)
|
|
mValue->HashReference(hashCtx);
|
|
hashCtx.Mixin(mParamNum);
|
|
hashCtx.Mixin(mInitType);
|
|
hashCtx.Mixin(mPendingInitType);
|
|
if (mScope != NULL)
|
|
mScope->HashReference(hashCtx);
|
|
if (mDeclDbgLoc != NULL)
|
|
mDeclDbgLoc->HashReference(hashCtx);
|
|
|
|
// The others only get filled in after generation -- not part of hash
|
|
}
|
|
};
|
|
|
|
class BeDbgFile;
|
|
|
|
class BeDbgCodeEmission
|
|
{
|
|
public:
|
|
BeDbgLoc* mDbgLoc;
|
|
int mPos;
|
|
};
|
|
|
|
class BeDbgFunction : public BeMDNode
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeDbgFunction, BeMDNode);
|
|
|
|
public:
|
|
int mIdx;
|
|
|
|
BeMDNode* mScope;
|
|
BeDbgFile* mFile;
|
|
int mLine;
|
|
String mName;
|
|
String mLinkageName;
|
|
BeDbgFunctionType* mType;
|
|
//Array<BeDbgVariable*> mParams;
|
|
Array<BeDbgType*> mGenericArgs;
|
|
Array<BeConstant*> mGenericConstValueArgs;
|
|
BeFunction* mValue;
|
|
bool mIsLocalToUnit;
|
|
bool mIsStaticMethod;
|
|
bool mIncludedAsMember;
|
|
int mFlags;
|
|
int mVK;
|
|
int mVIndex;
|
|
|
|
Array<BeDbgVariable*> mVariables;
|
|
int mPrologSize;
|
|
int mCodeLen;
|
|
Array<BeDbgCodeEmission> mEmissions;
|
|
|
|
int mCvTypeId;
|
|
int mCvFuncId;
|
|
int mCvArgListId;
|
|
|
|
public:
|
|
BeDbgFunction()
|
|
{
|
|
mIdx = -1;
|
|
mScope = NULL;
|
|
mFile = NULL;
|
|
mLine = -1;
|
|
mType = NULL;
|
|
mValue = NULL;
|
|
mFlags = 0;
|
|
mIsLocalToUnit = false;
|
|
mVK = -1;
|
|
mVIndex = -1;
|
|
mIsStaticMethod = true;
|
|
mIncludedAsMember = false;
|
|
mPrologSize = 0;
|
|
mCodeLen = -1;
|
|
mCvTypeId = -1;
|
|
mCvFuncId = -1;
|
|
mCvArgListId = -1;
|
|
}
|
|
|
|
BeMDNode* GetParamType(int paramIdx)
|
|
{
|
|
/*if (!mParams.empty())
|
|
return mParams[paramIdx]->mType;*/
|
|
if (paramIdx < (int)mVariables.size())
|
|
{
|
|
auto param = mVariables[paramIdx];
|
|
if (param->mParamNum == paramIdx)
|
|
return param->mType;
|
|
}
|
|
return mType->mParams[paramIdx];
|
|
}
|
|
|
|
bool HasThis()
|
|
{
|
|
return !mIsStaticMethod;
|
|
|
|
/*bool matchLLVM = false;
|
|
|
|
// This matches the LLVM CV emitter
|
|
if (matchLLVM)
|
|
{
|
|
return (BeValueDynCast<BeDbgType>(mScope) != NULL) &&
|
|
(mType->mParams.size() > 0);
|
|
}
|
|
else
|
|
{
|
|
return ((mVariables.size() > 0) && (mVariables[0]->mName == "this"));
|
|
}*/
|
|
}
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override;
|
|
};
|
|
|
|
class BeDbgInlinedScope : public BeMDNode
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeDbgInlinedScope, BeMDNode);
|
|
BeMDNode* mScope;
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
mScope->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeDbgFile;
|
|
|
|
class BeDbgStructType : public BeDbgType
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeDbgStructType, BeDbgType);
|
|
|
|
public:
|
|
BeMDNode* mScope;
|
|
String mName;
|
|
BeDbgType* mDerivedFrom;
|
|
Array<BeDbgStructMember*> mMembers;
|
|
Array<BeDbgFunction*> mMethods;
|
|
bool mIsFullyDefined;
|
|
bool mIsStatic;
|
|
BeDbgFile* mDefFile;
|
|
int mDefLine;
|
|
|
|
public:
|
|
BeDbgStructType()
|
|
{
|
|
mScope = NULL;
|
|
mDerivedFrom = NULL;
|
|
mIsStatic = false;
|
|
mIsFullyDefined = false;
|
|
mDefFile = NULL;
|
|
mDefLine = 0;
|
|
}
|
|
|
|
void SetMembers(SizedArrayImpl<BeMDNode*>& members);
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override;
|
|
};
|
|
|
|
class BeDbgEnumMember : public BeMDNode
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeDbgEnumMember, BeMDNode);
|
|
|
|
public:
|
|
String mName;
|
|
int64 mValue;
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
hashCtx.MixinStr(mName);
|
|
hashCtx.Mixin(mValue);
|
|
}
|
|
};
|
|
|
|
class BeDbgEnumType : public BeDbgType
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeDbgEnumType, BeDbgType);
|
|
|
|
public:
|
|
BeMDNode* mScope;
|
|
String mName;
|
|
BeDbgType* mElementType;
|
|
bool mIsFullyDefined;
|
|
Array<BeDbgEnumMember*> mMembers;
|
|
|
|
public:
|
|
BeDbgEnumType()
|
|
{
|
|
mScope = NULL;
|
|
mElementType = NULL;
|
|
mIsFullyDefined = false;
|
|
}
|
|
|
|
void SetMembers(SizedArrayImpl<BeMDNode*>& members);
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
mScope->HashReference(hashCtx);
|
|
hashCtx.MixinStr(mName);
|
|
if (mElementType != NULL)
|
|
mElementType->HashReference(hashCtx);
|
|
hashCtx.Mixin(mIsFullyDefined);
|
|
for (auto member : mMembers)
|
|
member->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeDbgFile : public BeMDNode
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeDbgFile, BeMDNode);
|
|
|
|
public:
|
|
String mFileName;
|
|
String mDirectory;
|
|
Val128 mMD5Hash;
|
|
int mIdx;
|
|
|
|
void ToString(String& str);
|
|
void GetFilePath(String& outStr);
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
hashCtx.MixinStr(mFileName);
|
|
hashCtx.Mixin(mMD5Hash);
|
|
hashCtx.MixinStr(mDirectory);
|
|
}
|
|
};
|
|
|
|
class BeDbgGlobalVariable : public BeMDNode
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeDbgGlobalVariable, BeMDNode);
|
|
|
|
BeMDNode* mContext;
|
|
String mName;
|
|
String mLinkageName;
|
|
BeDbgFile* mFile;
|
|
int mLineNum;
|
|
BeMDNode* mType;
|
|
bool mIsLocalToUnit;
|
|
BeConstant* mValue;
|
|
BeMDNode* mDecl;
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override
|
|
{
|
|
hashCtx.Mixin(TypeId);
|
|
hashCtx.MixinStr(mName);
|
|
hashCtx.MixinStr(mLinkageName);
|
|
if (mFile != NULL)
|
|
mFile->HashReference(hashCtx);
|
|
hashCtx.Mixin(mLineNum);
|
|
mType->HashReference(hashCtx);
|
|
hashCtx.Mixin(mIsLocalToUnit);
|
|
if (mValue != NULL)
|
|
mValue->HashReference(hashCtx);
|
|
if (mDecl != NULL)
|
|
mDecl->HashReference(hashCtx);
|
|
}
|
|
};
|
|
|
|
class BeDbgModule : public BeMDNode
|
|
{
|
|
public:
|
|
BE_VALUE_TYPE(BeDbgModule, BeMDNode);
|
|
|
|
public:
|
|
BeModule* mBeModule;
|
|
String mFileName;
|
|
String mDirectory;
|
|
String mProducer;
|
|
|
|
OwnedVector<BeDbgFile> mFiles;
|
|
OwnedVector<BeDbgNamespace> mNamespaces;
|
|
OwnedVector<BeDbgGlobalVariable> mGlobalVariables;
|
|
|
|
OwnedVector<BeMDNode> mTypes;
|
|
Array<BeDbgFunction*> mFuncs; // Does not include methods in structs
|
|
|
|
virtual void HashContent(BeHashContext& hashCtx) override;
|
|
BeDbgReferenceType* CreateReferenceType(BeDbgType* dbgType);
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
class BeDbgModule;
|
|
|
|
class BeModule
|
|
{
|
|
public:
|
|
BeIRCodeGen* mBeIRCodeGen;
|
|
Array<BeConstant*> mConfigConsts32;
|
|
Array<BeConstant*> mConfigConsts64;
|
|
|
|
BeFunction* mActiveFunction;
|
|
BumpAllocator mAlloc;
|
|
OwnedVector<BeValue> mOwnedValues; // Those that need dtors
|
|
OwnedVector<BeGlobalVariable> mGlobalVariables;
|
|
BeContext* mContext;
|
|
String mModuleName;
|
|
String mTargetTriple;
|
|
String mTargetCPU;
|
|
BeBlock* mActiveBlock;
|
|
int mInsertPos;
|
|
BeDbgLoc* mCurDbgLoc;
|
|
BeDbgLoc* mPrevDbgLocInline;
|
|
BeDbgLoc* mLastDbgLoc;
|
|
Array<BeArgument*> mArgs;
|
|
Array<BeFunction*> mFunctions;
|
|
Dictionary<String, BeFunction*> mFunctionMap;
|
|
int mCurDbgLocIdx;
|
|
int mCurLexBlockId;
|
|
|
|
BeDbgModule* mDbgModule;
|
|
CeMachine* mCeMachine;
|
|
|
|
public:
|
|
void AddInst(BeInst* inst);
|
|
static void ToString(StringImpl& str, BeType* type);
|
|
static void StructToString(StringImpl& str, BeStructType* type);
|
|
|
|
template <typename T>
|
|
T* AllocInst()
|
|
{
|
|
T* newInst = mAlloc.Alloc<T>();
|
|
AddInst(newInst);
|
|
return newInst;
|
|
}
|
|
|
|
template <typename T>
|
|
T* AllocInstOwned()
|
|
{
|
|
T* newInst = mOwnedValues.Alloc<T>();
|
|
AddInst(newInst);
|
|
return newInst;
|
|
}
|
|
|
|
public:
|
|
BeModule(const StringImpl& moduleName, BeContext* context);
|
|
~BeModule();
|
|
|
|
void Hash(BeHashContext& hashCtx);
|
|
|
|
String ToString(BeFunction* func = NULL);
|
|
void Print();
|
|
void Print(BeFunction* func);
|
|
void PrintValue(BeValue* val);
|
|
|
|
void DoInlining(BeFunction* func);
|
|
void DoInlining();
|
|
|
|
static BeCmpKind InvertCmp(BeCmpKind cmpKind);
|
|
static BeCmpKind SwapCmpSides(BeCmpKind cmpKind);
|
|
void SetActiveFunction(BeFunction* function);
|
|
BeArgument* GetArgument(int arg);
|
|
BeBlock* CreateBlock(const StringImpl& name);
|
|
void AddBlock(BeFunction* function, BeBlock* block);
|
|
void RemoveBlock(BeFunction* function, BeBlock* block);
|
|
BeBlock* GetInsertBlock();
|
|
void SetInsertPoint(BeBlock* block);
|
|
void SetInsertPointAtStart(BeBlock* block);
|
|
BeFunction* CreateFunction(BeFunctionType* funcType, BfIRLinkageType linkageType, const StringImpl& name);
|
|
BeDbgLoc* GetCurrentDebugLocation();
|
|
void SetCurrentDebugLocation(BeDbgLoc* dbgLoc);
|
|
void SetCurrentDebugLocation(int line, int column, BeMDNode* diScope, BeDbgLoc* diInlinedAt);
|
|
BeDbgLoc* DupDebugLocation(BeDbgLoc* dbgLoc);
|
|
void DupCurrentDebugLocation();
|
|
|
|
///
|
|
BeNopInst* CreateNop();
|
|
BeUndefValueInst* CreateUndefValue(BeType* type);
|
|
BeNumericCastInst* CreateNumericCast(BeValue* value, BeType* toType, bool valSigned, bool toSigned);
|
|
BeBitCastInst* CreateBitCast(BeValue* value, BeType* toType);;
|
|
BeCmpInst* CreateCmp(BeCmpKind cmpKind, BeValue* lhs, BeValue* rhs);
|
|
BeBinaryOpInst* CreateBinaryOp(BeBinaryOpKind opKind, BeValue* lhs, BeValue* rhs, BfOverflowCheckKind overflowCheckKind = BfOverflowCheckKind_None);
|
|
|
|
BeAllocaInst* CreateAlloca(BeType* type);
|
|
BeLoadInst* CreateLoad(BeValue* value, bool isVolatile);
|
|
BeLoadInst* CreateAlignedLoad(BeValue* value, int alignment, bool isVolatile);
|
|
BeStoreInst* CreateStore(BeValue* val, BeValue* ptr, bool isVolatile);
|
|
BeStoreInst* CreateAlignedStore(BeValue* val, BeValue* ptr, int alignment, bool isVolatile);
|
|
BeGEPInst* CreateGEP(BeValue* ptr, BeValue* idx0, BeValue* idx1);
|
|
|
|
BeBrInst* CreateBr(BeBlock* block);
|
|
BeCondBrInst* CreateCondBr(BeValue* cond, BeBlock* trueBlock, BeBlock* falseBlock);
|
|
BeRetInst* CreateRetVoid();
|
|
BeRetInst* CreateRet(BeValue* value);
|
|
BeSetRetInst* CreateSetRet(BeValue* value, int returnTypeId);
|
|
BeCallInst* CreateCall(BeValue* func, const SizedArrayImpl<BeValue*>& args);
|
|
|
|
BeConstant* GetConstant(BeType* type, double floatVal);
|
|
BeConstant* GetConstant(BeType* type, int64 intVal);
|
|
BeConstant* GetConstant(BeType* type, bool boolVal);
|
|
BeConstant* GetConstantNull(BePointerType* type);
|
|
};
|
|
|
|
NS_BF_END |