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:
parent
660e7d8125
commit
1f20d76f94
14 changed files with 75 additions and 22 deletions
|
@ -102,7 +102,7 @@ namespace System
|
|||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(.Method /*1*/ | .Invocation)]
|
||||
[AttributeUsage(.Method | .Constructor | .Invocation | .Property)]
|
||||
public struct InlineAttribute : Attribute
|
||||
{
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -102,7 +102,7 @@ namespace System
|
|||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(.Method /*1*/ | .Invocation | .Property)]
|
||||
[AttributeUsage(.Method | .Constructor | .Invocation | .Property)]
|
||||
public struct InlineAttribute : Attribute
|
||||
{
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue