Skip to content

Commit 4964fc4

Browse files
committed
[1.10>master] [MERGE #5504 @sigatrev] Code Quality: use legalizePostRegAlloc flag on Func instead of passing bool to Legalizers
Merge pull request #5504 from sigatrev:users/magardn/legalize ARM and ARM64 legalizers behave differently before and after register allocation. We've had bugs in the past where, mainly through static helper functions similar to Lowerer::InsertMove where we've had the flag wrong. This commit adds a flag on Func to tell the legalizer if it should behave as if register allocation has happened or not, and removes the need to pass the flags. The flag was not used on x86 and x64 There were a couple of places where the flag passed did not agree with whether register allocation has finished, in particular LinearScan::InsertLea (passed the flag true) and ARM and ARM64 LowererMD::ChangeToAssign (always passed false). I've added an RAII auto-restore helper to change the flag on the Func while those calls are in progress . While not ideal, it does have the benefit of being mroe expressive. I'm using a new flag instead of the existing (dbg only) isPostRegAlloc flag because the flag can be temporarily overriden.
2 parents f8154dd + 9796560 commit 4964fc4

16 files changed

+332
-318
lines changed

lib/Backend/Func.cpp

+7-22
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ Func::Func(JitArenaAllocator *alloc, JITTimeWorkItem * workItem,
7272
hasInstrNumber(false),
7373
maintainByteCodeOffset(true),
7474
frameSize(0),
75+
topFunc(parentFunc ? parentFunc->topFunc : this),
7576
parentFunc(parentFunc),
7677
argObjSyms(nullptr),
7778
m_nonTempLocalVars(nullptr),
@@ -109,6 +110,7 @@ Func::Func(JitArenaAllocator *alloc, JITTimeWorkItem * workItem,
109110
isTJLoopBody(false),
110111
m_nativeCodeDataSym(nullptr),
111112
isFlowGraphValid(false),
113+
legalizePostRegAlloc(false),
112114
#if DBG
113115
m_callSiteCount(0),
114116
#endif
@@ -1314,6 +1316,11 @@ Func::EndPhase(Js::Phase tag, bool dump)
13141316
}
13151317
#endif
13161318

1319+
if (tag == Js::RegAllocPhase)
1320+
{
1321+
this->legalizePostRegAlloc = true;
1322+
}
1323+
13171324
#if DBG
13181325
if (tag == Js::LowererPhase)
13191326
{
@@ -1352,28 +1359,6 @@ Func::EndPhase(Js::Phase tag, bool dump)
13521359
#endif
13531360
}
13541361

1355-
Func const *
1356-
Func::GetTopFunc() const
1357-
{
1358-
Func const * func = this;
1359-
while (!func->IsTopFunc())
1360-
{
1361-
func = func->parentFunc;
1362-
}
1363-
return func;
1364-
}
1365-
1366-
Func *
1367-
Func::GetTopFunc()
1368-
{
1369-
Func * func = this;
1370-
while (!func->IsTopFunc())
1371-
{
1372-
func = func->parentFunc;
1373-
}
1374-
return func;
1375-
}
1376-
13771362
StackSym *
13781363
Func::EnsureLoopParamSym()
13791364
{

lib/Backend/Func.h

+26-2
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,8 @@ static const unsigned __int64 c_debugFillPattern8 = 0xcececececececece;
364364
}
365365
void NumberInstrs();
366366
bool IsTopFunc() const { return this->parentFunc == nullptr; }
367-
Func const * GetTopFunc() const;
368-
Func * GetTopFunc();
367+
Func const * GetTopFunc() const { return this->topFunc; }
368+
Func * GetTopFunc() { return this->topFunc; }
369369

370370
void SetFirstArgOffset(IR::Instr* inlineeStart);
371371

@@ -732,6 +732,7 @@ static const unsigned __int64 c_debugFillPattern8 = 0xcececececececece;
732732
bool hasTempObjectProducingInstr:1; // At least one instruction which can produce temp object
733733
bool isTJLoopBody : 1;
734734
bool isFlowGraphValid : 1;
735+
bool legalizePostRegAlloc : 1;
735736
#if DBG
736737
bool hasCalledSetDoFastPaths:1;
737738
bool isPostLower:1;
@@ -836,6 +837,8 @@ static const unsigned __int64 c_debugFillPattern8 = 0xcececececececece;
836837
}
837838
}
838839

840+
bool ShouldLegalizePostRegAlloc() const { return topFunc->legalizePostRegAlloc; }
841+
839842
bool GetApplyTargetInliningRemovedArgumentsAccess() const { return this->applyTargetInliningRemovedArgumentsAccess;}
840843
void SetApplyTargetInliningRemovedArgumentsAccess() { this->applyTargetInliningRemovedArgumentsAccess = true;}
841844

@@ -1024,6 +1027,7 @@ static const unsigned __int64 c_debugFillPattern8 = 0xcececececececece;
10241027
#ifdef PROFILE_EXEC
10251028
Js::ScriptContextProfiler *const m_codeGenProfiler;
10261029
#endif
1030+
Func * const topFunc;
10271031
Func * const parentFunc;
10281032
StackSym * m_inlineeFrameStartSym;
10291033
uint maxInlineeArgOutSize;
@@ -1106,6 +1110,26 @@ class AutoCodeGenPhase
11061110
bool dump;
11071111
bool isPhaseComplete;
11081112
};
1113+
1114+
class AutoRestoreLegalize
1115+
{
1116+
public:
1117+
AutoRestoreLegalize(Func * func, bool val) :
1118+
m_func(func->GetTopFunc()),
1119+
m_originalValue(m_func->legalizePostRegAlloc)
1120+
{
1121+
m_func->legalizePostRegAlloc = val;
1122+
}
1123+
1124+
~AutoRestoreLegalize()
1125+
{
1126+
m_func->legalizePostRegAlloc = m_originalValue;
1127+
}
1128+
private:
1129+
Func * m_func;
1130+
bool m_originalValue;
1131+
};
1132+
11091133
#define BEGIN_CODEGEN_PHASE(func, phase) { AutoCodeGenPhase __autoCodeGen(func, phase);
11101134
#define END_CODEGEN_PHASE(func, phase) __autoCodeGen.EndPhase(func, phase, true, true); }
11111135
#define END_CODEGEN_PHASE_NO_DUMP(func, phase) __autoCodeGen.EndPhase(func, phase, false, true); }

lib/Backend/LinearScan.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -4797,7 +4797,8 @@ IR::Instr* LinearScan::InsertLea(IR::RegOpnd *dst, IR::Opnd *src, IR::Instr *con
47974797
{
47984798
IR::Instr *instrPrev = insertBeforeInstr->m_prev;
47994799

4800-
IR::Instr *instrRet = Lowerer::InsertLea(dst, src, insertBeforeInstr, true);
4800+
AutoRestoreLegalize restore(insertBeforeInstr->m_func, true);
4801+
IR::Instr *instrRet = Lowerer::InsertLea(dst, src, insertBeforeInstr);
48014802

48024803
for (IR::Instr *instr = instrPrev->m_next; instr != insertBeforeInstr; instr = instr->m_next)
48034804
{

lib/Backend/Lower.cpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -15381,7 +15381,7 @@ IR::Instr *Lowerer::InsertSub(
1538115381
return instr;
1538215382
}
1538315383

15384-
IR::Instr *Lowerer::InsertLea(IR::RegOpnd *const dst, IR::Opnd *const src, IR::Instr *const insertBeforeInstr, bool postRegAlloc)
15384+
IR::Instr *Lowerer::InsertLea(IR::RegOpnd *const dst, IR::Opnd *const src, IR::Instr *const insertBeforeInstr)
1538515385
{
1538615386
Assert(dst);
1538715387
Assert(src);
@@ -15393,11 +15393,11 @@ IR::Instr *Lowerer::InsertLea(IR::RegOpnd *const dst, IR::Opnd *const src, IR::I
1539315393
IR::Instr *const instr = IR::Instr::New(LowererMD::MDLea, dst, src, func);
1539415394

1539515395
insertBeforeInstr->InsertBefore(instr);
15396-
return ChangeToLea(instr, postRegAlloc);
15396+
return ChangeToLea(instr);
1539715397
}
1539815398

1539915399
IR::Instr *
15400-
Lowerer::ChangeToLea(IR::Instr * instr, bool postRegAlloc)
15400+
Lowerer::ChangeToLea(IR::Instr * instr)
1540115401
{
1540215402
Assert(instr);
1540315403
Assert(instr->GetDst());
@@ -15407,7 +15407,7 @@ Lowerer::ChangeToLea(IR::Instr * instr, bool postRegAlloc)
1540715407
Assert(!instr->GetSrc2());
1540815408

1540915409
instr->m_opcode = LowererMD::MDLea;
15410-
LowererMD::Legalize(instr, postRegAlloc);
15410+
LowererMD::Legalize(instr);
1541115411
return instr;
1541215412
}
1541315413

@@ -27190,7 +27190,7 @@ Lowerer::SetHasBailedOut(IR::Instr * bailoutInstr)
2719027190
IR::SymOpnd * hasBailedOutOpnd = IR::SymOpnd::New(this->m_func->m_hasBailedOutSym, TyUint32, this->m_func);
2719127191
IR::Instr * setInstr = IR::Instr::New(LowererMD::GetStoreOp(TyUint32), hasBailedOutOpnd, IR::IntConstOpnd::New(1, TyUint32, this->m_func), this->m_func);
2719227192
bailoutInstr->InsertBefore(setInstr);
27193-
LowererMD::Legalize(setInstr, true);
27193+
LowererMD::Legalize(setInstr);
2719427194
}
2719527195

2719627196
IR::Instr*
@@ -27241,7 +27241,7 @@ Lowerer::EmitSaveEHBailoutReturnValueAndJumpToRetThunk(IR::Instr * insertAfterIn
2724127241
IR::RegOpnd *eaxOpnd = IR::RegOpnd::New(NULL, LowererMD::GetRegReturn(TyMachReg), TyMachReg, this->m_func);
2724227242
IR::Instr * movInstr = IR::Instr::New(LowererMD::GetStoreOp(TyVar), bailoutReturnValueSymOpnd, eaxOpnd, this->m_func);
2724327243
insertAfterInstr->InsertAfter(movInstr);
27244-
LowererMD::Legalize(movInstr, true);
27244+
LowererMD::Legalize(movInstr);
2724527245

2724627246
IR::BranchInstr * jumpInstr = IR::BranchInstr::New(LowererMD::MDUncondBranchOpcode, this->currentRegion->GetBailoutReturnThunkLabel(), this->m_func);
2724727247
movInstr->InsertAfter(jumpInstr);
@@ -27263,7 +27263,7 @@ Lowerer::EmitRestoreReturnValueFromEHBailout(IR::LabelInstr * restoreLabel, IR::
2726327263

2726427264
epilogLabel->InsertBefore(restoreLabel);
2726527265
epilogLabel->InsertBefore(movInstr);
27266-
LowererMD::Legalize(movInstr, true);
27266+
LowererMD::Legalize(movInstr);
2726727267
restoreLabel->InsertBefore(IR::BranchInstr::New(LowererMD::MDUncondBranchOpcode, epilogLabel, this->m_func));
2726827268
}
2726927269

lib/Backend/Lower.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -397,8 +397,8 @@ class Lowerer
397397
static IR::BranchInstr * InsertTestBranch(IR::Opnd *const testSrc1, IR::Opnd *const testSrc2, const Js::OpCode branchOpCode, const bool isUnsigned, IR::LabelInstr *const target, IR::Instr *const insertBeforeInstr);
398398
static IR::Instr * InsertAdd(const bool needFlags, IR::Opnd *const dst, IR::Opnd *src1, IR::Opnd *src2, IR::Instr *const insertBeforeInstr);
399399
static IR::Instr * InsertSub(const bool needFlags, IR::Opnd *const dst, IR::Opnd *src1, IR::Opnd *src2, IR::Instr *const insertBeforeInstr);
400-
static IR::Instr * InsertLea(IR::RegOpnd *const dst, IR::Opnd *const src, IR::Instr *const insertBeforeInstr, bool postRegAlloc = false);
401-
static IR::Instr * ChangeToLea(IR::Instr *const instr, bool postRegAlloc = false);
400+
static IR::Instr * InsertLea(IR::RegOpnd *const dst, IR::Opnd *const src, IR::Instr *const insertBeforeInstr);
401+
static IR::Instr * ChangeToLea(IR::Instr *const instr);
402402
static IR::Instr * InsertXor(IR::Opnd *const dst, IR::Opnd *const src1, IR::Opnd *const src2, IR::Instr *const insertBeforeInstr);
403403
static IR::Instr * InsertAnd(IR::Opnd *const dst, IR::Opnd *const src1, IR::Opnd *const src2, IR::Instr *const insertBeforeInstr);
404404
static IR::Instr * InsertOr(IR::Opnd *const dst, IR::Opnd *const src1, IR::Opnd *const src2, IR::Instr *const insertBeforeInstr);

lib/Backend/arm/EncoderMD.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -2401,7 +2401,7 @@ bool EncoderMD::TryConstFold(IR::Instr *instr, IR::RegOpnd *regOpnd)
24012401
}
24022402

24032403
instr->ReplaceSrc(regOpnd, regOpnd->m_sym->GetConstOpnd());
2404-
LegalizeMD::LegalizeInstr(instr, false);
2404+
LegalizeMD::LegalizeInstr(instr);
24052405

24062406
return true;
24072407
}
@@ -2421,7 +2421,7 @@ bool EncoderMD::TryFold(IR::Instr *instr, IR::RegOpnd *regOpnd)
24212421
}
24222422
IR::SymOpnd *symOpnd = IR::SymOpnd::New(regOpnd->m_sym, regOpnd->GetType(), instr->m_func);
24232423
instr->ReplaceSrc(regOpnd, symOpnd);
2424-
LegalizeMD::LegalizeInstr(instr, false);
2424+
LegalizeMD::LegalizeInstr(instr);
24252425

24262426
return true;
24272427
}

0 commit comments

Comments
 (0)