1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 11:38:21 +02:00

Added a 'cast' intrinsic

This commit is contained in:
Brian Fiete 2020-02-19 13:16:33 -08:00
parent 660e7d8125
commit 1f20d76f94
14 changed files with 75 additions and 22 deletions

View file

@ -102,7 +102,7 @@ namespace System
}
}
[AttributeUsage(.Method /*1*/ | .Invocation)]
[AttributeUsage(.Method | .Constructor | .Invocation | .Property)]
public struct InlineAttribute : Attribute
{

View file

@ -13,7 +13,9 @@ namespace System
[AlwaysInclude]
static class Internal
{
[Intrinsic("cast")]
public static extern Object UnsafeCastToObject(void* ptr);
[Intrinsic("cast")]
public static extern void* UnsafeCastToPtr(Object obj);
[NoReturn]
public static extern void ThrowIndexOutOfRange(int stackOffset = 0);

View file

@ -78,7 +78,10 @@ namespace System
[Inline]
public static implicit operator Nullable<T>(T value)
{
return Nullable<T>(value);
Nullable<T> result;
result.mHasValue = true;
result.mValue = value;
return result;
}
[Inline]

View file

@ -102,7 +102,7 @@ namespace System
}
}
[AttributeUsage(.Method /*1*/ | .Invocation | .Property)]
[AttributeUsage(.Method | .Constructor | .Invocation | .Property)]
public struct InlineAttribute : Attribute
{

View file

@ -13,7 +13,9 @@ namespace System
[AlwaysInclude]
static class Internal
{
[Intrinsic("cast")]
public static extern Object UnsafeCastToObject(void* ptr);
[Intrinsic("cast")]
public static extern void* UnsafeCastToPtr(Object obj);
[NoReturn]
public static extern void ThrowIndexOutOfRange(int stackOffset = 0);

View file

@ -70,7 +70,10 @@ namespace System
[Inline]
public static implicit operator Nullable<T>(T value)
{
return Nullable<T>(value);
Nullable<T> result;
result.mHasValue = true;
result.mValue = value;
return result;
}
[Inline]

View file

@ -1902,7 +1902,9 @@ void BeIRCodeGen::HandleNextCmd()
case BfIRCmd_GetIntrinsic:
{
CMD_PARAM(int, intrinId);
CMD_PARAM(BeType*, returnType);
CMD_PARAM(CmdParamVec<BeType*>, paramTypes);
auto intrin = mBeModule->mAlloc.Alloc<BeIntrinsic>();
intrin->mKind = (BfIRIntrinsic)intrinId;
@ -1934,6 +1936,9 @@ void BeIRCodeGen::HandleNextCmd()
case BfIRIntrinsic_AtomicCmpStore_Weak:
intrin->mReturnType = mBeContext->GetPrimitiveType(BeTypeCode_Boolean);
break;
case BfIRIntrinsic_Cast:
intrin->mReturnType = returnType;
break;
}
SetResult(curId, intrin);

View file

@ -16209,6 +16209,15 @@ void BeMCContext::Generate(BeFunction* function)
result = scratchReg;
}
break;
case BfIRIntrinsic_Cast:
{
result = AllocVirtualReg(intrin->mReturnType);
CreateDefineVReg(result);
auto vregInfo = GetVRegInfo(result);
vregInfo->mRelTo = GetOperand(castedInst->mArgs[0].mValue);
vregInfo->mIsExpr = true;
}
break;
case BfIRIntrinsic_MemSet:
{
if (auto constVal = BeValueDynCast<BeConstant>(castedInst->mArgs[1].mValue))

View file

@ -4232,9 +4232,9 @@ void BfIRBuilder::AddPhiIncoming(BfIRValue phi, BfIRValue value, BfIRBlock comin
NEW_CMD_INSERTED;
}
BfIRFunction BfIRBuilder::GetIntrinsic(int intrinId, const BfSizedArray<BfIRType>& paramTypes)
BfIRFunction BfIRBuilder::GetIntrinsic(int intrinId, BfIRType returnType, const BfSizedArray<BfIRType>& paramTypes)
{
BfIRValue retVal = WriteCmd(BfIRCmd_GetIntrinsic, intrinId, paramTypes);
BfIRValue retVal = WriteCmd(BfIRCmd_GetIntrinsic, intrinId, returnType, paramTypes);
NEW_CMD_INSERTED;
return retVal;
}

View file

@ -403,6 +403,7 @@ enum BfIRIntrinsic : uint8
BfIRIntrinsic_AtomicXChg,
BfIRIntrinsic_AtomicXor,
BfIRIntrinsic_BSwap,
BfIRIntrinsic_Cast,
BfIRIntrinsic_Cos,
BfIRIntrinsic_Floor,
BfIRIntrinsic_Free,
@ -1136,7 +1137,7 @@ public:
BfIRValue CreatePhi(BfIRType type, int incomingCount);
void AddPhiIncoming(BfIRValue phi, BfIRValue value, BfIRBlock comingFrom);
BfIRFunction GetIntrinsic(int intrinId, const BfSizedArray<BfIRType>& paramTypes);
BfIRFunction GetIntrinsic(int intrinId, BfIRType returnType, const BfSizedArray<BfIRType>& paramTypes);
BfIRFunctionType MapMethod(BfMethodInstance* methodInstance);
BfIRFunctionType CreateFunctionType(BfIRType resultType, const BfSizedArray<BfIRType>& paramTypes, bool isVarArg = false);
BfIRFunction CreateFunction(BfIRFunctionType funcType, BfIRLinkageType linkageType, const StringImpl& name);

View file

@ -143,6 +143,7 @@ static const BuiltinEntry gIntrinEntries[] =
{"atomic_xchg"},
{"atomic_xor"},
{"bswap"},
{"cast"},
{"cos"},
{"floor"},
{"free"},
@ -1815,18 +1816,24 @@ void BfIRCodeGen::HandleNextCmd()
case BfIRCmd_GetIntrinsic:
{
CMD_PARAM(int, intrinId);
CMD_PARAM(llvm::Type*, returnType);
CMD_PARAM(CmdParamVec<llvm::Type*>, paramTypes);
bool isFakeIntrinsic = false;
if ((intrinId >= BfIRIntrinsic_Atomic_FIRST) && (intrinId <= BfIRIntrinsic_Atomic_LAST))
if (((intrinId >= BfIRIntrinsic_Atomic_FIRST) && (intrinId <= BfIRIntrinsic_Atomic_LAST)) ||
(intrinId == BfIRIntrinsic_Cast))
{
isFakeIntrinsic = true;
}
if (isFakeIntrinsic)
{
auto intrinsicData = mAlloc.Alloc<BfIRIntrinsicData>();
intrinsicData->mIntrinsic = (BfIRIntrinsic)intrinId;
intrinsicData->mReturnType = returnType;
BfIRCodeGenEntry entry;
entry.mKind = BfIRCodeGenEntryKind_FakeIntrinsic;
entry.mIntrinsic = (BfIRIntrinsic)intrinId;
entry.mKind = BfIRCodeGenEntryKind_IntrinsicData;
entry.mIntrinsicData = intrinsicData;
mResults.TryAdd(curId, entry);
break;
}
@ -1863,6 +1870,7 @@ void BfIRCodeGen::HandleNextCmd()
{ (llvm::Intrinsic::ID)-1, -1}, // AtomicXChg,
{ (llvm::Intrinsic::ID)-1, -1}, // AtomicXor,
{ llvm::Intrinsic::bswap, -1},
{ (llvm::Intrinsic::ID) - 1, -1}, // cast,
{ llvm::Intrinsic::cos, -1},
{ llvm::Intrinsic::floor, -1},
{ (llvm::Intrinsic::ID)-1, -1}, // free
@ -2005,9 +2013,11 @@ void BfIRCodeGen::HandleNextCmd()
Read(func, &codeGenEntry);
CMD_PARAM(CmdParamVec<llvm::Value*>, args);
if ((func == NULL) && (codeGenEntry != NULL) && (codeGenEntry->mKind == BfIRCodeGenEntryKind_FakeIntrinsic))
if ((func == NULL) && (codeGenEntry != NULL) && (codeGenEntry->mKind == BfIRCodeGenEntryKind_IntrinsicData))
{
switch (codeGenEntry->mIntrinsic)
auto intrinsicData = codeGenEntry->mIntrinsicData;
switch (intrinsicData->mIntrinsic)
{
case BfIRIntrinsic_AtomicCmpStore:
case BfIRIntrinsic_AtomicCmpStore_Weak:
@ -2077,11 +2087,11 @@ void BfIRCodeGen::HandleNextCmd()
}
auto inst = mIRBuilder->CreateAtomicCmpXchg(args[0], args[1], args[2], successOrdering, failOrdering);
if (codeGenEntry->mIntrinsic == BfIRIntrinsic_AtomicCmpStore_Weak)
if (intrinsicData->mIntrinsic == BfIRIntrinsic_AtomicCmpStore_Weak)
inst->setWeak(true);
if ((memoryKind & BfIRAtomicOrdering_Volatile) != 0)
inst->setVolatile(true);
if (codeGenEntry->mIntrinsic == BfIRIntrinsic_AtomicCmpXChg)
if (intrinsicData->mIntrinsic == BfIRIntrinsic_AtomicCmpXChg)
{
auto prevVal = mIRBuilder->CreateExtractValue(inst, 0);
SetResult(curId, prevVal);
@ -2218,7 +2228,7 @@ void BfIRCodeGen::HandleNextCmd()
bool isFloat = args[1]->getType()->isFloatingPointTy();
auto op = llvm::AtomicRMWInst::BinOp::Add;
switch (codeGenEntry->mIntrinsic)
switch (intrinsicData->mIntrinsic)
{
case BfIRIntrinsic_AtomicAdd:
op = llvm::AtomicRMWInst::BinOp::Add;
@ -2293,7 +2303,7 @@ void BfIRCodeGen::HandleNextCmd()
llvm::Value* result = atomicRMW;
if ((memoryKind & BfIRAtomicOrdering_ReturnModified) != 0)
{
switch (codeGenEntry->mIntrinsic)
switch (intrinsicData->mIntrinsic)
{
case BfIRIntrinsic_AtomicAdd:
if (isFloat)
@ -2310,7 +2320,7 @@ void BfIRCodeGen::HandleNextCmd()
case BfIRIntrinsic_AtomicUMin:
{
llvm::Value* cmpVal = NULL;
switch (codeGenEntry->mIntrinsic)
switch (intrinsicData->mIntrinsic)
{
case BfIRIntrinsic_AtomicMax:
if (isFloat)
@ -2360,6 +2370,11 @@ void BfIRCodeGen::HandleNextCmd()
SetResult(curId, result);
}
break;
case BfIRIntrinsic_Cast:
{
SetResult(curId, mIRBuilder->CreateBitCast(args[0], intrinsicData->mReturnType));
}
break;
default:
Fail("Unhandled intrinsic");
}

View file

@ -13,7 +13,14 @@ enum BfIRCodeGenEntryKind
BfIRCodeGenEntryKind_LLVMType,
BfIRCodeGenEntryKind_LLVMBasicBlock,
BfIRCodeGenEntryKind_LLVMMetadata,
BfIRCodeGenEntryKind_FakeIntrinsic,
BfIRCodeGenEntryKind_IntrinsicData,
};
class BfIRIntrinsicData
{
public:
BfIRIntrinsic mIntrinsic;
llvm::Type* mReturnType;
};
struct BfIRCodeGenEntry
@ -25,7 +32,7 @@ struct BfIRCodeGenEntry
llvm::Type* mLLVMType;
llvm::BasicBlock* mLLVMBlock;
llvm::MDNode* mLLVMMetadata;
BfIRIntrinsic mIntrinsic;
BfIRIntrinsicData* mIntrinsicData;
};
};
@ -54,6 +61,7 @@ class BfIRCodeGen : public BfIRCodeGenBase
public:
BfIRBuilder* mBfIRBuilder;
BumpAllocator mAlloc;
BfTargetTriple mTargetTriple;
String mModuleName;
llvm::LLVMContext* mLLVMContext;

View file

@ -6096,7 +6096,7 @@ BfIRFunction BfModule::GetIntrinsic(BfMethodInstance* methodInstance, bool repor
SizedArray<BfIRType, 2> paramTypes;
for (auto& param : methodInstance->mParams)
paramTypes.push_back(mBfIRBuilder->MapType(param.mResolvedType));
return mBfIRBuilder->GetIntrinsic(intrinId, paramTypes);
return mBfIRBuilder->GetIntrinsic(intrinId, mBfIRBuilder->MapType(methodInstance->mReturnType), paramTypes);
}
else if (reportFailure)
error = StrFormat("Unable to find intrinsic '%s'", entry.mString.c_str());

View file

@ -6281,6 +6281,11 @@ void BfModule::Visit(BfDeferStatement* deferStmt)
else
scope = mCurMethodState->mCurScope;
if ((scope == mCurMethodState->mCurScope) && (scope->mCloseNode == NULL))
{
Warn(0, "This defer will immediately execute. Consider specifying a wider scope target such as 'defer::'", deferStmt->mDeferToken);
}
if (auto block = BfNodeDynCast<BfBlock>(deferStmt->mTargetNode))
{
if (deferStmt->mBind != NULL)