blob: bb480d6047c4c11372858e01632b9ab3cea78bc3 [file]
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft Corporation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#pragma once
class Lifetime
{
public:
Lifetime(JitArenaAllocator * alloc, StackSym *sym, RegNum reg, uint32 start, uint32 end, Func *func)
: sym(sym), reg(reg), start(start), end(end), previousDefBlockNumber(0), defList(alloc),
useList(alloc), lastUseLabel(NULL), region(NULL), isSpilled(false), useCount(0), useCountAdjust(0), allDefsCost(0), isLiveAcrossCalls(false),
isLiveAcrossUserCalls(false), isDeadStore(true), isOpHelperSpilled(false), cantOpHelperSpill(false), isOpHelperSpillAsArg(false),
isFloat(false), isSimd128F4(false), isSimd128I4(false), isSimd128I8(false), isSimd128I16(false), isSimd128U4(false), isSimd128U8(false), isSimd128U16(false),
isSimd128D2(false), isSimd128B4(false), isSimd128B8(false), isSimd128B16(false), cantSpill(false), dontAllocate(false), isSecondChanceAllocated(false), isCheapSpill(false), spillStackSlot(NULL),
totalOpHelperLengthByEnd(0), needsStoreCompensation(false), alloc(alloc), regionUseCount(NULL), regionUseCountAdjust(NULL),
cantStackPack(false)
{
intUsageBv.ClearAll();
regPreference.ClearAll();
}
public:
StackSym * sym;
uint32 * regionUseCount;
uint32 * regionUseCountAdjust;
SList<IR::Instr *> defList;
SList<IR::Instr *> useList;
IR::LabelInstr * lastUseLabel;
Region * region;
StackSlot * spillStackSlot;
JitArenaAllocator * alloc;
BitVector intUsageBv;
BitVector regPreference;
uint32 start;
uint32 end;
uint32 previousDefBlockNumber;
uint32 useCount;
uint32 useCountAdjust;
uint32 allDefsCost;
uint32 lastAllocationStart;
RegNum reg;
uint totalOpHelperLengthByEnd;
uint8 isSpilled:1;
uint8 isLiveAcrossCalls:1;
uint8 isLiveAcrossUserCalls:1;
uint8 isDeadStore:1;
uint8 isOpHelperSpilled:1;
uint8 isOpHelperSpillAsArg : 1;
uint8 cantOpHelperSpill:1;
uint8 isFloat:1;
uint8 isSimd128F4 : 1;
uint8 isSimd128I4 : 1;
uint8 isSimd128I8 : 1;
uint8 isSimd128I16 : 1;
uint8 isSimd128B4 : 1;
uint8 isSimd128B8 : 1;
uint8 isSimd128B16 : 1;
uint8 isSimd128U4 : 1;
uint8 isSimd128U8 : 1;
uint8 isSimd128U16 : 1;
uint8 isSimd128D2 : 1;
uint8 cantSpill:1;
uint8 dontAllocate:1;
uint8 isSecondChanceAllocated:1;
uint8 isCheapSpill:1;
uint8 needsStoreCompensation:1;
uint8 cantStackPack : 1;
bool isSimd128()
{
bool result = isSimd128F4;
result |= isSimd128I4;
result |= isSimd128I8;
result |= isSimd128I16;
result |= isSimd128U4;
result |= isSimd128U8;
result |= isSimd128U16;
result |= isSimd128D2;
result |= isSimd128B4;
result |= isSimd128B8;
result |= isSimd128B16;
return result;
}
void AddToUseCount(uint32 newUseValue, Loop *loop, Func *func)
{
Assert((this->useCount + newUseValue) >= this->useCount);
this->useCount += newUseValue;
if (loop)
{
if (!this->regionUseCount)
{
this->regionUseCount = AnewArrayZ(this->alloc, uint32, func->loopCount+1);
this->regionUseCountAdjust = AnewArrayZ(this->alloc, uint32, func->loopCount+1);
}
while (loop)
{
this->regionUseCount[loop->loopNumber] += newUseValue;
loop = loop->parent;
}
}
}
void SubFromUseCount(uint32 newUseValue, Loop *loop)
{
Assert((this->useCount - newUseValue) <= this->useCount);
this->useCount -= newUseValue;
Assert(!loop || this->regionUseCount);
while (loop)
{
Assert((this->regionUseCount[loop->loopNumber] - newUseValue) <= this->regionUseCount[loop->loopNumber]);
this->regionUseCount[loop->loopNumber] -= newUseValue;
loop = loop->parent;
}
}
uint32 GetRegionUseCount(Loop *loop)
{
if (loop && !PHASE_OFF1(Js::RegionUseCountPhase))
{
if (this->regionUseCount)
{
return this->regionUseCount[loop->loopNumber];
}
else
{
return 0;
}
}
else
{
return this->useCount;
}
}
void AddToUseCountAdjust(uint32 newUseValue, Loop *loop, Func *func)
{
Assert((this->useCountAdjust + newUseValue) >= this->useCountAdjust);
this->useCountAdjust += newUseValue;
if (loop)
{
if (!this->regionUseCount)
{
this->regionUseCount = AnewArrayZ(this->alloc, uint32, func->loopCount+1);
this->regionUseCountAdjust = AnewArrayZ(this->alloc, uint32, func->loopCount+1);
}
do
{
this->regionUseCountAdjust[loop->loopNumber] += newUseValue;
loop = loop->parent;
} while (loop);
}
}
void ApplyUseCountAdjust(Loop *loop)
{
Assert((this->useCount + this->useCountAdjust) >= this->useCount);
this->useCount -= this->useCountAdjust;
this->useCountAdjust = 0;
if (loop && this->regionUseCount)
{
do
{
Assert((this->regionUseCount[loop->loopNumber] - this->regionUseCountAdjust[loop->loopNumber]) <= this->regionUseCount[loop->loopNumber]);
this->regionUseCount[loop->loopNumber] -= this->regionUseCountAdjust[loop->loopNumber];
this->regionUseCountAdjust[loop->loopNumber] = 0;
loop = loop->parent;
} while (loop);
}
}
};