1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 12:32:20 +02:00

Alloc allign attributes, lambda captures

This commit is contained in:
Brian Fiete 2019-11-26 13:11:17 -08:00
parent 79ccb33586
commit 12e5b525ad
23 changed files with 540 additions and 219 deletions

View file

@ -1386,7 +1386,10 @@ void BeIRCodeGen::HandleNextCmd()
{
BF_ASSERT(!((BeStructType*)type)->mIsOpaque);
}
SetResult(curId, mBeModule->CreateAlloca(type));
auto allocaInst = mBeModule->CreateAlloca(type);
allocaInst->mAlign = type->mAlign;
SetResult(curId, allocaInst);
}
break;
case BfIRCmd_AllocaArray:
@ -1396,8 +1399,9 @@ void BeIRCodeGen::HandleNextCmd()
auto allocaInst = mBeModule->AllocInst<BeAllocaInst>();
allocaInst->mType = type;
allocaInst->mAlign = type->mAlign;
allocaInst->mArraySize = arraySize;
SetResult(curId, allocaInst);
}
break;
@ -1406,8 +1410,10 @@ void BeIRCodeGen::HandleNextCmd()
CMD_PARAM(BeValue*, val);
CMD_PARAM(int, alignment);
auto inst = BeValueDynCast<BeAllocaInst>(val);
inst->mAlign = alignment;
//TODO: Implement
/*inst->setAlignment(alignment);*/
/*inst->setAlignment(alignment);*/
}
break;
case BfIRCmd_AliasValue:

View file

@ -2941,6 +2941,8 @@ BeMCOperand BeMCContext::CreateCall(const BeMCOperand& func, const SizedArrayImp
SizedArray<_ShadowReg, 8> shadowRegs;
BF_ASSERT(mMaxCallParamCount >= argCount);
mMaxCallParamCount = BF_MAX(mMaxCallParamCount, argCount);
for (int argIdx = args.size() - 1; argIdx >= 0; argIdx--)
{
@ -3651,6 +3653,7 @@ BeMCOperand BeMCContext::AllocVirtualReg(BeType* type, int refCount, bool mustBe
int vregIdx = (int)mVRegInfo.size();
BeMCVRegInfo* vregInfo = mAlloc.Alloc<BeMCVRegInfo>();
vregInfo->mType = type;
vregInfo->mAlign = type->mAlign;
vregInfo->mRefCount = refCount;
vregInfo->mForceReg = mustBeReg;
mVRegInfo.push_back(vregInfo);
@ -3661,7 +3664,7 @@ BeMCOperand BeMCContext::AllocVirtualReg(BeType* type, int refCount, bool mustBe
if (mDebugging)
{
if (mcOperand.mVRegIdx == 31)
if (mcOperand.mVRegIdx == 3)
{
NOP;
}
@ -7902,13 +7905,7 @@ void BeMCContext::DoFrameObjPass()
// we need for calls with more than 4 params.
// If we're doing UseBP, we have to allocate these at call time
int homeSize = BF_ALIGN(BF_MAX(mMaxCallParamCount, 4) * 8, 16);
for (int homeVRegIdx : mDeferredHomeSizeOffsets)
{
auto vregInfo = mVRegInfo[homeVRegIdx];
BF_ASSERT(vregInfo->mRelOffset.mImmediate == -1);
vregInfo->mRelOffset.mImmediate = BF_ALIGN(homeSize, 16);
}
mStackSize = 0;
if (mUseBP)
@ -7947,12 +7944,13 @@ void BeMCContext::DoFrameObjPass()
if ((vregInfo->mRefCount > 0) && (!vregInfo->mIsExpr) && (vregInfo->mReg == X64Reg_None) && (vregInfo->mFrameOffset == INT_MIN))
{
int align = BF_MAX(vregInfo->mType->mAlign, 1);
BF_ASSERT(vregInfo->mAlign != -1);
int align = BF_MAX(vregInfo->mAlign, 1);
int alignOffset = regStackOffset + 8;
int alignedPosition = (mStackSize + alignOffset + (align - 1)) & ~(align - 1);
mStackSize = alignedPosition - alignOffset;
//vregInfo->mFrameOffset = -mStackSize - regStackOffset - 8;
mStackSize += BF_ALIGN(vregInfo->mType->mSize, vregInfo->mType->mAlign);
mStackSize += BF_ALIGN(vregInfo->mType->mSize, vregInfo->mAlign);
vregInfo->mFrameOffset = -mStackSize - regStackOffset;
}
}
@ -8893,6 +8891,7 @@ bool BeMCContext::DoLegalization()
auto relVRegInfo = mVRegInfo[relVRegIdx];
setInst->mKind = BeMCInstKind_MovSX;
relVRegInfo->mType = mModule->mContext->GetPrimitiveType(BeTypeCode_Int64);
relVRegInfo->mAlign = relVRegInfo->mType->mAlign;
if (debugging)
OutputDebugStrF(" Def MovSX\n");
isFinalRun = false;
@ -14693,7 +14692,7 @@ String BeMCContext::ToString(bool showVRegFlags, bool showVRegDetails)
{
str += " ";
str += ToString(BeMCOperand::FromVReg(vregIdx));
str += StrFormat(": size=%d, align=%d, at ", vregInfo->mType->mSize, vregInfo->mType->mAlign);
str += StrFormat(": size=%d, align=%d, at ", vregInfo->mType->mSize, vregInfo->mAlign);
X64CPURegister reg;
int offset;
@ -14840,7 +14839,9 @@ void BeMCContext::Generate(BeFunction* function)
mDbgPreferredRegs[32] = X64Reg_R8;*/
//mDbgPreferredRegs[8] = X64Reg_RAX;
//mDebugging = function->mName == "?DoResolveConfigString@IDEApp@IDE@bf@@QEAA_NPEAVString@System@3@PEAVOptions@Workspace@23@PEAVProject@23@PEAVOptions@823@UStringView@53@00@Z";
mDebugging = function->mName ==
//"?TestPrimitives@Nullable@Tests@bf@@SAXXZ"
"?TestAlloc@Blurg@bf@@SAXXZ";
//"?Main@Program@bf@@CAHPEAV?$Array1@PEAVString@System@bf@@@System@2@@Z";
//"?Hey@Blurg@bf@@SAXXZ";
@ -14875,6 +14876,7 @@ void BeMCContext::Generate(BeFunction* function)
SizedArray<int, 64> stackSaveVRegs;
// Scan pass
mMaxCallParamCount = 4;
for (int blockIdx = 0; blockIdx < (int)function->mBlocks.size(); blockIdx++)
{
auto beBlock = function->mBlocks[blockIdx];
@ -14889,7 +14891,8 @@ void BeMCContext::Generate(BeFunction* function)
{
case BeAllocaInst::TypeId:
{
if (!inHeadAlloca)
auto castedInst = (BeAllocaInst*)inst;
if ((!inHeadAlloca) || (castedInst->mAlign > 16))
mUseBP = true;
}
break;
@ -14902,6 +14905,12 @@ void BeMCContext::Generate(BeFunction* function)
stackSaveVRegs.push_back(stackVReg.mVRegIdx);
}
break;
case BeCallInst::TypeId:
{
auto castedInst = (BeCallInst*)inst;
mMaxCallParamCount = BF_MAX(mMaxCallParamCount, (int)castedInst->mArgs.size());
}
break;
default:
inHeadAlloca = false;
break;
@ -15360,10 +15369,17 @@ void BeMCContext::Generate(BeFunction* function)
}
break;
case BeAllocaInst::TypeId:
{
{
if (mDebugging)
{
NOP;
}
int homeSize = BF_ALIGN(BF_MAX(mMaxCallParamCount, 4) * 8, 16);
auto castedInst = (BeAllocaInst*)inst;
auto mcSize = BeMCOperand::FromImmediate(castedInst->mType->mSize);
bool isAligned16 = false;
int align = castedInst->mAlign;
BeType* allocType = castedInst->mType;
bool preservedVolatiles = false;
bool doPtrCast = false;
@ -15385,7 +15401,7 @@ void BeMCContext::Generate(BeFunction* function)
if (mcSize.mImmediate == 1)
{
mcSize = mcArraySize;
}
}
else
{
auto mcInst = AllocInst(BeMCInstKind_IMul, mcArraySize, mcSize);
@ -15395,10 +15411,12 @@ void BeMCContext::Generate(BeFunction* function)
}
}
if (inHeadAlloca)
// The stack is 16-byte aligned on entry - we have to manually adjust for any alignment greater than that
if ((inHeadAlloca) && (align <= 16))
{
result = AllocVirtualReg(allocType);
auto vregInfo = mVRegInfo[result.mVRegIdx];
vregInfo->mAlign = castedInst->mAlign;
vregInfo->mHasDynLife = true;
if (castedInst->mForceMem)
vregInfo->mForceMem = true;
@ -15416,6 +15434,7 @@ void BeMCContext::Generate(BeFunction* function)
vregInfo->mIsExpr = true;
vregInfo->mRelTo = result;
vregInfo->mType = resultType;
vregInfo->mAlign = resultType->mSize;
CreateDefineVReg(ptrResult);
result = ptrResult;
@ -15438,6 +15457,8 @@ void BeMCContext::Generate(BeFunction* function)
}
}
int stackAlign = BF_MAX(align, 16);
BeMCOperand mcFunc;
mcFunc.mKind = BeMCOperandKind_SymbolAddr;
mcFunc.mSymbolIdx = mCOFFObject->GetSymbolRef("__chkstk")->mIdx;
@ -15449,7 +15470,7 @@ void BeMCContext::Generate(BeFunction* function)
}
if ((mcSize.IsImmediate()) && (!preservedVolatiles) && (!needsChkStk))
{
{
AllocInst(BeMCInstKind_Sub, BeMCOperand::FromReg(X64Reg_RSP), mcSize);
}
else
@ -15482,7 +15503,7 @@ void BeMCContext::Generate(BeFunction* function)
// and BOOM. We rely on the front-end to tell us when we can omit it.
}
else if (!isAligned16)
{
{
AllocInst(BeMCInstKind_Mov, BeMCOperand::FromReg(X64Reg_RAX), mcSize);
AllocInst(BeMCInstKind_Add, BeMCOperand::FromReg(X64Reg_RAX), BeMCOperand::FromImmediate(0xF));
AllocInst(BeMCInstKind_And, BeMCOperand::FromReg(X64Reg_RAX), BeMCOperand::FromImmediate(~0xF));
@ -15493,8 +15514,7 @@ void BeMCContext::Generate(BeFunction* function)
AllocInst(BeMCInstKind_Call, mcFunc);
}
AllocInst(BeMCInstKind_Sub, BeMCOperand::FromReg(X64Reg_RSP), BeMCOperand::FromReg(X64Reg_RAX));
AllocInst(BeMCInstKind_Sub, BeMCOperand::FromReg(X64Reg_RSP), BeMCOperand::FromReg(X64Reg_RAX));
if (doFastChkStk)
{
AllocInst(BeMCInstKind_FastCheckStack, BeMCOperand::FromReg(X64Reg_RSP));
@ -15514,8 +15534,7 @@ void BeMCContext::Generate(BeFunction* function)
auto vregInfo = mVRegInfo[ptrValue.mVRegIdx];
vregInfo->mIsExpr = true;
vregInfo->mRelTo = BeMCOperand::FromReg(X64Reg_RSP);
vregInfo->mRelOffset = BeMCOperand::FromImmediate(-1);
mDeferredHomeSizeOffsets.Add(ptrValue.mVRegIdx);
vregInfo->mRelOffset = BeMCOperand::FromImmediate(homeSize);
CreateDefineVReg(ptrValue);
}
else
@ -15529,6 +15548,14 @@ void BeMCContext::Generate(BeFunction* function)
CreateDefineVReg(result);
AllocInst(BeMCInstKind_Mov, result, ptrValue);
if (stackAlign > 16)
{
// We have to align after everything - note that we always have to keep the 'homeSize' space available from RSP for calls,
// so the ANDing for alignment must be done here
AllocInst(BeMCInstKind_And, result, BeMCOperand::FromImmediate(~(stackAlign - 1)));
AllocInst(BeMCInstKind_Sub, BeMCOperand::FromReg(X64Reg_RSP), BeMCOperand::FromImmediate(stackAlign - 16));
}
BF_ASSERT(mUseBP);
}
@ -16037,6 +16064,7 @@ void BeMCContext::Generate(BeFunction* function)
auto vregInfo = GetVRegInfo(castedTarget);
vregInfo->mMustExist = true;
vregInfo->mType = valType;
vregInfo->mAlign = valType->mAlign;
vregInfo->mIsExpr = true;
vregInfo->mRelTo = mcTarget;
CreateDefineVReg(castedTarget);

View file

@ -715,6 +715,7 @@ public:
X64CPURegister mReg;
X64CPURegister mNaturalReg; // From param
BeType* mType;
int mAlign;
int mFrameOffset; // 0 = 'RBP' (probably first local var or saved RBP), 8 means retAddr
bool mRegNumPinned;
bool mHasDynLife;
@ -756,6 +757,7 @@ public:
public:
BeMCVRegInfo()
{
mAlign = -1;
mRegNumPinned = false;
mReg = X64Reg_None;
mNaturalReg = X64Reg_None;
@ -1256,8 +1258,7 @@ public:
BeVTrackingList* mCurVRegsInit;
BeVTrackingList* mCurVRegsLive;
Array<int> mTextRelocs;
Array<BeMCSwitchEntry> mSwitchEntries;
Array<int> mDeferredHomeSizeOffsets;
Array<BeMCSwitchEntry> mSwitchEntries;
Dictionary<int, X64CPURegister> mDbgPreferredRegs;

View file

@ -258,6 +258,9 @@ void BeInliner::Visit(BeAllocaInst* allocaInst)
auto destAllocInst = AllocInst(allocaInst);
destAllocInst->mType = allocaInst->mType;
destAllocInst->mArraySize = Remap(allocaInst->mArraySize);
destAllocInst->mAlign = allocaInst->mAlign;
destAllocInst->mNoChkStk = allocaInst->mNoChkStk;
destAllocInst->mForceMem = allocaInst->mForceMem;
}
void BeInliner::Visit(BeAliasValueInst* aliasValueInst)
@ -1525,7 +1528,9 @@ String BeDumpContext::ToString(BeDbgFunction* dbgFunction)
void BeDumpContext::ToString(StringImpl& str, int val)
{
str += StrFormat("%d", val);
char iStr[32];
sprintf(iStr, "%d", val);
str += iStr;
}
String BeDumpContext::ToString(int val)
@ -2146,6 +2151,8 @@ String BeModule::ToString(BeFunction* wantFunc)
str += ", ";
dc.ToString(str, castedInst->mArraySize);
}
str += ", align ";
dc.ToString(str, castedInst->mAlign);
}
break;
DISPLAY_INST1(BeAliasValueInst, "aliasvalue", mPtr);
@ -2672,6 +2679,9 @@ void BeModule::DoInlining(BeFunction* func)
auto destAlloca = mAlloc.Alloc<BeAllocaInst>();
destAlloca->mType = allocaInst->mType;
destAlloca->mArraySize = allocaInst->mArraySize;
destAlloca->mAlign = allocaInst->mAlign;
destAlloca->mNoChkStk = allocaInst->mNoChkStk;
destAlloca->mForceMem = allocaInst->mForceMem;
destAlloca->mName = allocaInst->mName;
auto destBlock = func->mBlocks[0];

View file

@ -811,6 +811,7 @@ public:
BeType* mType;
BeValue* mArraySize;
int mAlign;
bool mNoChkStk;
bool mForceMem;
@ -823,6 +824,7 @@ public:
mType->HashReference(hashCtx);
if (mArraySize != NULL)
mArraySize->HashReference(hashCtx);
hashCtx.Mixin(mAlign);
hashCtx.Mixin(mNoChkStk);
hashCtx.Mixin(mForceMem);
}