| //------------------------------------------------------------------------------------------------------- |
| // Copyright (C) Microsoft. All rights reserved. |
| // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. |
| //------------------------------------------------------------------------------------------------------- |
| #pragma once |
| |
| #include "Lifetime.h" |
| |
| struct OpHelperSpilledLifetime |
| { |
| Lifetime * lifetime; |
| RegNum reg; |
| bool spillAsArg; |
| bool reload; // determines if we want to reload the lifetime at the end of the helper |
| }; |
| |
| class OpHelperBlock |
| { |
| public: |
| OpHelperBlock(JitArenaAllocator * alloc) : spilledLifetime(alloc) {} |
| |
| IR::LabelInstr * opHelperLabel; |
| IR::Instr * opHelperEndInstr; |
| SList<OpHelperSpilledLifetime> spilledLifetime; |
| |
| public: |
| uint Length() const; |
| |
| private: |
| // Disable copy constructor |
| OpHelperBlock(OpHelperBlock const&); |
| }; |
| |
| class SCCLiveness |
| { |
| private: |
| Func * func; |
| JitArenaAllocator *tempAlloc; |
| Loop * curLoop; |
| uint32 lastCall; |
| uint32 lastNonOpHelperCall; |
| uint16 loopNest; |
| IR::LabelInstr * lastOpHelperLabel; |
| Region * curRegion; |
| SListBase<Loop*> * extendedLifetimesLoopList; |
| public: |
| SCCLiveness(Func *func, JitArenaAllocator *tempAlloc) : func(func), |
| tempAlloc(tempAlloc), loopNest(0), lastCall(0), lastNonOpHelperCall(0), |
| curLoop(NULL), lastOpHelperLabel(NULL), opHelperBlockList(tempAlloc), |
| curRegion(NULL), lifetimeList(tempAlloc), |
| totalOpHelperFullVisitedLength(0) |
| { |
| extendedLifetimesLoopList = JitAnew(tempAlloc, SListBase<Loop *>); |
| } |
| |
| void Build(); |
| #if DBG_DUMP |
| void Dump(); |
| #endif |
| |
| SList<Lifetime *> lifetimeList; |
| SList<OpHelperBlock> opHelperBlockList; |
| uint totalOpHelperFullVisitedLength; |
| |
| private: |
| void ProcessSrc(IR::Opnd *src, IR::Instr *instr); |
| void ProcessDst(IR::Opnd *dst, IR::Instr *instr); |
| void ProcessRegUse(IR::RegOpnd *regUse, IR::Instr *instr); |
| void ProcessRegDef(IR::RegOpnd *regDef, IR::Instr *instr); |
| void ExtendLifetime(Lifetime *lifetime, IR::Instr *instr); |
| void ProcessStackSymUse(StackSym * stackSym, IR::Instr * instr, int usageSize = MachPtr); |
| void ProcessBailOutUses(IR::Instr * bailOutInstr); |
| Lifetime * InsertLifetime(StackSym *stackSym, RegNum reg, IR::Instr *const currentInstr); |
| void EndOpHelper(IR::Instr * instr); |
| bool FoldIndir(IR::Instr *instr, IR::Opnd *opnd); |
| uint CurrentOpHelperVisitedLength(IR::Instr *const currentInstr) const; |
| }; |